Correct 04000000 finding: CheckRequest self-test leftover, not test mode

Bench refutation (display is static under axis movement; version-only
exchanges leave it alone) kills the A-9-E chord theory. Real mechanism:
the CheckRequest handler at $C5A6 runs a full self-test — sets the
test-display flag $2421, brackets itself with TestModeChange 0x8C,
lamp pattern, pod scan, five-channel encoder sweep — and returns
without repainting, leaving the channel-4 frame (04000000) as a stale
cosmetic snapshot. Board fully healthy; no reset needed. PROTOCOL.md
now warns hosts that 0x8C fires around every check. Candidate firmware
fix (repaint cave off $C5E4) noted for a future burn.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Cyd
2026-07-19 16:04:11 -05:00
co-authored by Claude Fable 5
parent ea6199d516
commit 6e22e2fdbc
+18 -3
View File
@@ -55,9 +55,10 @@ J1 (14-pin, from the RIO's EXTERNAL DISPLAY port) is all input:
## What the RIO firmware displays (v4.2) ## What the RIO firmware displays (v4.2)
All display writes go through `$CB49` (buffer render) or five canned All display writes go through `$CB49` (buffer render) or five canned
patterns at `$CB7C$CC52`, driven from three contexts: initialization, patterns at `$CB7C$CC52`, driven from four contexts: initialization,
the built-in **test mode**, and the **serial error/crash displays** the built-in **test mode**, the **serial error/crash displays**, and
(below). During normal, healthy gameplay the display is static. the **CheckRequest self-test** (all below). During normal, healthy
gameplay the display is static.
**Normal operation:** `F0000000` — written at cold boot (`$C068`) and warm **Normal operation:** `F0000000` — written at cold boot (`$C068`) and warm
re-init (`$C64B`), then left alone. re-init (`$C64B`), then left alone.
@@ -92,6 +93,20 @@ In the axis tests `hhll` is the **live 16-bit quadrature count in hex**
and watch the number move. The channel IDs are literally the keypad keys and watch the number move. The channel IDs are literally the keypad keys
that start them, which is why the fourth axis reads `0C`. that start them, which is why the fourth axis reads `0C`.
## The CheckRequest self-test leftover: `04000000`
The host `CheckRequest` (`0x80`) triggers a full self-test in the
handler at `$C5A6`: it sets the same display flag test mode uses
(`$2421`), brackets itself with `TestModeChange 0x8C` notifications,
flashes a lamp pattern, scans the pods, and sweeps the five encoder
channels — rendering each channel's `cc00hhll` frame as it goes. It
clears the flag on exit but **never repaints the display**, so after
every status check the digits are left showing the last frame:
channel 4, usually `04000000` with idle encoders. It is a stale
snapshot (axis movement does not update it — bench-confirmed
2026-07-19), purely cosmetic, and the board keeps operating normally.
Any reset repaints `F0000000`.
## Error displays (the third use) ## Error displays (the third use)
Two more display writers live in the serial machinery — the display is Two more display writers live in the serial machinery — the display is