Page 1 of 1

The first frame is always white (test ROM)

Posted: Sat Nov 10, 2018 9:55 pm
by tepples
When the program turns on rendering by changing bit 7 of LCDC ($FF40) from 0 to 1, the PPU goes straight to the start of rendering (scanline 0). And for some reason, the LCD does not receive the first frame that the PPU generates, instead displaying a white screen for one frame. (On monochrome systems, this is the same whiter-than-white shade displayed when rendering is off.) Some games, such as Pokémon Pinball, use this blank frame to prepare things before the first visible frame, such as the sprite display list to be DMA copied to OAM during the first vblank.

Though recent BGB emulates this quirk, mGBA 0.8-5388-f92059be does not. This causes 1 frame of corruption to appear in Pokémon Pinball and numerous other games after a screen transition. Many games on KiGB's compatibility list are there because of this quirk.

So I've made a test ROM for this quirk. Expect a whiter-than-white screen on an authentic Game Boy or Game Boy Pocket, or a white screen on an authentic Game Boy Color, Game Boy Advance, or Game Boy Player. (I haven't tested it on my cousin's Super Game Boy yet.) On an emulator that does not emulate this quirk, it will instead speak truth.

Re: The first frame is always white (test ROM)

Posted: Sat Dec 29, 2018 3:39 pm
by tepples
Version 0.02 features a less cheeky failure message.

Re: The first frame is always white (test ROM)

Posted: Sun Dec 30, 2018 3:33 am
by nocash
Thinking about it... the combination of first+white in the filename sounds much more concerning... initiallyblankscreen or missingblackgraypixels would avoid possible associations with racism... though nintendo apparently didn't care about that either when inventing their hardware design with enforced whiteness - their backlight driven handhelds would look much nicer if they would default to black screens, or allow to use custom a backdrop color during forced blank.

Re: The first frame is always white (test ROM)

Posted: Fri Jan 04, 2019 6:37 pm
by ISSOtm
Quick note about this on SGB: the SGB appears to lose VSync when rapidly turning the LCD on and off, which causes the picture to scroll.

Testing during development of my homebrew game also led to the conclusion that disabling the LCD on SGB simply causes the picture to stop updating, as evidenced by a lack of blinking during screen transitions. There's probably investigation to be made regarding the ICD2 chip.

Re: The first frame is always white (test ROM)

Posted: Sun Jan 13, 2019 9:51 am
by Near
Oooh, a very interesting test case. I wonder how higan emulates this in SGB mode.

It was very difficult to reverse engineer the ICD2 from scratch, and it's always felt incredibly hacky how to detect where to transfer uploaded Game Boy screen chunks to, based on the writes the SGB sends to the ICD2. Somehow it ended up stable enough to work with border uploads, game uploads, and even the weird >100% speed mode that causes skipped frames on a real SGB.

But I have a feeling this is going to push it even more, and not run correctly.

Re: The first frame is always white (test ROM)

Posted: Sun Jan 13, 2019 10:59 am
by ISSOtm
Higan doesn't emulate this correctly, according to this game I'm developing. Soft-resetting it causes it to enter a boot-loop until the key combo is released, and this triggers the same behavior tepple's ROM tests (turn the LCD off after that first frame).

Higan first shows a glitched frame (like, wrong tiles loaded? I can't tell exactly what's going on due to lacking a debugger) then a solid blank frame; this is roughly the same as BGB, which emulates the "white first frame" even on SGB.
On my SGB1, a garbled picture scrolls indefinitely (though the bottom tile line seems to behave differently?). This garbled picture appears to differ based on what's loaded in VRAM prior to resetting, though that might be a consequence of how my ROM works, I'm not sure.

Re: The first frame is always white (test ROM)

Posted: Wed Feb 13, 2019 7:06 pm
by ISSOtm
gekkio recently figured out the exact behavior behind the "blank frame": when turning the PPU/LCD on, no VSync signal is generated. The LCD screens respond by doing absolutely nothing, but the ICD2 works differently.

Liji created two test ROMs, which turn the PPU off at specific LY values1. Notably, no VSync signal is sent ever.
Turning the PPU off so it generates 64 scanlines before aborting the frame creates a stable2 picture.
Generating one less line before aborting causes the picture to instead scroll upwards by 1 pixel each frame.
Liji also noticed that turning the LCD off on the first VBlank after turning it off causes the picture to shift upwards by 112 pixels. If you're savvy, you will have noticed that 112 + 144 = 256. Hmm...

To explain the current theory we believe in, I will start by quoting a bit of fullsnes:
SGB Port 6000h - LCD Character Row and Buffer Write-Row (R)

7-3 Current Character Row on Gameboy LCD (0..11h) (11h=Last Row, or Vblank)
2 Seems to be always zero
1-0 Current Character Row WRITE Buffer Number (0..3)
The ICD2 appears to track the Game Boy's LY value (divided by 8). How can it, since it only has access to LCD lines? The theory is simply that the ICD2 has a counter that gets incremented each time 8 scanlines are recieved (= each time a new character row is pushed to one of the four buffers), and reset when it recieves a VSync signal.
When turning the LCD off then on again, the VSync signal is never recieved, so the counter simply increases without resetting. It's then assumed that the SGB firmware simply ignores those rows, which explains why 122 lines are dropped when full frames are generated without VSync.
That last part has been confirmed, as the following is present in the firmware:

Code: Select all

.80:B9BE                 LDA     ICD2CURROW
.80:B9C2                 STA     CurLYAndBufNum ; orig=0x0290
.80:B9C5                 LDA     ICD2CURROW
.80:B9C9                 CMP     CurLYAndBufNum ; orig=0x0290
.80:B9CC                 BNE     ReadCHRRows
.80:B9CE                 CMP     #$11 << 3
.80:B9D0                 BCS     locret_80BA0C
The rest of this theory should be somewhat easily verifiable by checking if the "GB row number" in $6000 indeed goes past 0x11. I have in mind to upload code to the SNES that would enabled forced blanking as soon as a row number greater than 0x11 is read, but I haven't got time to write it yet.

Does higan emulate this correctly? Apparently, no.

1 This means the PPU is turned off mid-frame repeatedly, which Nintendo's programming manual refers to as "strictly forbidden". It's therefore strongly discouraged to run those on a DMG/MGB; CGB and later should be fine according to the same document.
2 The picture flickers and is somewhat inconsistent on SGB1, but I'm tempted to blame the different clock rates on both sides of the ICD2.

Re: The first frame is always white (test ROM)

Posted: Fri Feb 22, 2019 3:34 pm
by Near
Exceelent work in figuring this out. I would love to commit a patch for this if anyone had some free time.

Unfortunately I am absolutely swamped at the moment, so if you need me to get to this, it'll probably be a while ...