const types = @import("types.zig"); const Mirroring = types.Mirroring; const Mapper87 = @This(); 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, ) Mapper87 { 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 Mapper87, address: u16, ) ?usize { if (address < 0x8000) return null; const offset = @as(usize, address - 0x8000); const bank = if (self.prg_bank_count > 0) (self.prg_bank_count - 1) else 0; return bank * 0x8000 + offset; } pub fn cpuWrite( self: *Mapper87, address: u16, value: u8, ) void { if (address >= 0x6000 and address <= 0x7FFF) { self.chr_bank = ((value & 1) << 1) | ((value >> 1) & 1); } } pub fn ppuMapRead( self: *const Mapper87, 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 Mapper87, address: u16, ) ?usize { if (address >= 0x2000) return null; return address; } pub fn mirroring( self: *const Mapper87, ) Mirroring { return self.mirroring_mode; } pub fn irqAsserted(_: *const Mapper87) bool { return false; }