64 lines
2.1 KiB
Rust
64 lines
2.1 KiB
Rust
use crate::{cartridge::Cartridge, ppu::Ppu};
|
|
|
|
pub trait Bus {
|
|
fn read(&mut self, address: u16) -> u8;
|
|
fn write(&mut self, address: u16, value: u8);
|
|
}
|
|
|
|
pub struct NesBus {
|
|
ram: [u8; 0x800], // 2KB fixed array, mirrors to fill $0000 to $1FFF
|
|
cart: Cartridge,
|
|
ppu: Ppu,
|
|
openbus: u8, // last byte on the CPU data bus
|
|
}
|
|
|
|
impl NesBus {
|
|
pub fn new(cart: Cartridge) -> Self {
|
|
Self { ram: [0; 0x800], cart, ppu: Ppu::new(), openbus: 0 }
|
|
}
|
|
|
|
pub fn tick_ppu(&mut self, cycles: u64) {
|
|
self.ppu.tick(&mut self.cart, cycles);
|
|
}
|
|
pub fn frame_done(&self) -> bool {
|
|
self.ppu.frame_done()
|
|
}
|
|
pub fn take_nmi(&mut self) -> bool {
|
|
self.ppu.take_nmi()
|
|
}
|
|
pub fn framebuffer(&self) -> &[u8] {
|
|
self.ppu.framebuffer()
|
|
}
|
|
pub fn begin_frame(&mut self) {
|
|
self.ppu.begin_frame();
|
|
}
|
|
|
|
pub fn ppu(&self) -> &Ppu { &self.ppu }
|
|
pub fn ram(&self) -> &[u8; 0x800] { &self.ram }
|
|
}
|
|
|
|
impl Bus for NesBus {
|
|
fn read(&mut self, address: u16) -> u8 {
|
|
let result = match address {
|
|
0x0000..=0x1FFF => self.ram[(address & 0x07FF) as usize], // Zero-Page my beloved
|
|
0x2000..=0x3FFF => self.ppu.read(&mut self.cart, address, self.openbus),
|
|
0x4000..=0x401F => self.openbus, // APU regs: unmapped reads return bus contents
|
|
0x4020..=0x5FFF => self.openbus, // expansion: open bus
|
|
0x6000..=0x7FFF => self.cart.read_prg_ram(address), // SRAM reads from the cartridge
|
|
0x8000..=0xFFFF => self.cart.read_prg(address), // this is te space PRG Rom gets "loaded" to in real hardware
|
|
};
|
|
self.openbus = result;
|
|
result
|
|
}
|
|
|
|
fn write(&mut self, address: u16, value: u8) {
|
|
match address {
|
|
0x0000..=0x1FFF => self.ram[(address & 0x07FF) as usize] = value,
|
|
0x2000..=0x3FFF => self.ppu.write(&mut self.cart, address, value),
|
|
0x6000..=0x7FFF => self.cart.write_prg_ram(address, value),
|
|
0x8000..=0xFFFF => self.cart.write_prg(address, value),
|
|
_ => {} // Everything else dropped for now
|
|
}
|
|
self.openbus = value;
|
|
}
|
|
} |