pinobatch / numism

I'm at the platform game, I'm at the emulator test, I'm at the combination platform game and emulator test
Apache License 2.0
16 stars 1 forks source link

GB: Test 16-bit reads from $3FFF #1

Open pinobatch opened 3 years ago

pinobatch commented 3 years ago

Lycoder, developer of GB emulator Geebly, suspected that some emulators might have trouble with 16-bit reads across the MBC breakpoint. The case we identified was a stack copy from $3FFF:

ld sp, $3FFF
pop de

calc84maniac, developer of TI-Boy CE, reminded the channel to test with multiple MBC banks. I generalized to these:

Now:

After the ROM exceeds 32 KiB and MBC is added:

After Game Boy Color is added:

As usual, if everything passes including "usual culprits"-tier emulators (VBA, Goomba, no$gmb, KiGB, and rew.), don't make it a coin. It may be wise to make an exerciser first if possible.

pinobatch commented 3 years ago

@ISSOtm suggested testing execution across bank boundary by ending bank 0 with C4 20 once MBC is in place, and setting the first byte of the next bank so as to jump into WRAM.

After I thought about it, I ended up with this sketch of a test rig:

3F81: 3E 10      ld a, 16
3F83: C9         ret
3F84: 3E 11      ld a, 17
3F86: C9         ret
3F87: 3E 12      ld a, 18
3F89: C9         ret
3F8A: 3E 12      ld a, 19
3F8C: C9         ret
[...]
3FFE: C4 20 83   call nz, $8320
3FFF: 20 83      jr nz, $3F84
4001: 3E 01      ld a, 1
4003: C9         ret

Each combination of (call or jr, ZF set or clear, and bank 0, 1, 2, and 3) would be tested. This requires hardcoding something starting at $3F81 and $3FFE in ROM0, as well as the first 4 bytes of each bank (including rst $00) and the last byte of each ROMX bank (try 20 28 30 38?). The call nz targets jump into RAM so that the test can set up temporary trampolines at $8020, $8320, $8620, and $8920 (to the effect ld b, constant ret) when testing that the jump is taken. VRAM is chosen so as not to overlap state in WRAM.