Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add test for STAT write bug with LCD off #13

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions ppu/stat_lcd_off.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
RESULTS_START EQU $c000
RESULTS_N_ROWS EQU 1

include "base.inc"

CorrectResults:
; The first byte is $E0 on CGB, since there is no STAT write bug there
db $E2, $E0, $00, $E0, $E0, $E0, $E0, $00

RunTest:
; Disable all interrupts
di
xor a
ldh [rIE], a
call LCDOn

; Wait for the first scanline of VBlank, to have more reliable PPU timing
.waitVBlank
ldh a, [rLY]
cp $90
jr nz, .waitVBlank

; Clear any pending interrupts
xor a
ldh [rIF], a
; Request STAT to only occur on Mode 0
ld a, STATF_MODE00
ldh [rSTAT], a
; On DMG, this requests the interrupt due to the STAT write glitch
; (This is only part of the test's results as a sanity check)
ldh a, [rIF]
ld [RESULTS_START], a

; We must be in Mode 1 at this point, and turning the LCD off has STAT report Mode 0
; But does that actually request a Mode 0 interrupt?
xor a
ldh [rIF], a
call LCDOff
ldh a, [rIF]
ld [RESULTS_START + 1], a

; While we're at this, check which scanline LY reports
ldh a, [rLY]
ld [RESULTS_START + 2], a
inc a
ldh [rLYC], a ; Ensure LYC doesn't match it

; Now, if we write to STAT, is the STAT write bug triggered?
xor a
ldh [rIF], a
ld a, STATF_LYC
ldh [rSTAT], a
ldh a, [rIF]
ld [RESULTS_START + 3], a

; The only condition active is LYC, which we ensured is not fulfilled;
; fulfill it, and see if the STAT interrupt is triggered
xor a
ldh [rIF], a
ld a, [RESULTS_START + 2] ; Get back the value written earlier, in case LY changed fsr
ldh [rLYC], a
ldh a, [rIF]
ld [RESULTS_START + 4], a

; What if we request Mode 1?
xor a
ldh [rIF], a
ld a, STATF_MODE01
ldh [rSTAT], a
ldh a, [rIF]
ld [RESULTS_START + 5], a

; Screw it, request everything! (The Xmas test of STAT write glitch...)
xor a
ldh [rIF], a
ld a, $FF
ldh [rSTAT], a
ldh a, [rIF]
ld [RESULTS_START + 6], a

; LY shouldn't change, and we need to pad the remaining byte somehow, so read it as
; a sanity check
ldh a, [rLY]
ld [RESULTS_START + 7], a
ret