allow cartridge to handle ppu r/w

This commit is contained in:
Daniel Bauer
2020-01-18 21:58:13 +01:00
parent 624791d429
commit 0a16eefab1
4 changed files with 51 additions and 21 deletions

View File

@@ -53,7 +53,7 @@ impl Memory for Bus {
fn readb(&self, addr: Addr) -> Byte { fn readb(&self, addr: Addr) -> Byte {
if let Some(cartridge) = &self.cartridge { if let Some(cartridge) = &self.cartridge {
if CART_ADDR_RANGE[0] <= addr && addr <= CART_ADDR_RANGE[1] { 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] { 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) { fn writeb(&mut self, addr: Addr, data: Byte) {
if let Some(cartridge) = &mut self.cartridge { if let Some(cartridge) = &mut self.cartridge {
if CART_ADDR_RANGE[0] <= addr && addr <= CART_ADDR_RANGE[1] { 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] { if RAM_ADDR_RANGE[0] <= addr && addr <= RAM_ADDR_RANGE[1] {

View File

@@ -1,5 +1,4 @@
use crate::nes::mappers::*; use crate::nes::mappers::*;
use crate::nes::Memory;
use failure::Error; use failure::Error;
use std::io::prelude::*; use std::io::prelude::*;
use std::fs::File; use std::fs::File;
@@ -102,21 +101,38 @@ impl Cartridge {
mapper: Box::new(Mapper0::new(1, 1)) mapper: Box::new(Mapper0::new(1, 1))
} }
} }
}
impl Memory for Cartridge { pub fn readb(&self, addr: Addr) -> Option<Byte> {
fn readb(&self, addr: Addr) -> Byte { if let Some(mapped_addr) = self.mapper.map_read_addr(addr) {
let mapped_addr = self.mapper.map_read_addr(addr); return Some(self.prg_rom[mapped_addr as usize])
self.prg_rom[mapped_addr as usize] }
None
} }
fn writeb(&mut self, addr: Addr, data: Byte) { pub fn writeb(&mut self, addr: Addr, data: Byte) -> bool {
let mapped_addr = self.mapper.map_write_addr(addr); if let Some(mapped_addr) = self.mapper.map_write_addr(addr) {
self.prg_rom[mapped_addr as usize] = data; 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<Byte> {
// 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)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;

View File

@@ -1,8 +1,8 @@
use crate::nes::types::*; use crate::nes::types::*;
pub trait Mapper { pub trait Mapper {
fn map_read_addr(&self, addr: Addr) -> Addr; fn map_read_addr(&self, addr: Addr) -> Option<Addr>;
fn map_write_addr(&self, addr: Addr) -> Addr; fn map_write_addr(&self, addr: Addr) -> Option<Addr>;
} }
// Mapper 0 // Mapper 0
@@ -29,24 +29,24 @@ impl Mapper0 {
} }
impl Mapper for Mapper0 { impl Mapper for Mapper0 {
fn map_read_addr(&self, addr: Addr) -> Addr { fn map_read_addr(&self, addr: Addr) -> Option<Addr> {
if 0x8000 <= addr && addr <= 0xFFFF { if 0x8000 <= addr && addr <= 0xFFFF {
if self.prg_banks > 1 { if self.prg_banks > 1 {
return addr & 0x7fff; return Some(addr & 0x7fff);
} else { } 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<Addr> {
if 0x8000 <= addr && addr <= 0xFFFF { if 0x8000 <= addr && addr <= 0xFFFF {
if self.prg_banks > 1 { if self.prg_banks > 1 {
return addr & 0x7fff; return Some(addr & 0x7fff);
} else { } else {
return addr & 0x3fff; return Some(addr & 0x3fff);
} }
} }
0x0000 None
} }
} }

View File

@@ -35,6 +35,13 @@ impl PPUBus {
impl PPUMemory for PPUBus { impl PPUMemory for PPUBus {
fn readb_ppu(&self, addr: Addr) -> Byte { 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] { if PATTERN_ADDR_RANGE[0] <= addr && addr <= PATTERN_ADDR_RANGE[1] {
let table = if addr < 0x1000 { 0 } else { 1 }; let table = if addr < 0x1000 { 0 } else { 1 };
return self.pattern_memory[table as usize][(addr % 0x1000) as usize] return self.pattern_memory[table as usize][(addr % 0x1000) as usize]
@@ -60,6 +67,13 @@ impl PPUMemory for PPUBus {
0x00 0x00
} }
fn writeb_ppu(&mut self, addr: Addr, data: Byte) { 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] { if PATTERN_ADDR_RANGE[0] <= addr && addr <= PATTERN_ADDR_RANGE[1] {
let table = if addr < 0x1000 { 0 } else { 1 }; let table = if addr < 0x1000 { 0 } else { 1 };
self.pattern_memory[table as usize][(addr % 0x1000) as usize] = data; self.pattern_memory[table as usize][(addr % 0x1000) as usize] = data;