Gekkio / mooneye-test-suite

Mooneye Test Suite is a suite of Game Boy test ROMs
MIT License
92 stars 9 forks source link

mgb_oam_dma_halt_sprites is potentially unit and revision specific #1

Open LIJI32 opened 2 years ago

LIJI32 commented 2 years ago

Running the test on some of my devices, I'm getting:

  1. DMG-B, blob – I'm getting the MGB expected result (Test source expects a different sprite on a DMG)
  2. MGB (Specifically, Game Boy Light) – I'm getting no sprite at all
  3. CGB-0, A, B, C and D (tested one of each) – No sprite at all
  4. CGB-E, AGB, AGS-001 and AGS-101 – I'm getting the attached image.

Haven't tested on my SGB2 yet.

image

LIJI32 commented 2 years ago

(I updated the image I posted a few times, I didn't create it properly)

The CGB-E+ behavior is as if OAM bytes 2 and 3 haven't been modified at all yet so the "new" bytes have no effect.

It seems that DMA does not prevent mode 2 from accessing OAM if the CPU is in halt mode, but other than that, DMA during halt on these revisions behaves "as expected" from DMA during LCD on (The address the PPU reads is the address DMA writes to, except for bit 0 since OAM is built of "even/Y and tile" and "odd/X and flags" memory components)

LIJI32 commented 2 years ago

I believe I figured the behavior of this test out. First of all, the test halts during the DMA write to FE02 (The new value isn't written yet). As noted before, when the PPU reads OAM in this case, it uses the DMA destination address (except for bit 0). On the CGB-E and later it indeed just reads the unmodified values. (I believe CGB-0 to D just block the PPU from accessing OAM during Mode 2 if DMA is active)

Pre-CGB models behave the same, with one exception – they trigger an OAM corruption! Due to PHI being stopped, the WR signal to OAM is being held, so the entire ROM is doing one huge continuous write to FE02, which triggers the OAM corruption bug. This explains why bytes FE04 to FE08 have an effect, and why this ROM is unit specific – some OAM corruption patterns are indeed unit specific, and this is most likely a unique pattern anyway. The reason your MGB and my DMG are reading 38 and 5A is because these values are actually at OAM at that moment.

Sadly I don't think it'll be possible to make a non-visual test of this corruption, as by the time DMA ends, it will have overwritten every corrupted byte with new, valid data.