LY and STAT are actually fairly consistent at startup on SGB and GBC
- Dominant language
- Markdown
- Stars
- 783
- Forks
- 134
- Avg merge
- 6h 54m
- Merged PRs (30d)
- 3
Description
In the hardware registers section of power-up sequence, the values for `DIV`, `LY` and `STAT` are given as `??`, citing their dependence on header values and user input. While this is definitely true for `DIV` on GBC in compatibility mode, this is in broad strokes not true for `LY` and `STAT`.
On SGB, the last thing that happens before the game boots is a 4 frame wait, based on VBlank. Each frame wait is implemented as waiting for `LY==$90` followed by a busy wait. The variance should really just be a few cycles of jitter from when exactly the VBlank wait starts. (So something like a variation of 5 M cycles.) I believe the following will always be true on SGB, although someone could try to calculate the limit cases and prove it wrong:
```
DIV==$D8
LY==$00
STAT==$85
```
On GBC, the last thing that happens is tied to a VBlank wait, some copies to VRAM, and optionally setting up compatibility mode. I think we can declare `DIV` generally undecidable, especially in comaptibility mode. However, in GBC mode it seems like the code path is fully consistent with no dependence on the header. One code path per boot ROM revision, at least. This gives `DIV==$20` for CGB0 and `DIV==$1E` for CGB and AGB-CGB. If I'm missing a case where the code path would diverge in GBC mode, please remind me.
What we I think can say for sure is that while `LY` might vary slightly, say within `$90-94` it will be firmly within VBlank at the hand-over in all cases. This would in turn imply `STAT==$81`. Again, feel free to disprove this.
A few final notes: It is nevertheless sound advice to discourage relying on initial values. I remember a recent case where some game didn't work with with SameBoot because it didn't honor the assumption that GBC at least guarantees hand-off *somewhere* inside VBlank. Likewise, the initial value of `DIV` is kind of pointless, since practical use of `DIV` for RNG relies on the timing of the lower bits of the counter as well. For example, even though `DIV==$1E` for both CGB and AGB-CGB as per above, there's a 1 M cycle difference between the two, which can create an avalanche effect in a RNG.
Contributor guide
Research direction
Start in the hardware registers section of the power-up sequence and trace the SGB and GBC hand-over paths, including the four-frame VBlank wait and compatibility-mode branches. Validate the proposed DIV, LY, and STAT values across the listed boot ROM revisions and edge cases. Done means documenting only values that are demonstrably consistent, while retaining caveats about timing and unreliable initial values.
Written by the indexing model from the issue text.
Assessment
- Domain
- documentation, embedded-iot
- Issue type
- Documentation
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100