From 42c6b21124f0a725bf48e62af0a0244658535a2c Mon Sep 17 00:00:00 2001 From: Rekai Musuka Date: Fri, 21 Oct 2022 05:12:49 -0300 Subject: [PATCH] fix: impl BG?{X,Y} RefPoint write behaviour outside of Vblank With this fix Mode 7-like games now properly render their backgrounds --- src/bus/io.zig | 8 ++++---- src/ppu.zig | 10 ++++++++++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/bus/io.zig b/src/bus/io.zig index bafc4fb..77df1d0 100644 --- a/src/bus/io.zig +++ b/src/bus/io.zig @@ -156,12 +156,12 @@ pub fn write(bus: *Bus, comptime T: type, address: u32, value: T) void { 0x0400_001C => bus.ppu.setBgOffsets(3, value), 0x0400_0020 => bus.ppu.aff_bg[0].writePaPb(value), 0x0400_0024 => bus.ppu.aff_bg[0].writePcPd(value), - 0x0400_0028 => bus.ppu.aff_bg[0].x = @bitCast(i32, value), - 0x0400_002C => bus.ppu.aff_bg[0].y = @bitCast(i32, value), + 0x0400_0028 => bus.ppu.aff_bg[0].setX(bus.ppu.dispstat.vblank.read(), value), + 0x0400_002C => bus.ppu.aff_bg[0].setY(bus.ppu.dispstat.vblank.read(), value), 0x0400_0030 => bus.ppu.aff_bg[1].writePaPb(value), 0x0400_0034 => bus.ppu.aff_bg[1].writePcPd(value), - 0x0400_0038 => bus.ppu.aff_bg[1].x = @bitCast(i32, value), - 0x0400_003C => bus.ppu.aff_bg[1].y = @bitCast(i32, value), + 0x0400_0038 => bus.ppu.aff_bg[1].setX(bus.ppu.dispstat.vblank.read(), value), + 0x0400_003C => bus.ppu.aff_bg[1].setY(bus.ppu.dispstat.vblank.read(), value), 0x0400_0040 => log.debug("Wrote 0x{X:0>8} to WIN0H and WIN1H", .{value}), 0x0400_0044 => log.debug("Wrote 0x{X:0>8} to WIN0V and WIN1V", .{value}), 0x0400_0048 => log.debug("Wrote 0x{X:0>8} to WININ and WINOUT", .{value}), diff --git a/src/ppu.zig b/src/ppu.zig index 9d1d38f..0d8ffd9 100644 --- a/src/ppu.zig +++ b/src/ppu.zig @@ -752,6 +752,16 @@ const AffineBackground = struct { }; } + pub fn setX(self: *Self, is_vblank: bool, value: u32) void { + self.x = @bitCast(i32, value); + if (!is_vblank) self.x_latch = @bitCast(i32, value); + } + + pub fn setY(self: *Self, is_vblank: bool, value: u32) void { + self.y = @bitCast(i32, value); + if (!is_vblank) self.y_latch = @bitCast(i32, value); + } + pub fn writePaPb(self: *Self, value: u32) void { self.pa = @bitCast(i16, @truncate(u16, value)); self.pb = @bitCast(i16, @truncate(u16, value >> 16));