use crate::cartridge::base_mapper::BaseMapper;
use crate::cartridge::mapper::{Mapper, MapperCapabilities};
pub struct Mapper327 {
base: BaseMapper,
}
impl Mapper327 {
pub fn new(ctx: super::mapper::MapperContext) -> Self {
let capabilities = MapperCapabilities {
prg_bank_size_kb: 32,
chr_bank_size_kb: 8,
max_prg_ram_kb: 0,
..Default::default()
};
let mut base = BaseMapper::new(&ctx, capabilities);
base.configure_prg_banking(32 * 1024);
base.configure_chr_banking(8 * 1024);
let mut mapper = Self { base };
mapper.update_banks();
mapper
}
fn update_banks(&mut self) {
self.base.select_prg_page(0, 0);
self.base.select_chr_page(0, 0);
}
}
impl Mapper for Mapper327 {
fn base(&self) -> &BaseMapper {
&self.base
}
fn base_mut(&mut self) -> &mut BaseMapper {
&mut self.base
}
fn read_prg(&self, addr: u16) -> u8 {
match addr {
0x8000..=0xFFFF => self.base.read_prg_rom(addr),
_ => 0,
}
}
fn write_prg(&mut self, _addr: u16, _value: u8) {
}
fn registers_snapshot(&self) -> Vec<u8> {
vec![]
}
fn restore_registers(&mut self, _data: &[u8]) {}
fn reset(&mut self) {}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::cartridge::NametableLayout;
use crate::cartridge::mapper::{MapperContext, create_mapper};
use crate::cartridge::test_helpers::banked_data;
const PRG_BANKS: usize = 3; const CHR_BANKS: usize = 5;
fn make_mapper() -> Mapper327 {
let prg = banked_data(32 * 1024, PRG_BANKS);
let chr = banked_data(8 * 1024, CHR_BANKS);
Mapper327::new(MapperContext::new_for_test(
327,
prg,
chr,
NametableLayout::Horizontal,
))
}
#[test]
fn mapper_327_is_registered() {
let prg = banked_data(32 * 1024, PRG_BANKS);
let chr = banked_data(8 * 1024, CHR_BANKS);
let result = create_mapper(MapperContext::new_for_test(
327,
prg,
chr,
NametableLayout::Horizontal,
));
assert!(
result.is_ok(),
"Mapper 327 must be registered in the factory"
);
}
#[test]
fn power_on_prg_8000_reads_bank_0() {
let mapper = make_mapper();
assert_eq!(
mapper.read_prg(0x8000),
0,
"$8000 must map to PRG bank 0 at power-on"
);
}
#[test]
fn power_on_prg_ffff_reads_bank_0_last_byte() {
let prg = banked_data(32 * 1024, PRG_BANKS);
let chr = banked_data(8 * 1024, CHR_BANKS);
let expected = prg[0x7FFF];
let mapper = Mapper327::new(MapperContext::new_for_test(
327,
prg,
chr,
NametableLayout::Horizontal,
));
assert_eq!(
mapper.read_prg(0xFFFF),
expected,
"$FFFF must read last byte of PRG bank 0"
);
}
#[test]
fn power_on_chr_0000_reads_bank_0() {
let mut mapper = make_mapper();
assert_eq!(
mapper.read_chr(0x0000),
0,
"$0000 must map to CHR bank 0 at power-on"
);
}
#[test]
fn power_on_chr_1fff_reads_bank_0_last_byte() {
let prg = banked_data(32 * 1024, PRG_BANKS);
let chr = banked_data(8 * 1024, CHR_BANKS);
let expected = chr[0x1FFF];
let mut mapper = Mapper327::new(MapperContext::new_for_test(
327,
prg,
chr,
NametableLayout::Horizontal,
));
assert_eq!(
mapper.read_chr(0x1FFF),
expected,
"$1FFF must read last byte of CHR bank 0"
);
}
#[test]
fn writes_to_prg_space_do_not_change_prg() {
let mut mapper = make_mapper();
mapper.write_prg(0x8000, 0xFF);
mapper.write_prg(0xFFFF, 0xFF);
assert_eq!(
mapper.read_prg(0x8000),
0,
"PRG must remain bank 0 after writes"
);
}
#[test]
fn mirroring_fixed_from_header_horizontal() {
let mapper = make_mapper();
assert_eq!(
mapper.get_mirroring(),
NametableLayout::Horizontal,
"Mirroring must be fixed from header"
);
}
#[test]
fn mirroring_not_changed_by_writes() {
let mut mapper = make_mapper();
mapper.write_prg(0x8000, 0xFF);
assert_eq!(
mapper.get_mirroring(),
NametableLayout::Horizontal,
"Mirroring must not change after writes"
);
}
#[test]
fn irq_never_pending() {
let mut mapper = make_mapper();
mapper.write_prg(0x8000, 0xFF);
assert!(!mapper.irq_pending(), "Mapper 327 must never assert IRQ");
}
#[test]
fn registers_snapshot_is_empty() {
let mapper = make_mapper();
assert!(
mapper.registers_snapshot().is_empty(),
"Mapper 327 has no registers; snapshot must be empty"
);
}
#[test]
fn restore_registers_with_empty_data_is_noop() {
let mut mapper = make_mapper();
mapper.restore_registers(&[]);
assert_eq!(mapper.read_prg(0x8000), 0);
}
#[test]
fn reset_leaves_prg_at_bank_0() {
let mut mapper = make_mapper();
mapper.reset();
assert_eq!(
mapper.read_prg(0x8000),
0,
"PRG must remain bank 0 after reset"
);
}
}