From eb62d598178fdcb3d354418e5260304d247f6015 Mon Sep 17 00:00:00 2001 From: Kevin Hamacher Date: Fri, 14 Feb 2020 13:15:52 +0100 Subject: [PATCH] Add support for MBC5 --- src/cartridge.rs | 5 ++- src/mbc/mbc5.rs | 112 +++++++++++++++++++++++++++++++++++++++++++++++ src/mbc/mod.rs | 1 + 3 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 src/mbc/mbc5.rs diff --git a/src/cartridge.rs b/src/cartridge.rs index c666490..c694d8b 100644 --- a/src/cartridge.rs +++ b/src/cartridge.rs @@ -1,4 +1,4 @@ -use crate::mbc::{mbc, mbc1, mbc2, mbc3}; +use crate::mbc::{mbc, mbc1, mbc2, mbc3, mbc5}; #[derive(Debug, PartialEq)] enum MemoryBankControllerType { @@ -6,6 +6,7 @@ enum MemoryBankControllerType { MBC1, MBC2, MBC3, + MBC5, //HuC1, } @@ -29,6 +30,7 @@ impl Cartridge { 0x01..=0x03 => MemoryBankControllerType::MBC1, 0x05..=0x06 => MemoryBankControllerType::MBC2, 0x0F..=0x13 => MemoryBankControllerType::MBC3, + 0x19..=0x1E => MemoryBankControllerType::MBC5, // 0xFF => MemoryBankControllerType::HuC1, _ => panic!("Unsupported MBC type: {:02X}", rom[0x0147]), }; @@ -62,6 +64,7 @@ impl Cartridge { 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)), }; Cartridge { diff --git a/src/mbc/mbc5.rs b/src/mbc/mbc5.rs new file mode 100644 index 0000000..7cf4d23 --- /dev/null +++ b/src/mbc/mbc5.rs @@ -0,0 +1,112 @@ +use super::mbc::MBC; + +pub struct MBC5 { + rom: Box<[u8]>, + ram: Box<[u8]>, + rom_bank_no: u16, + ram_bank_no: u8, + ram_rtc_enabled: bool, +} + +impl MBC5 { + pub fn new(rom: Box<[u8]>, ram: Box<[u8]>) -> Self { + MBC5 { + rom: rom, + ram: ram, + rom_bank_no: 1, + ram_bank_no: 0, + ram_rtc_enabled: false, + } + } + fn active_rom_bank(&self) -> u16 { + self.rom_bank_no + } + + fn active_ram_bank(&self) -> u8 { + self.ram_bank_no + } +} + +impl MBC for MBC5 { + fn dump_ram(&self, file: &String) { + use crate::write_file; + write_file(&file, &self.ram).expect("Saving failed"); + } + + fn read_byte(&self, addr: u16) -> u8 { + match addr { + 0x0000..=0x3FFF => self.rom[addr as usize], + 0x4000..=0x7FFF => { + let addr = addr - 0x4000; + let abs_addr: usize = addr as usize + self.active_rom_bank() as usize * 0x4000; + let val: u8 = self.rom[abs_addr]; + val + } + 0xA000..=0xBFFF => { + let addr = addr - 0xA000; + match self.active_ram_bank() { + 0x00..=0x03 => { + self.ram[self.active_ram_bank() as usize * 0x2000 + addr as usize] + } + 0x08..=0x0C => { + // TODO + println!("MBC5: Ignoring RTC read"); + 0 + } + _ => panic!( + "MBC5: Accessing unknown RAM bank {:02X}", + self.active_ram_bank() + ), + } + } + _ => { + panic!("MBC5: Unable to read from {:04X}", addr); + } + } + } + + fn write_byte(&mut self, addr: u16, val: u8) { + match addr { + 0x0000..=0x1FFF => match val { + 0x0A => self.ram_rtc_enabled = true, + 0x00 => self.ram_rtc_enabled = false, + _ => println!("MBC5: Unknown MBC value {:02X} for {:04X}", val, addr), + }, + // Lower part rom bank select + 0x2000..=0x2FFF => self.rom_bank_no = (self.rom_bank_no & (!0xFF)) | u16::from(val), + 0x3000..=0x3FFF => { + self.rom_bank_no = (self.rom_bank_no & (0xFF)) | ((u16::from(val) & 1) << 8) + } + 0x4000..=0x5FFF => { + // RAM bank select + self.ram_bank_no = val & 0x0F; + } + 0x6000..=0x7FFF => { + // Latch clock data + match val { + 0x00 => println!("latch = 0"), + 0x01 => println!("latch = 1"), // TODO: This should copy the current clock to the register + _ => panic!("MBC5: Unknown latch value {:02X}", val), + } + } + 0xA000..=0xBFFF => { + let addr = addr - 0xA000; + match self.active_ram_bank() { + 0x00..=0x03 => { + let active_bank = self.active_ram_bank() as usize; + self.ram[active_bank * 0x2000 + addr as usize] = val; + } + 0x08..=0x0C => { + // TODO + println!("MBC5: Ignoring RTC write ({:02X})", val); + } + _ => panic!( + "MBC5: Writing unknown RAM bank {:02X}", + self.active_ram_bank() + ), + } + } + _ => panic!("MBC5: Writing {:02X} to {:04X} not supported", val, addr), + } + } +} diff --git a/src/mbc/mod.rs b/src/mbc/mod.rs index fdcb7ca..889428c 100644 --- a/src/mbc/mod.rs +++ b/src/mbc/mod.rs @@ -2,3 +2,4 @@ pub mod mbc; pub mod mbc1; pub mod mbc2; pub mod mbc3; +pub mod mbc5;