nes_emulator/src/peripherals/mapper/nrom.rs

72 lines
1.8 KiB
Rust

use super::{
Mapper,
super::{
Peripheral,
Ram,
},
};
pub struct Nrom128 {
prg_rom: Ram<0x4000>, //16KiB
prg_ram: Ram<0x2000>, //8KiB
chr_rom: Ram<0x2000>, //8KiB
v_ram: Ram<0x0800>, //2KiB
vertical: bool,
}
impl Peripheral for Nrom128 {
fn read_addr(&self, addr: u16) -> u8 {
match addr {
0x6000..=0x7FFF => self.prg_ram.read_addr(addr - 0x6000),
0x8000..=0xFFFF => self.prg_rom.read_addr((addr - 0x8000) % 0x4000),
//mirrored every 16KiB
_ => panic!("{}: Invalid address", addr),
}
}
fn write_addr(&mut self, addr: u16, data: u8) {
match addr {
0x6000..=0x7FFF => self.prg_ram.write_addr(addr - 0x6000, data),
_ => (), //writes are ignored for rom or invald addresses
}
}
}
impl Mapper for Nrom128 {
fn ppu_read_addr(&self, addr: u16) -> u8 {
match addr {
0x0000..=0x1FFF => self.chr_rom.read_addr(addr),
0x2000..=0x3EFF => {
match self.vertical {
false => match (addr - 0x2000) % 0x0FFF {
0x0000..=0x07FF => self.v_ram.read_addr(addr % 0x0400),
0x0800..=0x0FFF => self.v_ram.read_addr((addr % 0x0400) + 0x0800),
_ => panic!("Unexpected behaviour"),
},
true => self.v_ram.read_addr(addr % 0x0800),
}},
_ => panic!("{}: Invalid ppu address", addr),
}
}
}
impl Nrom128 {
pub fn new(vertical: bool) -> Self {
Self {
prg_rom: Ram::<0x4000>::new(),
prg_ram: Ram::<0x2000>::new(),
chr_rom: Ram::<0x2000>::new(),
v_ram: Ram::<0x0800>::new(),
vertical,
}
}
}