test(nes): modularize conformance suite and add NESdev emulator test ROMs

This commit is contained in:
2026-08-27 07:16:28 +02:00
parent 57f349fa17
commit 9ba71b7b62
8 changed files with 327 additions and 0 deletions
+57
View File
@@ -0,0 +1,57 @@
// ponytail: simple stateless harness helpers without custom runner frameworks
const std = @import("std");
const testing = std.testing;
const build_options = @import("build_options");
const Nes = @import("../root.zig").Nes;
pub fn loadRomAlloc(allocator: std.mem.Allocator, relative_path: []const u8) ![]u8 {
const base_dir = build_options.nes_test_roms_dir orelse return error.SkipZigTest;
var dir = try std.Io.Dir.openDirAbsolute(testing.io, base_dir, .{});
defer dir.close(testing.io);
return try dir.readFileAlloc(testing.io, relative_path, allocator, @enumFromInt(10 * 1024 * 1024));
}
// ponytail: runRom asserts progress so test blocks can be concise 1-liners
pub fn runRom(relative_path: []const u8, frames: usize) !Nes {
if (build_options.nes_test_roms_dir == null) return error.SkipZigTest;
const rom_data = try loadRomAlloc(testing.allocator, relative_path);
defer testing.allocator.free(rom_data);
var nes: Nes = undefined;
try nes.init(rom_data);
for (0..frames) |_| {
nes.runFrame();
}
try testing.expect(nes.cpu.cycles > 1_500_000);
try testing.expect(nes.bus.ppu.frame_count >= frames);
return nes;
}
/// Runs a Blargg test ROM and checks $6000 status byte (0x00 = pass, 0x01..0x7F = error code).
pub fn runBlarggRom(relative_path: []const u8, max_frames: usize) !Nes {
if (build_options.nes_test_roms_dir == null) return error.SkipZigTest;
const rom_data = try loadRomAlloc(testing.allocator, relative_path);
defer testing.allocator.free(rom_data);
var nes: Nes = undefined;
try nes.init(rom_data);
var status: u8 = 0x80;
for (0..max_frames) |_| {
nes.runFrame();
status = nes.bus.read(0x6000);
if (status == 0x00) break;
if (status > 0x00 and status < 0x80) return error.BlarggTestFailed;
}
if (status != 0x00) return error.BlarggTestTimeout;
return nes;
}
pub fn countNonBlackPixels(framebuffer: []const u8) usize {
var count: usize = 0;
for (framebuffer) |pixel| {
if (pixel != 0x0F and pixel != 0) count += 1;
}
return count;
}