use crate::core::mappers::AxRom;
use super::{
mappers::{CnRom, NRom, PxRom, SxRom, TxRom, UxRom},
CartridgeMemory, NametableArrangement,
};
use std::fmt::{Debug, Display};
#[typetag::serde(tag = "mapper")]
pub trait Mapper: Debug + Display {
fn read_cpu(&self, cpu_addr: usize, mem: &CartridgeMemory) -> u8;
fn write_cpu(&mut self, cpu_addr: usize, mem: &mut CartridgeMemory, value: u8);
fn read_ppu(&mut self, ppu_addr: usize, mem: &CartridgeMemory) -> u8 {
self.read_ppu_debug(ppu_addr, mem)
}
fn write_ppu(&mut self, ppu_addr: usize, mem: &mut CartridgeMemory, value: u8);
fn read_ppu_debug(&self, ppu_addr: usize, mem: &CartridgeMemory) -> u8;
fn nametable_arrangement(&self, mem: &CartridgeMemory) -> NametableArrangement {
mem.nametable_arrangement
}
fn advance_cpu_cycles(&mut self, _cycles: u32) {}
fn set_addr_value(&mut self, _addr: u32) {}
fn irq(&mut self) -> bool {
false
}
fn mapper_num(&self) -> u32;
fn transform_nametable_addr(&self, _addr: usize) -> usize {
0
}
}
pub fn get_mapper(mapper_id: usize) -> Option<Box<dyn Mapper>> {
Some(match mapper_id {
0 => Box::new(NRom::default()),
1 => Box::new(SxRom::default()),
2 => Box::new(UxRom::default()),
3 => Box::new(CnRom::default()),
4 => Box::new(TxRom::default()),
7 => Box::new(AxRom::default()),
9 => Box::new(PxRom::default()),
_ => return None,
})
}
pub fn bank_addr(bank_size: usize, bank_num: usize, offset: usize) -> usize {
bank_size * bank_num + (offset % bank_size)
}
pub fn num_banks(bank_size: usize, mem: &[u8]) -> usize {
(mem.len() - 1) / bank_size + 1
}