ref: 28e362d368805ad91e0662fcc9577cb74ef13d4e
parent: 9651e5cbd6d9f6064b3ad63246b09194e32139e3
author: Jacob Moody <moody@posixcafe.org>
date: Fri Feb 10 22:38:26 EST 2023
games/gb: implement internal window line counter The y offset used for windows is not based on LY but another internal window counter that is incremented alongside LY but only when the window is on screen. This fixes an issue with the dmg-acid2 and cgb-acid2 test roms. https://github.com/mattcurrie/dmg-acid2 https://gbdev.io/pandocs/Tile_Maps.html#window
--- a/sys/src/games/gb/dat.h
+++ b/sys/src/games/gb/dat.h
@@ -14,7 +14,7 @@
extern Event *elist;
extern ulong clock;
-extern u8int ppuy, ppustate;
+extern u8int ppuy, ppustate, ppuw;
extern u8int apustatus;
--- a/sys/src/games/gb/mem.c
+++ b/sys/src/games/gb/mem.c
@@ -109,6 +109,7 @@
ppusync();
if((~v & reg[a] & LCDEN) != 0){
ppuy = 0;
+ ppuw = 0;
ppustate = 0;
delevent(&evhblank);
}
--- a/sys/src/games/gb/ppu.c
+++ b/sys/src/games/gb/ppu.c
@@ -5,7 +5,7 @@
#include "dat.h"
#include "fns.h"
-u8int ppustate, ppuy;
+u8int ppustate, ppuy, ppuw;
ulong hblclock, rendclock;
jmp_buf mainjmp, renderjmp;
static int cyc, done, ppux, ppux0;
@@ -118,8 +118,8 @@
}while(m > 8);
if(win == -1){
win = 1;
- ta = 0x1800 | reg[LCDC] << 4 & 0x400 | ppuy - reg[WY] << 2 & 0x3e0;
- y = ppuy - reg[WY] << 1 & 14;
+ ta = 0x1800 | reg[LCDC] << 4 & 0x400 | ppuw - reg[WY] << 2 & 0x3e0;
+ y = ppuw - reg[WY] << 1 & 14;
cyc += 2;
m = 175 - reg[WX];
goto restart;
@@ -292,6 +292,8 @@
switch(ppustate){
case 0:
hblclock = clock + evhblank.time;
+ if(reg[WX] <= 166 && reg[WY] <= 143)
+ ppuw++;
if(++ppuy == 144){
ppustate = 1;
if((reg[STAT] & IRQM1) != 0)
@@ -310,8 +312,11 @@
break;
case 1:
hblclock = clock + evhblank.time;
+ if(reg[WX] <= 166 && reg[WY] <= 143)
+ ppuw++;
if(++ppuy == 154){
ppuy = 0;
+ ppuw = 0;
ppustate = 2;
if((reg[STAT] & IRQM2) != 0)
reg[IF] |= IRQLCDS;