diff --git a/src/nes/bus.rs b/src/nes/bus.rs index 09513af..2c90bd1 100644 --- a/src/nes/bus.rs +++ b/src/nes/bus.rs @@ -53,7 +53,7 @@ impl Memory for Bus { fn readb(&self, addr: Addr) -> Byte { if let Some(cartridge) = &self.cartridge { if CART_ADDR_RANGE[0] <= addr && addr <= CART_ADDR_RANGE[1] { - return cartridge.borrow().readb(addr) + return cartridge.borrow().readb(addr).unwrap() // does not fail. } } if RAM_ADDR_RANGE[0] <= addr && addr <= RAM_ADDR_RANGE[1] { @@ -71,7 +71,7 @@ impl Memory for Bus { fn writeb(&mut self, addr: Addr, data: Byte) { if let Some(cartridge) = &mut self.cartridge { if CART_ADDR_RANGE[0] <= addr && addr <= CART_ADDR_RANGE[1] { - cartridge.borrow_mut().writeb(addr, data) + cartridge.borrow_mut().writeb(addr, data); } } if RAM_ADDR_RANGE[0] <= addr && addr <= RAM_ADDR_RANGE[1] { diff --git a/src/nes/cartridge.rs b/src/nes/cartridge.rs index 71b4db2..ff19382 100644 --- a/src/nes/cartridge.rs +++ b/src/nes/cartridge.rs @@ -1,5 +1,4 @@ use crate::nes::mappers::*; -use crate::nes::Memory; use failure::Error; use std::io::prelude::*; use std::fs::File; @@ -102,21 +101,38 @@ impl Cartridge { mapper: Box::new(Mapper0::new(1, 1)) } } -} -impl Memory for Cartridge { - fn readb(&self, addr: Addr) -> Byte { - let mapped_addr = self.mapper.map_read_addr(addr); - self.prg_rom[mapped_addr as usize] + pub fn readb(&self, addr: Addr) -> Option { + if let Some(mapped_addr) = self.mapper.map_read_addr(addr) { + return Some(self.prg_rom[mapped_addr as usize]) + } + None } - fn writeb(&mut self, addr: Addr, data: Byte) { - let mapped_addr = self.mapper.map_write_addr(addr); - self.prg_rom[mapped_addr as usize] = data; + pub fn writeb(&mut self, addr: Addr, data: Byte) -> bool { + if let Some(mapped_addr) = self.mapper.map_write_addr(addr) { + self.prg_rom[mapped_addr as usize] = data; + return true + } + false + } + + // Read from cartridge if the cartridge has readable VRAM/VROM + pub fn readb_ppu(&self, addr: Addr) -> Option { + // TODO + None + } + + // Let the cartridge handle the ppu write. Returns true if cartridge + // handled the write, false otherwise + pub fn writeb_ppu(&mut self, addr: Addr, data: Byte) -> bool { + // TODO + false } } + #[cfg(test)] mod tests { use super::*; diff --git a/src/nes/mappers.rs b/src/nes/mappers.rs index 316101d..a61b390 100644 --- a/src/nes/mappers.rs +++ b/src/nes/mappers.rs @@ -1,8 +1,8 @@ use crate::nes::types::*; pub trait Mapper { - fn map_read_addr(&self, addr: Addr) -> Addr; - fn map_write_addr(&self, addr: Addr) -> Addr; + fn map_read_addr(&self, addr: Addr) -> Option; + fn map_write_addr(&self, addr: Addr) -> Option; } // Mapper 0 @@ -29,24 +29,24 @@ impl Mapper0 { } impl Mapper for Mapper0 { - fn map_read_addr(&self, addr: Addr) -> Addr { + fn map_read_addr(&self, addr: Addr) -> Option { if 0x8000 <= addr && addr <= 0xFFFF { if self.prg_banks > 1 { - return addr & 0x7fff; + return Some(addr & 0x7fff); } else { - return addr & 0x3fff; + return Some(addr & 0x3fff); } } - 0x0000 + None } - fn map_write_addr(&self, addr: Addr) -> Addr { + fn map_write_addr(&self, addr: Addr) -> Option { if 0x8000 <= addr && addr <= 0xFFFF { if self.prg_banks > 1 { - return addr & 0x7fff; + return Some(addr & 0x7fff); } else { - return addr & 0x3fff; + return Some(addr & 0x3fff); } } - 0x0000 + None } } diff --git a/src/nes/ppubus.rs b/src/nes/ppubus.rs index 2da56a9..889d26e 100644 --- a/src/nes/ppubus.rs +++ b/src/nes/ppubus.rs @@ -35,6 +35,13 @@ impl PPUBus { impl PPUMemory for PPUBus { fn readb_ppu(&self, addr: Addr) -> Byte { + // give the cartridge a chance to handle it + if let Some(cartridge) = &self.cartridge { + if let Some(data) = cartridge.borrow().readb_ppu(addr) { + return data + } + } + if PATTERN_ADDR_RANGE[0] <= addr && addr <= PATTERN_ADDR_RANGE[1] { let table = if addr < 0x1000 { 0 } else { 1 }; return self.pattern_memory[table as usize][(addr % 0x1000) as usize] @@ -60,6 +67,13 @@ impl PPUMemory for PPUBus { 0x00 } fn writeb_ppu(&mut self, addr: Addr, data: Byte) { + // give the cartridge a chance to handle it + if let Some(cartridge) = &self.cartridge { + if cartridge.borrow_mut().writeb_ppu(addr, data) { + return + } + } + if PATTERN_ADDR_RANGE[0] <= addr && addr <= PATTERN_ADDR_RANGE[1] { let table = if addr < 0x1000 { 0 } else { 1 }; self.pattern_memory[table as usize][(addr % 0x1000) as usize] = data;