diff --git a/src/mbc/mbc5.rs b/src/mbc/mbc5.rs new file mode 100644 index 0000000..47450a9 --- /dev/null +++ b/src/mbc/mbc5.rs @@ -0,0 +1,58 @@ +use crate::mbc::mode::MBC; +use crate::memory::Memory; + +pub struct MBC5 { + rom: Vec, + ram: Vec, + ram_enabled: bool, + rom_bank: usize, + ram_bank: usize +} + +impl Memory for MBC5 { + fn read(&self, a: u16) -> u8 { + match a { + 0x0000..=0x3FFF => self.rom[a as usize], + 0x4000..=0x7FFF => self.rom[a as usize + self.rom_bank * 0x4000 - 0x4000], + 0xA000..=0xBFFF => { + if self.ram_enabled { + self.ram[a as usize + self.ram_bank * 0x2000 - 0xA000] + } else { + 0x00 + } + } + _ => panic!("Read to unsupported MBC5 address ({:#06x})!", a), + } + } + + fn write(&mut self, a: u16, v: u8) { + match a { + 0x0000..=0x1FFF => self.ram_enabled = v & 0x0F == 0x0A, + 0x2000..=0x2FFF => self.rom_bank = (self.rom_bank & 0x100) | (v as usize), + 0x3000..=0x3FFF => self.rom_bank = (self.rom_bank & 0x0ff) | (((v & 0x01) as usize) << 8), + 0x4000..=0x5FFF => self.ram_bank = (v & 0x0f) as usize, + // Unknown writes + 0x6000..=0x7FFF => {}, + 0xA000..=0xBFFF => { + if self.ram_enabled { + self.ram[a as usize + self.ram_bank * 0x2000 - 0xA000] = v; + } + } + _ => panic!("Write to unsupported MBC5 address ({:#06x})!", a), + } + } +} + +impl MBC for MBC5 { } + +impl MBC5 { + pub fn new(rom: Vec) -> Self { + Self { + rom, + ram: vec![0x00; 131072], + ram_enabled: false, + rom_bank: 0x00, + ram_bank: 0x00 + } + } +} \ No newline at end of file diff --git a/src/mbc/mod.rs b/src/mbc/mod.rs index 362f518..dfc7870 100644 --- a/src/mbc/mod.rs +++ b/src/mbc/mod.rs @@ -1,4 +1,5 @@ pub mod mode; pub mod rom_only; pub mod mbc1; -pub mod mbc3; \ No newline at end of file +pub mod mbc3; +pub mod mbc5; \ No newline at end of file diff --git a/src/mmu.rs b/src/mmu.rs index 99f3b99..a100050 100644 --- a/src/mmu.rs +++ b/src/mmu.rs @@ -3,6 +3,7 @@ use crate::mbc::mode::{MBC, MBCMode}; use crate::mbc::rom_only::ROMOnly; use crate::mbc::mbc1::MBC1; use crate::mbc::mbc3::MBC3; +use crate::mbc::mbc5::MBC5; use crate::memory::Memory; use crate::ppu::PPU; use crate::timer::Timer; @@ -38,6 +39,7 @@ impl MMU { MBCMode::RomOnly => Box::new(ROMOnly::new(rom)), MBCMode::MBC1 => Box::new(MBC1::new(rom)), MBCMode::MBC3 => Box::new(MBC3::new(rom)), + MBCMode::MBC5 => Box::new(MBC5::new(rom)), v => panic!("Unsupported MBC type! {:}", v) };