use crate::nes::cartridge::base_mapper::BaseMapper;
use crate::nes::cartridge::mapper::{Mapper, MapperCapabilities, MapperContext};
pub struct Mapper143 {
base: BaseMapper,
}
impl Mapper143 {
pub fn new(ctx: MapperContext) -> Self {
let capabilities = MapperCapabilities {
max_prg_ram_kb: 0,
..Default::default()
};
let base = BaseMapper::new(&ctx, capabilities);
Self { base }
}
fn is_protection_window(addr: u16) -> bool {
(0x4100..=0x5FFF).contains(&addr)
}
fn copy_protection_response(addr: u16) -> u8 {
(!(addr as u8) & 0x3F) | 0x40
}
}
impl Mapper for Mapper143 {
fn base(&self) -> &BaseMapper {
&self.base
}
fn base_mut(&mut self) -> &mut BaseMapper {
&mut self.base
}
fn read_prg_open_bus(&self, addr: u16, open_bus: u8) -> u8 {
if Self::is_protection_window(addr) {
return Self::copy_protection_response(addr);
}
self.base
.read_prg_open_bus(addr, open_bus, |a| self.read_prg(a))
}
fn write_prg(&mut self, _addr: u16, _value: u8) {
}
}
#[cfg(test)]
mod tests {
use crate::nes::cartridge::NametableLayout;
use crate::nes::cartridge::mapper::{MapperContext, create_mapper};
use crate::nes::cartridge::test_helpers::banked_data;
const PRG_BANK_16K: usize = 16 * 1024;
const CHR_BANK_8K: usize = 8 * 1024;
fn make_mapper143() -> Box<dyn crate::nes::cartridge::mapper::Mapper> {
let prg = banked_data(PRG_BANK_16K, 2);
let chr = banked_data(CHR_BANK_8K, 1);
create_mapper(MapperContext::new_for_test(
143,
prg,
chr,
NametableLayout::Vertical,
))
.expect("Mapper 143 must be registered in factory")
}
#[test]
fn mapper_143_is_registered_in_factory() {
let prg = banked_data(PRG_BANK_16K, 2);
let chr = banked_data(CHR_BANK_8K, 1);
let result = create_mapper(MapperContext::new_for_test(
143,
prg,
chr,
NametableLayout::Vertical,
));
assert!(result.is_ok(), "Mapper 143 must be creatable via factory");
}
#[test]
fn protection_read_at_4100_returns_addr_not_low_byte_or_0x40() {
let mapper = make_mapper143();
let val = mapper.read_prg_open_bus(0x4100, 0x00);
assert_eq!(val, 0x7F, "read at $4100 should return 0x7F");
}
#[test]
fn protection_read_at_4101_returns_addr_not_low_byte_or_0x40() {
let mapper = make_mapper143();
let val = mapper.read_prg_open_bus(0x4101, 0x00);
assert_eq!(val, 0x7E, "read at $4101 should return 0x7E");
}
#[test]
fn protection_read_at_5fff_returns_addr_not_low_byte_or_0x40() {
let mapper = make_mapper143();
let val = mapper.read_prg_open_bus(0x5FFF, 0x00);
assert_eq!(val, 0x40, "read at $5FFF should return 0x40");
}
#[test]
fn prg_bank_0_is_fixed_at_8000() {
let mapper = make_mapper143();
assert_eq!(
mapper.read_prg(0x8000),
0,
"bank 0 should be fixed at $8000"
);
}
#[test]
fn prg_bank_1_is_fixed_at_c000() {
let mapper = make_mapper143();
assert_eq!(
mapper.read_prg(0xC000),
1,
"bank 1 should be fixed at $C000"
);
}
#[test]
fn chr_is_fixed_at_bank_0() {
let mut mapper = make_mapper143();
assert_eq!(mapper.read_chr(0x0000), 0, "CHR should be fixed at bank 0");
}
}