add nes cartridge subsystem and 41 ines mapper variants
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
const types = @import("types.zig");
|
||||
const Mirroring = types.Mirroring;
|
||||
|
||||
const Mapper76 = @This();
|
||||
|
||||
bank_select: u8 = 0,
|
||||
bank_registers: [8]u8 = [_]u8{0} ** 8,
|
||||
prg_bank_count: usize,
|
||||
chr_bank_count: usize,
|
||||
fixed_mirroring: Mirroring,
|
||||
|
||||
pub fn init(
|
||||
prg_size: usize,
|
||||
chr_size: usize,
|
||||
mirroring_mode: Mirroring,
|
||||
) Mapper76 {
|
||||
return .{
|
||||
.prg_bank_count = prg_size / 0x2000,
|
||||
.chr_bank_count = if (chr_size > 0) chr_size / 0x0800 else 1,
|
||||
.fixed_mirroring = mirroring_mode,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn cpuMapRead(
|
||||
self: *const Mapper76,
|
||||
address: u16,
|
||||
) ?usize {
|
||||
if (address < 0x8000) return null;
|
||||
|
||||
const offset = @as(usize, address & 0x1fff);
|
||||
const last_bank = self.prg_bank_count - 1;
|
||||
const second_last_bank = self.prg_bank_count - 2;
|
||||
|
||||
const r6 = @as(usize, self.bank_registers[6]) % self.prg_bank_count;
|
||||
const r7 = @as(usize, self.bank_registers[7]) % self.prg_bank_count;
|
||||
|
||||
switch ((address - 0x8000) / 0x2000) {
|
||||
0 => return r6 * 0x2000 + offset,
|
||||
1 => return r7 * 0x2000 + offset,
|
||||
2 => return second_last_bank * 0x2000 + offset,
|
||||
3 => return last_bank * 0x2000 + offset,
|
||||
else => unreachable,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cpuWrite(
|
||||
self: *Mapper76,
|
||||
address: u16,
|
||||
value: u8,
|
||||
) void {
|
||||
if (address < 0x8000) return;
|
||||
|
||||
if ((address & 1) == 0) {
|
||||
self.bank_select = value & 0x07;
|
||||
} else {
|
||||
self.bank_registers[self.bank_select] = value;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ppuMapRead(
|
||||
self: *const Mapper76,
|
||||
address: u16,
|
||||
) ?usize {
|
||||
if (address >= 0x2000) return null;
|
||||
|
||||
const offset = @as(usize, address & 0x07ff);
|
||||
const slot = address / 0x0800;
|
||||
const reg_idx = @as(usize, 2 + slot);
|
||||
const bank = (@as(usize, self.bank_registers[reg_idx])) % self.chr_bank_count;
|
||||
|
||||
return bank * 0x0800 + offset;
|
||||
}
|
||||
|
||||
pub fn ppuMapWrite(
|
||||
self: *const Mapper76,
|
||||
address: u16,
|
||||
) ?usize {
|
||||
return self.ppuMapRead(address);
|
||||
}
|
||||
|
||||
pub fn mirroring(
|
||||
self: *const Mapper76,
|
||||
) Mirroring {
|
||||
return self.fixed_mirroring;
|
||||
}
|
||||
|
||||
pub fn irqAsserted(
|
||||
_: *const Mapper76,
|
||||
) bool {
|
||||
return false;
|
||||
}
|
||||
Reference in New Issue
Block a user