shithub: riscv

Download patch

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;