const types = @import("types.zig"); const Mirroring = types.Mirroring; const Mapper140 = @This(); prg_bank: u8 = 0, chr_bank: u8 = 0, prg_bank_count: usize, chr_bank_count: usize, mirroring_mode: Mirroring, pub fn init( prg_size: usize, chr_size: usize, _mirroring: Mirroring, ) Mapper140 { return .{ .prg_bank_count = prg_size / 0x8000, .chr_bank_count = if (chr_size > 0) chr_size / 0x2000 else 1, .mirroring_mode = _mirroring, }; } pub fn cpuMapRead( self: *const Mapper140, address: u16, ) ?usize { if (address < 0x8000) return null; const offset = @as(usize, address - 0x8000); const bank = @as(usize, self.prg_bank) % self.prg_bank_count; return bank * 0x8000 + offset; } pub fn cpuWrite( self: *Mapper140, address: u16, value: u8, ) void { if (address >= 0x6000 and address <= 0x7FFF) { self.prg_bank = (value >> 4) & 0x03; self.chr_bank = value & 0x0F; } } pub fn ppuMapRead( self: *const Mapper140, address: u16, ) ?usize { if (address >= 0x2000) return null; const bank = @as(usize, self.chr_bank) % self.chr_bank_count; return bank * 0x2000 + @as(usize, address); } pub fn ppuMapWrite( _: *const Mapper140, address: u16, ) ?usize { if (address >= 0x2000) return null; return address; } pub fn mirroring( self: *const Mapper140, ) Mirroring { return self.mirroring_mode; } pub fn irqAsserted(_: *const Mapper140) bool { return false; }