use crate::nes::cartridge::mapper_templates::SimpleBankedPrgMapper;
pub type UxromInvertedMapper = SimpleBankedPrgMapper<16, 180, false>;
#[cfg(test)]
mod tests {
use super::*;
use crate::nes::cartridge::mapper::MapperContext;
use crate::nes::cartridge::{Mapper, NametableLayout};
fn make_128k_prg() -> Vec<u8> {
(0u8..8).flat_map(|bank| vec![bank; 16 * 1024]).collect()
}
#[test]
fn test_lower_window_fixed_to_bank_0() {
let mut mapper = UxromInvertedMapper::new(
MapperContext::new_for_test(180, make_128k_prg(), vec![], NametableLayout::Horizontal)
.with_prg_ram_banks(0)
.with_unspecified_prg_ram_size()
.with_submapper(2),
);
assert_eq!(
mapper.read_prg(0x8000),
0,
"$8000 should read bank 0 initially"
);
assert_eq!(
mapper.read_prg(0xBFFF),
0,
"$BFFF should read bank 0 initially"
);
mapper.write_prg(0x8000, 3);
assert_eq!(
mapper.read_prg(0x8000),
0,
"$8000 must remain fixed to bank 0 after write"
);
assert_eq!(
mapper.read_prg(0xBFFF),
0,
"$BFFF must remain fixed to bank 0 after write"
);
mapper.write_prg(0x8000, 7);
assert_eq!(
mapper.read_prg(0x8000),
0,
"$8000 must remain fixed to bank 0 at bank 7"
);
}
#[test]
fn test_upper_window_switchable() {
let mut mapper = UxromInvertedMapper::new(
MapperContext::new_for_test(180, make_128k_prg(), vec![], NametableLayout::Horizontal)
.with_prg_ram_banks(0)
.with_unspecified_prg_ram_size()
.with_submapper(2),
);
assert_eq!(
mapper.read_prg(0xC000),
0,
"$C000 should be bank 0 initially"
);
assert_eq!(
mapper.read_prg(0xFFFF),
0,
"$FFFF should be bank 0 initially"
);
mapper.write_prg(0x8000, 3);
assert_eq!(mapper.read_prg(0xC000), 3, "$C000 should switch to bank 3");
assert_eq!(mapper.read_prg(0xFFFF), 3, "$FFFF should switch to bank 3");
mapper.write_prg(0xFFFF, 5);
assert_eq!(mapper.read_prg(0xC000), 5, "$C000 should switch to bank 5");
mapper.write_prg(0xC000, 1);
assert_eq!(mapper.read_prg(0xC000), 1, "$C000 should switch to bank 1");
}
#[test]
fn test_bank_select_mask_3_bits() {
let mut mapper = UxromInvertedMapper::new(
MapperContext::new_for_test(180, make_128k_prg(), vec![], NametableLayout::Horizontal)
.with_prg_ram_banks(0)
.with_unspecified_prg_ram_size()
.with_submapper(2),
);
mapper.write_prg(0x8000, 0b0000_1101);
assert_eq!(
mapper.read_prg(0xC000),
5,
"$C000 should be bank 5 when writing 13 (0b1101) to 3-bit masked register (13 & 7 = 5)"
);
assert_eq!(
mapper.read_prg(0x8000),
0,
"$8000 must remain bank 0 regardless of register write"
);
}
#[test]
fn test_registers_snapshot_restore() {
let prg = make_128k_prg();
let mut original = UxromInvertedMapper::new(
MapperContext::new_for_test(180, prg.clone(), vec![], NametableLayout::Horizontal)
.with_prg_ram_banks(0)
.with_unspecified_prg_ram_size()
.with_submapper(2),
);
original.write_prg(0x8000, 5);
original.write_chr(0x0000, 0xAB);
let snapshot = original.registers_snapshot();
let chr_snapshot = original.chr_ram_snapshot();
let mut restored = UxromInvertedMapper::new(
MapperContext::new_for_test(180, prg, vec![], NametableLayout::Horizontal)
.with_prg_ram_banks(0)
.with_unspecified_prg_ram_size()
.with_submapper(2),
);
restored.restore_registers(&snapshot);
restored.restore_chr_ram(&chr_snapshot);
assert_eq!(
restored.read_prg(0xC000),
5,
"Upper window should restore to bank 5"
);
assert_eq!(
restored.read_prg(0x8000),
0,
"Lower window must stay fixed at bank 0 after restore"
);
assert_eq!(
restored.read_chr(0x0000),
0xAB,
"CHR-RAM should restore correctly"
);
}
#[test]
fn test_chr_ram_read_write() {
let mut mapper = UxromInvertedMapper::new(
MapperContext::new_for_test(180, make_128k_prg(), vec![], NametableLayout::Horizontal)
.with_prg_ram_banks(0)
.with_unspecified_prg_ram_size(),
);
mapper.write_chr(0x0000, 0x55);
mapper.write_chr(0x1000, 0xAA);
mapper.write_chr(0x1FFF, 0xFF);
assert_eq!(mapper.read_chr(0x0000), 0x55);
assert_eq!(mapper.read_chr(0x1000), 0xAA);
assert_eq!(mapper.read_chr(0x1FFF), 0xFF);
}
#[test]
fn test_mapper_number() {
let mapper = UxromInvertedMapper::new(
MapperContext::new_for_test(180, make_128k_prg(), vec![], NametableLayout::Horizontal)
.with_prg_ram_banks(0)
.with_unspecified_prg_ram_size(),
);
assert_eq!(mapper.mapper_number(), 180);
}
}