From 63ceb7c954daf3e73f119ab635896ac7a8645abb Mon Sep 17 00:00:00 2001 From: Isaac Marovitz Date: Thu, 1 Feb 2024 21:25:49 -0500 Subject: [PATCH] Boot ROM Fixes Fixed DMG, CGB still broken --- src/components/cpu.rs | 13 +++++------ src/components/mmu.rs | 50 +++++++++++++++++++++++++++++++++++++------ src/components/ppu.rs | 3 ++- 3 files changed, 52 insertions(+), 14 deletions(-) diff --git a/src/components/cpu.rs b/src/components/cpu.rs index e4c7747..28200f3 100644 --- a/src/components/cpu.rs +++ b/src/components/cpu.rs @@ -14,10 +14,11 @@ pub struct CPU { } impl CPU { - pub fn new(mut rom: Vec, config: Config) -> Self { + pub fn new(rom: Vec, config: Config) -> Self { + let mut boot_rom: [u8; 0x900] = [0; 0x900]; let booting: bool = match config.boot_rom { Some(ref path) => { - let mut boot_rom = Vec::new(); + let mut boot_rom_vec = Vec::new(); let mut boot = match File::open(path.clone()) { Ok(file) => file, Err(err) => { @@ -25,14 +26,14 @@ impl CPU { process::exit(1); } }; - boot.read_to_end(&mut boot_rom) + boot.read_to_end(&mut boot_rom_vec) .expect("Failed to read Boot ROM!"); // Copy Boot ROM if config.mode == GBMode::DMG { - rom[0..=0x00FF].copy_from_slice(boot_rom.as_slice()); + boot_rom[0..=0x00FF].copy_from_slice(boot_rom_vec.as_slice()); } else if config.mode == GBMode::CGB { - rom[0..=0x08FF].copy_from_slice(boot_rom.as_slice()); + boot_rom[0..=0x08FF].copy_from_slice(boot_rom_vec.as_slice()); } true @@ -42,7 +43,7 @@ impl CPU { Self { reg: Registers::new(config.clone().mode, booting), - mem: MMU::new(rom, config), + mem: MMU::new(rom, config, booting, boot_rom), halted: false, ime: false, ime_ask: false diff --git a/src/components/mmu.rs b/src/components/mmu.rs index 2fe1d77..f0f819b 100644 --- a/src/components/mmu.rs +++ b/src/components/mmu.rs @@ -17,6 +17,9 @@ pub struct MMU { intf: Interrupts, inte: Interrupts, wram_bank: usize, + boot_rom: [u8; 0x900], + boot_rom_enabled: bool, + mode: GBMode } bitflags! { @@ -31,9 +34,8 @@ bitflags! { } impl MMU { - pub fn new(rom: Vec, config: Config) -> Self { - let cart_type: CartTypes = - FromPrimitive::from_u8(rom[0x0147]).expect("Failed to get Cart Type!"); + pub fn new(rom: Vec, config: Config, booting: bool, boot_rom: [u8; 0x900]) -> Self { + let cart_type: CartTypes = FromPrimitive::from_u8(rom[0x0147]).expect("Failed to get Cart Type!"); let mbc_mode = match cart_type.get_mbc() { MBCMode::Unsupported => panic!("Unsupported Cart Type! {:}", cart_type), v => { @@ -64,6 +66,9 @@ impl MMU { intf: Interrupts::empty(), inte: Interrupts::empty(), wram_bank: 0x01, + boot_rom, + boot_rom_enabled: booting, + mode: config.mode } } @@ -99,8 +104,37 @@ impl MMU { impl Memory for MMU { fn read(&self, a: u16) -> u8 { match a { - 0x0000..=0x7FFF => self.mbc.read(a), - 0x8000..=0x9FFF => self.ppu.read(a), + 0x0000..=0x00FF => { + if self.boot_rom_enabled { + self.boot_rom[a as usize] + } else { + self.mbc.read(a) + } + } + 0x0100..=0x1FFF => self.mbc.read(a), + 0x0200..=0x7FFF => { + if self.mode == GBMode::DMG { + self.mbc.read(a) + } else { + if self.boot_rom_enabled { + self.boot_rom[a as usize] + } else { + self.mbc.read(a) + } + } + } + 0x8000..=0x8FFF => { + if self.mode == GBMode::DMG { + self.ppu.read(a) + } else { + if self.boot_rom_enabled { + self.boot_rom[a as usize] + } else { + self.ppu.read(a) + } + } + } + 0x9000..=0x9FFF => self.ppu.read(a), 0xA000..=0xBFFF => self.mbc.read(a), 0xC000..=0xCFFF => self.wram[a as usize - 0xC000], 0xD000..=0xDFFF => self.wram[a as usize - 0xD000 + 0x1000 * self.wram_bank], @@ -141,7 +175,10 @@ impl Memory for MMU { 0xFF04..=0xFF07 => self.timer.write(a, v), 0xFF10..=0xFF3F => self.apu.write(a, v), 0xFF0F => self.intf = Interrupts::from_bits_truncate(v), - 0xFF50..=0xFF5F => {} + 0xFF50 => { + self.boot_rom_enabled = false; + } + 0xFF51..=0xFF5F => {} 0xFF70 => { self.wram_bank = match v & 0x07 { 0 => 1, @@ -149,7 +186,6 @@ impl Memory for MMU { } } 0xFEA0..=0xFEFF => {} - 0xFF7F => {} 0xFFFF => self.inte = Interrupts::from_bits_truncate(v), _ => panic!("Write to unsupported address ({:#06x})!", a), } diff --git a/src/components/ppu.rs b/src/components/ppu.rs index bbcf534..290e338 100644 --- a/src/components/ppu.rs +++ b/src/components/ppu.rs @@ -617,7 +617,7 @@ impl Memory for PPU { } 0xFF42 => self.sy = v, 0xFF43 => self.sx = v, - 0xFF44 => print!("Attempted to write to LY!"), + 0xFF44 => println!("Attempted to write to LY!"), 0xFF45 => { self.lc = v; self.check_lyc(); @@ -627,6 +627,7 @@ impl Memory for PPU { 0xFF49 => self.op1 = v, 0xFF4A => self.wy = v, 0xFF4B => self.wx = v, + 0xFF4C => {} // TODO: Handle PPU speed switching 0xFF4D => {} 0xFF4F => self.ram_bank = (v & 0x01) as usize,