LCD-on → First WODU
The path from the CPU's LCD-enabling write to the first H-Blank has a measured end-to-end length. It depends on SCX and not on the instruction stream that precedes the write. This chapter walks that path stage by stage, then maps it onto CPU-observable timing (scanline and frame timing).
- The first WODU↑ lands 251.536 + (SCX & 7) dots after the
LCD-enabling write's
ff40_d7↑ (dmg-sim measurement; no sprites, no window). - The instruction stream between the write and the first WODU is irrelevant to the PPU cascade: both dot-of-M-cycle phases are CPU-prelude-invariant.
- The first-scanline Mode 2 measures ~78.5 dots from the write — the dot-0 reference shifted, not a Mode 2 shortening.
- The whole
SCX & 7shift lands in the startup pipeline; every other stage is SCX-invariant to picosecond precision (measured at SCX ∈ {0,1,2,3,7}). - At first-WODU phases 2.556 and 3.556 the dispatch slips one M-cycle, raising the handler-entry A by one (canonical prelude).
The end-to-end path
The stages below walk the full path from ff40_d7↑ (the LCD-enabling
write's effect) to the first H-Blank condition on the first scanline. All
figures are for SCX=0, no sprites, and no window (dmg-sim measurement):
| Stage | Δ from ff40_d7↑ (dots) |
|---|---|
| → XODO↓ (VID_RST deasserts) | +0.001 |
| → first XUPY↑ (scan counter starts) | +0.480 |
| → first AVAP↑ (Mode 2 → 3) | +78.491 |
| → first SACU↑ | +85.5 (= AVAP + 7.026) |
| → first WODU↑ | +251.536 (= AVAP + 173.045) |
Two dot-of-M-cycle invariants accompany that path. The write's ff40_d7↑
lands at +2.020 dots into its M-cycle (the CUPA position). The first
WODU↑ lands at +1.556 dots into its M-cycle. Both phases are
CPU-prelude-invariant: they are ps-identical across five LCD-on events in
three radically different instruction streams — quickboot's mid-boot
enable, a test ROM's own enable, and post-HALT interrupt-handler
enables. The instruction stream between the write
and the first WODU is therefore irrelevant to the PPU cascade.
The first-scanline Mode 2 measured from the write spans ~78.5 dots rather than 80. That short span is not a Mode 2 shortening. It is the dot-0 reference shifted by the write phase (+2.020) and divider startup (+0.480). Each subsequent Mode 2 is exactly 80 dots.
SCX extension (measured at SCX ∈ {0,1,2,3,7}): the entire +1-dot-per-
SCX&7 shift lands in the startup pipeline. Every other stage is
SCX-invariant to picosecond precision, across the same SCX set. The total is
251.536 + (SCX & 7) dots. That total gives a first-WODU M-cycle phase of
(1.556 + (SCX & 7)) mod 4.
Mapping to CPU observables
For the canonical LDH (LCDC),a; xor a; inc a; inc a; … prelude, walking
the wall-clock M-cells from the write pins everything. The write's M-cycle
and WODU's are separated by 63 CLK9 edges. That places the first WODU at dot
1.556 of cell M65, with inc#61 in flight. Handler-entry A is therefore 61,
matching the hardware-verified ROM expectation.
A walk that charges 4 dots per instruction after the write's M3 comes out 4 dots short. The cause: the cell after a memory write hosts the writer's internal M4 and the next instruction's fetch. That is the SM83 fetch overlap.
One further mechanism joins the in-flight instruction: a one-M-cycle
dispatch slip. The slip happens when the WODU-driven int_pending
settles past the dispatch-trigger setup boundary. That is at first-WODU
phases 2.556/3.556 (see interrupt dispatch).
Per SCX, the in-flight instruction and the dispatch slip combine into the
hardware-verified expectations:
| SCX | WODU M-cycle | phase | in-flight | slip | handler A |
|---|---|---|---|---|---|
| 0 | M65 | 1.556 | inc#61 | no | 61 |
| 1 | M65 | 2.556 | inc#61 | +1 | 62 |
| 2 | M65 | 3.556 | inc#61 | +1 | 62 |
| 3 | M66 | 0.556 | inc#62 | no | 62 |
| 4 | M66 | 1.556 | inc#62 | no | 62 |
| 5 | M66 | 2.556 | inc#62 | +1 | 63 |
| 6 | M66 | 3.556 | inc#62 | +1 | 63 |
| 7 | M67 | 0.556 | inc#63 | no | 63 |
Skip-boot note
The first-scanline shortening happens once, in the first frame after the boot ROM's LCD-on. By PC=0x0100, hundreds of frames later, it is baked into the machine's phase. Skip-boot emulators must adopt the post-boot state values jointly: LX=98 with the divider states as given. They must not synthesise a "pre-shortening" LX and re-apply the shortening at a boot-ROM LCD-on edge. That edge never happens on the skip-boot path.