test(nes): consolidate and simplify inline subsystem unit tests

This commit is contained in:
2026-08-27 07:16:26 +02:00
parent f028213c11
commit 57f349fa17
35 changed files with 6856 additions and 0 deletions
+110
View File
@@ -0,0 +1,110 @@
const std = @import("std");
const common = @import("../common.zig");
const Mirroring = common.Mirroring;
// ponytail: Mapper 34 (BNROM / NINA-001) - 32KB PRG banking, optional NINA-001 4KB CHR banking
pub const Bnrom = @This();
prg_bank: u8 = 0,
chr_bank_0: u8 = 0,
chr_bank_1: u8 = 1,
mirroring_mode: Mirroring,
pub fn init(initial_mirroring: Mirroring) Bnrom {
return .{ .mirroring_mode = initial_mirroring };
}
pub fn cpuRead(self: *const Bnrom, address: u16, prg_rom: []const u8, prg_ram: []const u8) ?u8 {
if (address >= 0x6000 and address <= 0x7fff) {
const offset = address - 0x6000;
if (offset < prg_ram.len) return prg_ram[offset];
return 0;
}
if (address >= 0x8000 and address <= 0xffff) {
const total_32k_banks = @max(1, prg_rom.len / 0x8000);
const bank = @as(usize, self.prg_bank) % total_32k_banks;
const offset = (bank * 0x8000) + (address - 0x8000);
if (offset < prg_rom.len) return prg_rom[offset];
return 0;
}
return null;
}
pub fn cpuWrite(self: *Bnrom, address: u16, value: u8, prg_ram: []u8) bool {
if (address >= 0x6000 and address <= 0x7fff) {
// NINA-001 registers
switch (address) {
0x7ffd => {
self.prg_bank = value & 0x0f;
return true;
},
0x7ffe => {
self.chr_bank_0 = value & 0x0f;
return true;
},
0x7fff => {
self.chr_bank_1 = value & 0x0f;
return true;
},
else => {
const offset = address - 0x6000;
if (offset < prg_ram.len) {
prg_ram[offset] = value;
return true;
}
},
}
}
if (address >= 0x8000 and address <= 0xffff) {
// BNROM: select 32KB PRG bank
self.prg_bank = value & 0x0f;
return true;
}
return false;
}
pub fn ppuRead(self: *const Bnrom, address: u16, chr_rom: []const u8, chr_ram: []const u8, chr_is_ram: bool) ?u8 {
if (address < 0x2000) {
if (chr_is_ram) {
if (address < chr_ram.len) return chr_ram[address];
} else if (chr_rom.len > 0) {
const total_4k_banks = @max(1, chr_rom.len / 0x1000);
const bank = if (address < 0x1000)
@as(usize, self.chr_bank_0) % total_4k_banks
else
@as(usize, self.chr_bank_1) % total_4k_banks;
const offset = (bank * 0x1000) + (address & 0x0fff);
if (offset < chr_rom.len) return chr_rom[offset];
}
return 0;
}
return null;
}
pub fn ppuWrite(_: *Bnrom, address: u16, value: u8, chr_ram: []u8, chr_is_ram: bool) bool {
if (address < 0x2000 and chr_is_ram) {
if (address < chr_ram.len) {
chr_ram[address] = value;
return true;
}
}
return false;
}
pub fn mirroring(self: *const Bnrom) Mirroring {
return self.mirroring_mode;
}
pub fn irqLine(_: *const Bnrom) bool {
return false;
}
pub fn notifyPpuAddress(_: *Bnrom, _: u16) void {}
test "bnrom bank switching" {
var bn = Bnrom.init(.vertical);
var ram: [0x2000]u8 = undefined;
_ = bn.cpuWrite(0x8000, 3, &ram);
try std.testing.expectEqual(@as(u8, 3), bn.prg_bank);
}