From 570ff8536caf59c157285331b0bbf85bbae864e3 Mon Sep 17 00:00:00 2001 From: Rekai Musuka Date: Fri, 21 Oct 2022 05:12:41 -0300 Subject: [PATCH] chore: resolve incorrect memory mirror in VRAM + stub GPIO registers on ROM Write --- src/bus/GamePak.zig | 25 ++++++++++++++++++------- src/ppu.zig | 8 ++++++-- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/bus/GamePak.zig b/src/bus/GamePak.zig index 2e7e5c5..4ae26fa 100644 --- a/src/bus/GamePak.zig +++ b/src/bus/GamePak.zig @@ -113,18 +113,29 @@ pub fn write(self: *Self, comptime T: type, word_count: u16, address: u32, value } } - log.err("Wrote {} {X:} to 0x{X:0>8}", .{ T, value, address }); + switch (T) { + u32 => switch (address) { + 0x0800_00C4 => log.err("Wrote {} 0x{X:} to I/O Port Data and Direction", .{ T, value }), + 0x0800_00C6 => log.err("Wrote {} 0x{X:} to I/O Port Direction and Control", .{ T, value }), + else => {}, + }, + u16 => switch (address) { + 0x0800_00C4 => log.err("Wrote {} 0x{X:} to I/O Port Data", .{ T, value }), + 0x0800_00C6 => log.err("Wrote {} 0x{X:} to I/O Port Direction", .{ T, value }), + 0x0800_00C8 => log.err("Wrote {} 0x{X:} to I/O Port Control", .{ T, value }), + else => {}, + }, + u8 => log.warn("Wrote {} 0x{X:} to 0x{X:0>8}, Ignored.", .{ T, value, address }), + else => @compileError("GamePak: Unsupported write width"), + } } fn get(self: *const Self, i: u32) u8 { @setRuntimeSafety(false); + if (i < self.buf.len) return self.buf[i]; - if (i >= self.buf.len) { - const lhs = i >> 1 & 0xFFFF; - return @truncate(u8, lhs >> 8 * @truncate(u5, i & 1)); - } - - return self.buf[i]; + const lhs = i >> 1 & 0xFFFF; + return @truncate(u8, lhs >> 8 * @truncate(u5, i & 1)); } test "OOB Access" { diff --git a/src/ppu.zig b/src/ppu.zig index 9993fd0..c4b06ca 100644 --- a/src/ppu.zig +++ b/src/ppu.zig @@ -600,8 +600,12 @@ const Vram = struct { } fn mirror(address: usize) usize { - const addr = address & 0x1FFFF; // repeated in steps of 128KiB - return if (addr >= 0x18000) addr & 0x7FFF else addr; // 64K + 32K + 32K (abcc) + // Mirrored in steps of 128K (64K + 32K + 32K) (abcc) + const addr = address & 0x1FFFF; + + // If the address is within 96K we don't do anything, + // otherwise we want to mirror the last 32K (addresses between 64K and 96K) + return if (addr < vram_size) addr else 0x10000 + (addr & 0x7FFF); } };