fix(io): respect read-only bits in DISPSTAT

Superstar Saga now renders correctly
This commit is contained in:
Rekai Nyangadzayi Musuka 2022-11-02 07:54:06 -03:00
parent 505b1b9608
commit 102b2c946b
2 changed files with 12 additions and 3 deletions

View File

@ -317,14 +317,23 @@ pub const DisplayControl = extern union {
/// Read / Write /// Read / Write
pub const DisplayStatus = extern union { pub const DisplayStatus = extern union {
/// read-only
vblank: Bit(u16, 0), vblank: Bit(u16, 0),
/// read-only
hblank: Bit(u16, 1), hblank: Bit(u16, 1),
// read-only
coincidence: Bit(u16, 2), coincidence: Bit(u16, 2),
vblank_irq: Bit(u16, 3), vblank_irq: Bit(u16, 3),
hblank_irq: Bit(u16, 4), hblank_irq: Bit(u16, 4),
vcount_irq: Bit(u16, 5), vcount_irq: Bit(u16, 5),
vcount_trigger: Bitfield(u16, 8, 8), vcount_trigger: Bitfield(u16, 8, 8),
raw: u16, raw: u16,
pub fn set(self: *DisplayStatus, value: u16) void {
const mask: u16 = 0x00C7; // set bits are read-only
self.raw = (self.raw & mask) | (value & ~mask);
}
}; };
/// Read Only /// Read Only

View File

@ -94,7 +94,7 @@ pub fn write(comptime T: type, ppu: *Ppu, addr: u32, value: T) void {
u32 => switch (byte_addr) { u32 => switch (byte_addr) {
0x00 => ppu.dispcnt.raw = @truncate(u16, value), 0x00 => ppu.dispcnt.raw = @truncate(u16, value),
0x04 => { 0x04 => {
ppu.dispstat.raw = @truncate(u16, value); ppu.dispstat.set(@truncate(u16, value));
ppu.vcount.raw = @truncate(u16, value >> 16); ppu.vcount.raw = @truncate(u16, value >> 16);
}, },
0x08 => ppu.setAdjCnts(0, value), 0x08 => ppu.setAdjCnts(0, value),
@ -130,7 +130,7 @@ pub fn write(comptime T: type, ppu: *Ppu, addr: u32, value: T) void {
u16 => switch (byte_addr) { u16 => switch (byte_addr) {
0x00 => ppu.dispcnt.raw = value, 0x00 => ppu.dispcnt.raw = value,
0x02 => {}, // Green Swap 0x02 => {}, // Green Swap
0x04 => ppu.dispstat.raw = value, 0x04 => ppu.dispstat.set(value),
0x06 => {}, // VCOUNT 0x06 => {}, // VCOUNT
0x08 => ppu.bg[0].cnt.raw = value, 0x08 => ppu.bg[0].cnt.raw = value,
@ -178,7 +178,7 @@ pub fn write(comptime T: type, ppu: *Ppu, addr: u32, value: T) void {
u8 => switch (byte_addr) { u8 => switch (byte_addr) {
0x00, 0x01 => ppu.dispcnt.raw = setHalf(u16, ppu.dispcnt.raw, byte_addr, value), 0x00, 0x01 => ppu.dispcnt.raw = setHalf(u16, ppu.dispcnt.raw, byte_addr, value),
0x02, 0x03 => {}, // Green Swap 0x02, 0x03 => {}, // Green Swap
0x04, 0x05 => ppu.dispstat.raw = setHalf(u16, ppu.dispstat.raw, byte_addr, value), 0x04, 0x05 => ppu.dispstat.set(setHalf(u16, ppu.dispstat.raw, byte_addr, value)),
0x06, 0x07 => {}, // VCOUNT 0x06, 0x07 => {}, // VCOUNT
// BGXCNT // BGXCNT