const types = @import("types.zig"); const Mirroring = types.Mirroring; const Irem78 = @This(); prg_bank: u8 = 0, chr_bank: u8 = 0, mirroring_select: u1 = 0, prg_bank_count: usize, chr_bank_count: usize, pub fn init( prg_size: usize, chr_size: usize, ) Irem78 { return .{ .prg_bank_count = prg_size / 0x4000, .chr_bank_count = if (chr_size > 0) chr_size / 0x2000 else 1, }; } pub fn cpuMapRead( self: *const Irem78, address: u16, ) ?usize { if (address < 0x8000) return null; if (address < 0xC000) { const offset = @as(usize, address - 0x8000); const bank = @as(usize, self.prg_bank) % self.prg_bank_count; return bank * 0x4000 + offset; } else { const offset = @as(usize, address - 0xC000); const fixed_bank = if (self.prg_bank_count > 0) self.prg_bank_count - 1 else 0; return fixed_bank * 0x4000 + offset; } } pub fn cpuWrite( self: *Irem78, address: u16, value: u8, ) void { if (address < 0x8000) return; self.prg_bank = value & 0x07; self.mirroring_select = @truncate((value >> 3) & 1); self.chr_bank = (value >> 4) & 0x0F; } pub fn ppuMapRead( self: *const Irem78, 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 Irem78, address: u16, ) ?usize { if (address >= 0x2000) return null; return address; } pub fn mirroring( self: *const Irem78, ) Mirroring { return if (self.mirroring_select == 0) .single_screen_lower else .single_screen_upper; } pub fn irqAsserted(_: *const Irem78) bool { return false; }