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`.