Code for the Namco 175 and Namco 340 boards (iNES mapper 210).
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Encode, Decode)] 9enum Variant { 10 Namco175, 11 Namco340, 12 Unknown, 13} 14 15#[derive(Debug, Clone, Encode, Decode)] 16pub(crate) struct Namco175 { 17 variant: Variant, 18 chr_type: ChrType, 19 nametable_mirroring: NametableMirroring, 20 prg_banks: [u8; 3], 21 chr_banks: [u8; 8], 22 ram_enabled: bool, 23} 24 25impl Namco175 { 26 pub(crate) fn new( 27 sub_mapper_number: u8, 28 chr_type: ChrType, 29 nametable_mirroring: NametableMirroring, 30 ) -> Self { 31 let variant = match sub_mapper_number { 32 1 => Variant::Namco175, 33 2 => Variant::Namco340, 34 _ => Variant::Unknown, 35 }; 36 37 log::info!("Namco 175 variant: {variant:?}"); 38 39 Self { 40 variant, 41 chr_type, 42 nametable_mirroring, 43 prg_banks: [0; 3], 44 chr_banks: [0; 8], 45 ram_enabled: false, 46 } 47 } 48} 49 50impl MapperImpl<Namco175> { 51 pub(crate) fn read_cpu_address(&self, address: u16, cpu_open_bus: u8) -> u8 { 52 match address { 53 0x0000..=0x401F => panic!("invalid CPU map address: {address:04X}"), 54 0x4020..=0x5FFF => cpu_open_bus, 55 0x6000..=0x7FFF => { 56 if self.data.ram_enabled && !self.cartridge.prg_ram.is_empty() { 57 self.cartridge.get_prg_ram((address & 0x1FFF).into()) 58 } else { 59 cpu_open_bus 60 } 61 } 62 0x8000..=0xDFFF => { 63 let bank_index = (address & 0x7FFF) / 0x2000; 64 let bank_number = self.data.prg_banks[bank_index as usize]; 65 let prg_rom_addr = BankSizeKb::Eight.to_absolute_address(bank_number, address); 66 self.cartridge.get_prg_rom(prg_rom_addr) 67 } 68 0xE000..=0xFFFF => { 69 let prg_rom_addr = BankSizeKb::Eight 70 .to_absolute_address_last_bank(self.cartridge.prg_rom.len() as u32, address); 71 self.cartridge.get_prg_rom(prg_rom_addr) 72 } 73 } 74 } 75 76 pub(crate) fn write_cpu_address(&mut self, address: u16, value: u8) { 77 match address { 78 0x0000..=0x401F => panic!("invalid CPU map address: {address:04X}"), 79 0x6000..=0x7FFF if self.data.ram_enabled && !self.cartridge.prg_ram.is_empty() => { 80 self.cartridge.set_prg_ram((address & 0x1FFF).into(), value); 81 } 82 0x8000..=0xBFFF => { 83 let bank_index = (address & 0x7FFF) / 0x0800; 84 self.data.chr_banks[bank_index as usize] = value; 85 } 86 0xC000..=0xC7FF => { 87 if matches!(self.data.variant, Variant::Namco175 | Variant::Unknown) { 88 self.data.ram_enabled = value.bit(0); 89 } 90 } 91 0xE000..=0xE7FF => { 92 self.data.prg_banks[0] = value & 0x3F; 93 94 if matches!(self.data.variant, Variant::Namco340 | Variant::Unknown) { 95 self.data.nametable_mirroring = match value & 0xC0 { 96 0x00 => NametableMirroring::SingleScreenBank0, 97 0x40 => NametableMirroring::Vertical, 98 0x80 => NametableMirroring::SingleScreenBank1, 99 0xC0 => NametableMirroring::Horizontal, 100 _ => unreachable!("value & 0xC0 should always be 0x00/0x40/0x80/0xC0"), 101 }; 102 } 103 } 104 0xE800..=0xEFFF => { 105 self.data.prg_banks[1] = value & 0x3F; 106 } 107 0xF000..=0xF7FF => { 108 self.data.prg_banks[2] = value & 0x3F; 109 } 110 _ => {} 111 } 112 } 113} 114 115impl HasBasicPpuMapping for MapperImpl<Namco175> { 116 fn map_ppu_address(&self, address: u16) -> PpuMapResult { 117 match address { 118 0x0000..=0x1FFF => { 119 let bank_index = address / 0x0400; 120 let bank_number = self.data.chr_banks[bank_index as usize]; 121 let chr_addr = BankSizeKb::One.to_absolute_address(bank_number, address); 122 self.data.chr_type.to_map_result(chr_addr) 123 } 124 0x2000..=0x3EFF => { 125 PpuMapResult::Vram(self.data.nametable_mirroring.map_to_vram(address)) 126 } 127 0x3F00..=0xFFFF => panic!("invalid PPU map result: {address:04X}"), 128 } 129 } 130}