LCD-on Power-up
The first scanline of the first frame after LCDC.7 goes high runs 454 dots instead of 456. This chapter covers that shortening, the startup transient at the LCD pins, and which PPU flip-flops are reset by what (scanline and frame timing).
- The first scanline after LCD-on runs 454 dots instead of 456, with the whole 2-dot deficit in Mode 0 (dmg-sim measurement).
- The shortening changes no pixels, but STAT mode reads, LY reads, and per-scanline interrupt timing all see it.
- The LCD-on write sets the divider phase for the whole epoch, and no per-line adjustment exists anywhere in the chain.
- VSYNC is silent for all of the first frame, because the first LY 153→0 wrap is the one ending that frame.
- The sprite store is empty on the first frame, so a Y-visible sprite with on-screen X that steady-state frames render is missed.
The first scanline: the 454-dot line
Immediately post-LCD-on, the first scanline measures 453.5 ≈ 454 dots instead of 456. The deficit falls entirely in Mode 0; Mode 2 and Mode 3 match steady-state. The gate-level decomposition (dmg-sim measurement):
| Component | First scanline | Steady-state | Diff |
|---|---|---|---|
| Line-start reference → first LX-incrementing TALU↑ | 2.021 (XODO↓ phase) + 1.483 (divider startup) = 3.504 | 6.000 (first TALU↑ lands inside the RUTU pulse and doesn't count) | −2.496 |
| 112 further LX increments | 448.000 | 448.000 | 0 |
| LX=113 → SANU → RUTU | ≈2.0 | ≈2.0 | ≈0 |
| Total | 453.500 | 456.000 | −2.5 ≈ −2 |
The structural sum lands at −2.5 while the directly-measured Mode-0 deficit (below) is exactly −2.0 dots (488,000 ps). That ~0.5-dot difference is sub-dot TALU phase, conserved through the LX chain and never realised as a whole-dot change in line length. The line therefore runs an integer 454 dots, and the Mode-0 deficit is exactly 2.
The deficit's location is measured directly (dmg-sim measurement). The first scanline's Mode 3 + Mode 0 span (XYMU↓ → RUTU↑) is 48,680,932 ps (199.512 dots). The same span on scanlines 1–5 is 49,168,932 ps (201.512 dots), so the first scanline is shorter by exactly 488,000 ps = 2 dots. The pure-Mode-0 interval (XYMU↑ → RUTU↑) shows the same 488,000 ps gap, which places the whole deficit in Mode 0.
Three structural facts compose the deficit — and none of them is "drift":
- No leading RUTU pulse. A steady-state line spends one TALU period inside the RUTU pulse, where LX is held at 0. The first scanline starts counting immediately. Skipping that pulse saves 6 dots against the reference.
- The LCD-on write lands in T3 of its M-cycle (the CUPA position, +2.020 dots). VID_RST deasserts a gate delay later, at XODO↓ (+2.021). The chain's first effect is therefore 2.021 dots late against the M-cycle boundary.
- The divider stack starts mid-phase. The first TALU↑ lands 1.483 dots after VID_RST deasserts, which is 3.504 dots past the M-cycle boundary. A steady line, by contrast, spends 6.000 dots reaching its first counting rise.
That phase is then conserved exactly. The write sets the divider phase for the whole epoch. Every TALU↑ thereafter lands 854,890 ps past its M-cycle boundary with zero variance (155,000+ edges, dmg-sim measurement). The 854,890 ps figure covers all 113 rises on the first scanline and every steady-state rise after. No per-line adjustment exists anywhere in the chain. The LX chain is a delay-conserving propagator, not an amplifier.
Reproduce the three structural inputs (write phase, divider phase, no leading RUTU pulse) and let the trajectory fall out. Patching the LX==113 detector misframes a mechanism that contains no scanline-specific gating.
The LCD-on startup transient at the pins
| Pin | Pre-LCD-on | First edge after LCD-on | Cadence |
|---|---|---|---|
s (VSYNC) | static 0 | +17.1 ms — the LY 153→0 boundary ending the first frame | once per frame |
st (HSYNC) | static 0 | +19.2 µs (first-scanline Mode 3) | per scanline |
cp | static 0 | +20.7 µs | half-dot period during Mode 3 |
cpg | static 0 | +6.7 µs | per scanline |
cpl / fr | alternating at ~8/~4 kHz (audio mux) | seamless | per scanline |
ld0 / ld1 | static 0 | first Mode 3 pixel | pixel rate |
Seven of eight pins are normal from the first scanline. VSYNC is silent for all of the first frame. The cause: MEDA can only capture the LY=0 decode at an LY 153→0 wrap. The first such wrap is the one ending the first frame. From the second frame on, VSYNC fires once per frame. The first frame is distinguished by the absence of a pulse, not an altered one.
The community-documented consequence is that the first frame never reaches the glass ("first frame is blank"). That claim rests on pin-role references for the LCD's Y-driver, not on a measured glass-side behaviour. The PPU-side mechanism (MEDA's reset domain) is netlist-derived and measured. The 2-dot first-scanline shortening changes no pixels; it only moves where the mode and LY transitions fall. The shortening therefore has no display consequence. It is still fully observable to the CPU: STAT mode reads, LY reads, and per-scanline interrupt timing all see it.
VBlank IF is not gated by the first frame. The IF[0] latch (LOPE) has no LCD-off reset path, and POPU resumes normally after LCD-on. The first frame's VBlank entry raises IF[0] with the same edge structure as any steady-state frame (dmg-sim measurement). No first-frame interrupt suppression of any kind exists.
Pipeline state at LCD-on: the reset-domain taxonomy
Every PPU DFF belongs to one of five reset classes, and the whole cross-frame story follows from the classification:
| Class | Reset condition | Members | Behaviour |
|---|---|---|---|
| Direct LCD-off | ppu_reset_n / ppu_reset2_n | dividers WUVU/VENA/WOSU; RUTU, NYPE, POPU, MYTA, MEDA; NOPA | Held at 0 while LCDC.7=0; released at the VID_RST edge |
| Indirect LCD-off | combinational nets containing VID_RST terms | LX, LY, PX, VOGA, scan counter, fine-scroll counter, BG fetch counter, AVAP generator, sprite fetch counter, sprite store | Held at 0 during LCD-off; reset at their per-scanline/per-tile boundaries during rendering |
| Mode-3-only | the mode3 net | LYZU, PUXA, NYZE, PYGO, RENE, RYFA, PAHO, SEBA, TOBU, VONU | Zero at every Mode 3 entry, on every scanline, every frame — identical by construction |
| No-reset persistence | tied-high r_n or data-driven set/reset only | BG + sprite shift registers (32 cells), tile temp latches, SOBU/SUDA/TYFO, XYMU, ROXY | Hold state indefinitely across LCD-off |
| CPU-register | CPU-write/system-reset only | LCDC, SCX/SCY, WX/WY, palettes, LYC, STAT enables, ROPO | Survive LCDC.7 toggles; palettes have no reset at all (power-on state undefined on silicon) |
What matters is whether any persisted stale state reaches LD0/LD1. For the BG plane, no. The two-parallel-loads mechanism (BG pipeline) propagates stale content at load #1 (AVAP) and overwrites it at load #2 (first TEVO, dot 5.996). That overwrite lands before the first CLKPIPE shift at 7.026. CP is PX≥9-gated besides. For the sprite plane, stale shifter content is mux-gated until a real fetch fires. That leaves exactly two pieces of cross-frame state to examine at the first scanline. Only the first reaches LD0/LD1:
-
The sprite store is empty on the first frame. The LCD-on bypass never sets BESU, CARE never arms, and
oam_data_latchnever pulses (mode transitions). Consequences by OAM content:Case OAM at LY=0 Divergence on LD0/LD1? 1 no Y-visible sprite none — both frames render spriteless 2 Y-visible sprite, on-screen X yes — the first frame misses the sprite; steady-state frames render it 3 Y-visible sprite at OAM X=0 timing only — see below Case 1. Anchored across 777 Y-non-matching scanlines (zero TEKY/FEPO, zero variance) and 842 scanlines of DMA overlap across all three regimes. The anchor shows that DMA cannot convert an empty-store line into an extended one.
Case 3. A steady-state frame's save-written X=0 fires the X match and its fetch penalty. The first frame's reset-held store cannot fire: the store holds NOT(X), and reset decodes as X = 0xFF (sprite pipeline).
-
The window's REJO latch. REPU clears it on every VBlank entry (window control), so the latch carries nothing across frames. No divergence comes from this path.
Everything else lands outside the pixel path or is overwritten before it can be sampled. MEDA's silent first-frame VSYNC lands outside the pixel path. So does BESU's missing Mode 2 status/IRQ on the first scanline of the first frame.
One cold-boot footnote: ROPO (the LYC-match capture) resets only at system reset. STAT bit 2 therefore exposes the pre-LCD-off match value briefly, between LCD-on and the first TALU edge. On the very first boot, that value is the power-on zero.