Cleanup MBC related code

This commit is contained in:
Kevin Hamacher 2020-02-20 19:28:20 +01:00
parent fc935ab214
commit 847d12c3a8
9 changed files with 169 additions and 168 deletions

View File

@ -1,4 +1,4 @@
use crate::mbc::{mbc, mbc1, mbc2, mbc3, mbc5};
use crate::mbc;
#[derive(Debug, PartialEq)]
enum MemoryBankControllerType {
@ -24,7 +24,7 @@ pub struct Cartridge {
}
impl Cartridge {
pub fn new(rom: Box<[u8]>, save_file: Option<String>) -> Cartridge {
pub fn new(rom: Box<[u8]>, savefile: Option<String>) -> Cartridge {
let mbc_type: MemoryBankControllerType = match rom[0x0147] {
0x00 | 0x08..=0x09 => MemoryBankControllerType::None,
0x01..=0x03 => MemoryBankControllerType::MBC1,
@ -57,23 +57,20 @@ impl Cartridge {
println!("Rom size: {} banks", rom_banks);
println!("Ram size: {:?}", ram_size);
let ram = Cartridge::load_savefile(&save_file, ram_size);
let ram = Cartridge::load_savefile(&savefile, ram_size);
let mbc: Box<dyn mbc::MBC> = match mbc_type {
MemoryBankControllerType::None => Box::new(mbc::NoMBC::new(rom, ram)),
MemoryBankControllerType::MBC1 => Box::new(mbc1::MBC1::new(rom, ram)),
MemoryBankControllerType::MBC2 => Box::new(mbc2::MBC2::new(rom, ram)),
MemoryBankControllerType::MBC3 => Box::new(mbc3::MBC3::new(rom, ram)),
MemoryBankControllerType::MBC5 => Box::new(mbc5::MBC5::new(rom, ram)),
MemoryBankControllerType::MBC1 => Box::new(mbc::MBC1::new(rom, ram)),
MemoryBankControllerType::MBC2 => Box::new(mbc::MBC2::new(rom, ram)),
MemoryBankControllerType::MBC3 => Box::new(mbc::MBC3::new(rom, ram)),
MemoryBankControllerType::MBC5 => Box::new(mbc::MBC5::new(rom, ram)),
};
Cartridge {
mbc: mbc,
savefile: save_file,
}
Cartridge { mbc, savefile }
}
fn load_savefile(save_file: &Option<String>, ram_size: RamSize) -> Box<[u8]> {
fn load_savefile(savefile: &Option<String>, ram_size: RamSize) -> Box<[u8]> {
let size = match ram_size {
RamSize::None => 0,
RamSize::Ram2KB => 2048,
@ -81,7 +78,7 @@ impl Cartridge {
RamSize::Ram32KB => 16 * 2048,
};
if let &Some(ref filename) = save_file {
if let &Some(ref filename) = savefile {
let data = super::read_file(&filename);
if let Ok(data) = data {
if data.len() != size {

View File

@ -165,87 +165,83 @@ impl Interconnect {
// Make sure the window is responsive:
if self.cycles > 500 {
loop {
if let Some(event) = self.display.event_pump.poll_event() {
match event {
Event::Quit { .. }
| Event::KeyDown {
keycode: Some(Keycode::Escape),
..
} => {
self.cartridge.save();
self.display.dump_vram();
return TickResult::Shutdown;
}
Event::KeyDown {
keycode: Some(Keycode::Left),
..
} => self.press_key(Key::LEFT),
Event::KeyDown {
keycode: Some(Keycode::Down),
..
} => self.press_key(Key::DOWN),
Event::KeyDown {
keycode: Some(Keycode::Up),
..
} => self.press_key(Key::UP),
Event::KeyDown {
keycode: Some(Keycode::Right),
..
} => self.press_key(Key::RIGHT),
Event::KeyDown {
keycode: Some(Keycode::A),
..
} => self.press_key(Key::START),
Event::KeyDown {
keycode: Some(Keycode::S),
..
} => self.press_key(Key::SELECT),
Event::KeyDown {
keycode: Some(Keycode::Z),
..
} => self.press_key(Key::A),
Event::KeyDown {
keycode: Some(Keycode::X),
..
} => self.press_key(Key::B),
Event::KeyUp {
keycode: Some(Keycode::Left),
..
} => self.release_key(Key::LEFT),
Event::KeyUp {
keycode: Some(Keycode::Down),
..
} => self.release_key(Key::DOWN),
Event::KeyUp {
keycode: Some(Keycode::Up),
..
} => self.release_key(Key::UP),
Event::KeyUp {
keycode: Some(Keycode::Right),
..
} => self.release_key(Key::RIGHT),
Event::KeyUp {
keycode: Some(Keycode::A),
..
} => self.release_key(Key::START),
Event::KeyUp {
keycode: Some(Keycode::S),
..
} => self.release_key(Key::SELECT),
Event::KeyUp {
keycode: Some(Keycode::Z),
..
} => self.release_key(Key::A),
Event::KeyUp {
keycode: Some(Keycode::X),
..
} => self.release_key(Key::B),
_ => {}
while let Some(event) = self.display.event_pump.poll_event() {
match event {
Event::Quit { .. }
| Event::KeyDown {
keycode: Some(Keycode::Escape),
..
} => {
self.cartridge.save();
self.display.dump_vram();
return TickResult::Shutdown;
}
} else {
break;
Event::KeyDown {
keycode: Some(Keycode::Left),
..
} => self.press_key(Key::LEFT),
Event::KeyDown {
keycode: Some(Keycode::Down),
..
} => self.press_key(Key::DOWN),
Event::KeyDown {
keycode: Some(Keycode::Up),
..
} => self.press_key(Key::UP),
Event::KeyDown {
keycode: Some(Keycode::Right),
..
} => self.press_key(Key::RIGHT),
Event::KeyDown {
keycode: Some(Keycode::A),
..
} => self.press_key(Key::START),
Event::KeyDown {
keycode: Some(Keycode::S),
..
} => self.press_key(Key::SELECT),
Event::KeyDown {
keycode: Some(Keycode::Z),
..
} => self.press_key(Key::A),
Event::KeyDown {
keycode: Some(Keycode::X),
..
} => self.press_key(Key::B),
Event::KeyUp {
keycode: Some(Keycode::Left),
..
} => self.release_key(Key::LEFT),
Event::KeyUp {
keycode: Some(Keycode::Down),
..
} => self.release_key(Key::DOWN),
Event::KeyUp {
keycode: Some(Keycode::Up),
..
} => self.release_key(Key::UP),
Event::KeyUp {
keycode: Some(Keycode::Right),
..
} => self.release_key(Key::RIGHT),
Event::KeyUp {
keycode: Some(Keycode::A),
..
} => self.release_key(Key::START),
Event::KeyUp {
keycode: Some(Keycode::S),
..
} => self.release_key(Key::SELECT),
Event::KeyUp {
keycode: Some(Keycode::Z),
..
} => self.release_key(Key::A),
Event::KeyUp {
keycode: Some(Keycode::X),
..
} => self.release_key(Key::B),
_ => {}
}
}
self.cycles = 0;

View File

@ -1,53 +0,0 @@
pub trait MBC {
fn read_byte(&self, addr: u16) -> u8;
fn write_byte(&mut self, addr: u16, val: u8);
fn dump_ram(&self, file: &String);
}
pub struct NoMBC {
rom: Box<[u8]>,
ram: Box<[u8]>,
}
impl NoMBC {
pub fn new(rom: Box<[u8]>, ram: Box<[u8]>) -> NoMBC {
NoMBC { rom: rom, ram: ram }
}
}
impl MBC for NoMBC {
fn dump_ram(&self, file: &String) {
super::super::write_file(&file, &self.ram).expect("Saving failed");
}
fn write_byte(&mut self, addr: u16, val: u8) {
println!(
"Writing not supported for cartridges without MBC. (Tried to set {:04X} to {:02X})",
addr, val
);
}
fn read_byte(&self, addr: u16) -> u8 {
match addr {
0x0000..=0x7FFF => self.rom[addr as usize],
0xA000..=0xBFFF => {
// TODO: Check for ram
let addr = (addr as usize) - 0xA000;
if addr >= self.ram.len() {
println!(
"Tried to access {:04X}, however the memory is not present.",
addr + 0xA000
);
0
} else {
self.ram[addr]
}
}
_ => {
panic!("Cartride: Unable to read from {:04X}", addr);
}
}
}
}

View File

@ -1,4 +1,4 @@
use super::mbc::MBC;
use super::MBC;
enum BankMode {
RomBankMode,
@ -17,8 +17,8 @@ pub struct MBC1 {
impl MBC1 {
pub fn new(rom: Box<[u8]>, ram: Box<[u8]>) -> MBC1 {
MBC1 {
rom: rom,
ram: ram,
rom,
ram,
rom_bank_no: 1,
bank_mode: BankMode::RomBankMode,
bank_no_high: 0,
@ -43,7 +43,7 @@ impl MBC1 {
}
impl MBC for MBC1 {
fn dump_ram(&self, file: &String) {
fn dump_ram(&self, file: &str) {
super::super::write_file(&file, &self.ram).expect("Saving failed");
}

View File

@ -1,4 +1,4 @@
use super::mbc::MBC;
use super::MBC;
pub struct MBC2 {
rom: Box<[u8]>,
@ -10,8 +10,8 @@ pub struct MBC2 {
impl MBC2 {
pub fn new(rom: Box<[u8]>, ram: Box<[u8]>) -> MBC2 {
MBC2 {
rom: rom,
ram: ram,
rom,
ram,
rom_bank_no: 1,
ram_enable: false,
}
@ -23,7 +23,7 @@ impl MBC2 {
}
impl MBC for MBC2 {
fn dump_ram(&self, file: &String) {
fn dump_ram(&self, file: &str) {
super::super::write_file(&file, &self.ram).expect("Saving failed");
}

View File

@ -1,4 +1,4 @@
use super::mbc::MBC;
use super::MBC;
pub struct MBC3 {
rom: Box<[u8]>,
@ -11,8 +11,8 @@ pub struct MBC3 {
impl MBC3 {
pub fn new(rom: Box<[u8]>, ram: Box<[u8]>) -> MBC3 {
MBC3 {
rom: rom,
ram: ram,
rom,
ram,
rom_bank_no: 1,
ram_bank_no: 0,
ram_rtc_enabled: false,
@ -28,7 +28,7 @@ impl MBC3 {
}
impl MBC for MBC3 {
fn dump_ram(&self, file: &String) {
fn dump_ram(&self, file: &str) {
super::super::write_file(&file, &self.ram).expect("Saving failed");
}

View File

@ -1,4 +1,4 @@
use super::mbc::MBC;
use super::MBC;
pub struct MBC5 {
rom: Box<[u8]>,
@ -11,8 +11,8 @@ pub struct MBC5 {
impl MBC5 {
pub fn new(rom: Box<[u8]>, ram: Box<[u8]>) -> Self {
MBC5 {
rom: rom,
ram: ram,
rom,
ram,
rom_bank_no: 1,
ram_bank_no: 0,
ram_rtc_enabled: false,
@ -28,7 +28,7 @@ impl MBC5 {
}
impl MBC for MBC5 {
fn dump_ram(&self, file: &String) {
fn dump_ram(&self, file: &str) {
use crate::write_file;
write_file(&file, &self.ram).expect("Saving failed");
}

View File

@ -1,5 +1,63 @@
pub mod mbc;
pub mod mbc1;
pub mod mbc2;
pub mod mbc3;
pub mod mbc5;
mod mbc1;
mod mbc2;
mod mbc3;
mod mbc5;
pub use mbc1::MBC1;
pub use mbc2::MBC2;
pub use mbc3::MBC3;
pub use mbc5::MBC5;
pub trait MBC {
fn read_byte(&self, addr: u16) -> u8;
fn write_byte(&mut self, addr: u16, val: u8);
fn dump_ram(&self, file: &str);
}
pub struct NoMBC {
rom: Box<[u8]>,
ram: Box<[u8]>,
}
impl NoMBC {
pub fn new(rom: Box<[u8]>, ram: Box<[u8]>) -> NoMBC {
NoMBC { rom: rom, ram: ram }
}
}
impl MBC for NoMBC {
fn dump_ram(&self, file: &str) {
super::write_file(&file, &self.ram).expect("Saving failed");
}
fn write_byte(&mut self, addr: u16, val: u8) {
println!(
"Writing not supported for cartridges without MBC. (Tried to set {:04X} to {:02X})",
addr, val
);
}
fn read_byte(&self, addr: u16) -> u8 {
match addr {
0x0000..=0x7FFF => self.rom[addr as usize],
0xA000..=0xBFFF => {
// TODO: Check for ram
let addr = (addr as usize) - 0xA000;
if addr >= self.ram.len() {
println!(
"Tried to access {:04X}, however the memory is not present.",
addr + 0xA000
);
0
} else {
self.ram[addr]
}
}
_ => {
panic!("Cartride: Unable to read from {:04X}", addr);
}
}
}
}

View File

@ -5,7 +5,10 @@ mod square;
mod wave;
use self::pulse_simple::Playback;
use std::sync::{Arc, Mutex, atomic::{AtomicBool, Ordering}};
use std::sync::{
atomic::{AtomicBool, Ordering},
Arc, Mutex,
};
use std::thread;
const OUTPUT_SAMPLE_RATE: usize = 48100;