From 83fcb198c8d03c31b2d2216d4be914e574909620 Mon Sep 17 00:00:00 2001 From: Cyd Date: Sun, 19 Jul 2026 14:47:01 -0500 Subject: [PATCH] Error-handling inventory: E0 diagnostics, dEAd crash screen, no watchdog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The display has a third use: serial error annunciator. $D5F2 renders 'E0' + three live counters (TX-ring overflow $3187, reply retries $3184, give-up teardowns $3185); $DAB8/$DAB2 is a terminal crash screen spelling 'dEAd' when the TX dispatcher meets an unknown command byte. Also recorded: RX overrun is unhandled (checksum NAKs are the only symptom), unused vectors hang in BRA-self stubs, FAULT LED = MAX690 PFO, manual/remote reset works by pulling PFI low, RUN LED = buffered AS*, and the MAX690 watchdog is unconnected/unserviced — software wedges persist until reset, matching bench observations. Co-Authored-By: Claude Fable 5 --- RIOv4_2-ANALYSIS.md | 54 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/RIOv4_2-ANALYSIS.md b/RIOv4_2-ANALYSIS.md index e10c62c0..24817407 100644 --- a/RIOv4_2-ANALYSIS.md +++ b/RIOv4_2-ANALYSIS.md @@ -405,3 +405,57 @@ stop-and-wait delivery is always on (near-zero cost on clean links). Firmware images, hashes, disassemblies, the mechanized mash harness, and all eleven bench logs live in this directory. The original AMD chip is retired, preserved unmodified. + +## Error-handling inventory (v4.2, unpatched baseline) + +Complete map of what the board does — and pointedly does not do — when +things go wrong. Complements the wedge analysis above; display-side +detail in [`docs/hardware/display-board-1408.md`](../docs/hardware/display-board-1408.md). + +### Host-facing (protocol) + +- **Inbound packet checksum** (7-bit sum, verified at the `$D81F` + decision): good packet → queue **ACK `$FC`** (`$316F`); bad → **NAK + `$FD`** (`$3170`). The TX ISR sends pending ACK/NAK ahead of reply + data (`$D8A6`). Control bytes `$FE` RESTART / `$FF` IDLE. +- **Outbound reply delivery**: replies must be ACKed by the game; the + retry machine (`$D90E`/`$D9BE`) retransmits up to 4 times + (`INC $3184` per retry), then gives up — sends `$FE` RESTART, + `INC $317A`, teardown at `$DA2F` (`INC $3185`). The give-up teardown + is where the `$2521` wedge leak lives (see above; fixed in the patched + images). +- **RX overrun: unhandled.** The RX ISR reads SCSR/SCDR but never acts + on the overrun flag — dropped bytes just corrupt the frame and + surface as checksum NAKs. This is why the 125000-baud bench run + produced NAK=1082 rather than any explicit overrun signal. + +### Internal + +- **TX-ring overflow** (`$D63B` enqueue): if the ring would overtake + the drain pointer, the byte is silently dropped, `INC $3187`, and the + E0 diagnostic display refreshes. The host is not told. +- **TX dispatcher sanity trap** (`$D8C2`): each outgoing command byte + is looked up in an 8-entry table at `$3158`; no match ⇒ internal + corruption ⇒ `JMP $DAB2` — the **`dEAd` crash screen**, an infinite + loop rendering `dEAd` + RAM `$0000/$0001` on the 8-digit display. + Permanent until reset. +- **Unused interrupt vectors** → `NOP; BRA self` stubs at + `$DB07-$DB3D`: silent hang, no display, no recovery. +- **Error counters** `$3173-$317B` (ACK/NAK/retry/give-up bookkeeping) + and the three displayed ones `$3187/$3184/$3185` — rendered as + `E0 ` by `$D5F2` at every increment. + +### Hardware (RIO_1407 sheet 2) + +- **MAX690 supervisor**: power-on/brownout reset via the PFI + comparator. The front-panel RESET toggle (SW1) and the optocoupled + remote-reset input both work by pulling PFI low — a "commanded + power-fail". **FAULT LED = PFO**, so it lights during any such event. +- **No working watchdog.** WDI has no off-sheet tag (never reaches the + CPU) and the firmware contains no strobe code — so software hangs + (`dEAd`, vector stubs, the reply wedge) persist until a human or the + game PC resets the board. This is corroborating evidence for the + bench-observed behavior: a wedged board stays wedged indefinitely. +- **RUN LED = buffered `AS*`** (address strobe): it indicates "clock + alive", not "software alive" — it stays lit even inside the `dEAd` + loop. TX/RX LEDs are buffered `SER_OUT`/`SER_IN`.