Plain-language explanation of the reply-latch wedge for non-technical pod owners, linked from the firmware README top. Frames the bug as a 'busy' sticky note the board forgets to take down on the give-up path, and how RIO 4.3 fixes it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
5.2 KiB
RIO board firmware
Pod owner, not an engineer? Read wedge-explained.md — a plain-language account of the "stick died mid-battle" bug that RIO 4.3 fixes.
RIOv4_2.bin— RIO cockpit I/O board firmware v4.2, dumped 2026-07-04 from one of our own boards' EPROM: an AMD AM27C512-150 (64K x 8 UV EPROM, 150ns — the image fills it exactly). sha25660a88718835c654b6135dbec7721c40ef99dca07df2ad4b57eedeb24037a5f73. For the eventual patched burn: a pin-compatible Winbond W27C512 (electrically erasable, TL866-friendly) drops straight into the socket; the original AMD chip gets labeled and preserved unmodified.
First-look analysis (from the image alone, confirmed on hardware)
- MCU: Toshiba TMP68HC11 (read off the chip; the code fingerprint
agrees — 6800-family opcodes with writes into the 68HC11 internal
register block at
$10xx). - Memory map: image is FF up to 0xC000; 16KB of code occupies
$C000-$FFFF(EPROM mapped at the top of the HC11 address space). - Startup at
$C000:SEI; LDS #$8000; STAA $1024 (TMSK2); STAA $1022 (TMSK1); ...then a longJSRinit chain — textbook HC11 bring-up. - Vector table (
$FFD6-$FFFF, big-endian):$FFFERESET →$C000$FFD6SCI (serial) →$D630— the entry point of the board's receive/protocol interrupt handler. The suspected board-side DISABLE_AND_DIE-style wedge (see RIO-NOTES.md: the board mirrors the game's PCSPAK state machine, and mash-stress leaves the reply path dead while the button/event path stays alive) is reachable from here.$FFE4→$C1B2,$FFE6→$C18E(timer output-compares); most other vectors →$DB07..$DB3Dstubs.
Why this exists
The remaining RIO reliability issue is board-side: under button-mash
stress the board's reply/analog state machine wedges (RX dead, TX alive;
a button press or power cycle revives it), reproduced identically on two
different USB serial adapters. The game-side half of the protocol was
binary-patched for tolerance (BTL4OPT patches v2-v4); the board firmware
is the other half. Plan (RIO-NOTES.md "Board firmware patch plan"):
disassemble as 68HC11 from $C000 with the vector entries as roots, find
the SCI state machine (protocol constants FC=ACK FD=NAK FE=RESTART
FF=IDLE, idle-reload-4 patterns), patch the early-ACK/error wedge path or
widen its window, burn a new EPROM, keep this original safe.
RIO 4.3 — RIOv4_3.bin (current production firmware)
Christened 2026-07-19 after full on-hardware certification. Built
by make_patch.py --e0thresh=5 --checkrepaint --reportversion=4.3 RIOv4_2.bin RIOv4_3.bin; sha256
6d67a2fc77130b601fdb0ac02042dd4d0a98ac7e29a8077d588987a81073939c
(69 bytes changed vs stock). 9600 baud, native-game compatible. On the
stock v4.2 base it carries:
- Reply-latch wedge fix (edits 1-2) — bench-certified.
- E0-display threshold, N=5 (edit 5) — certified: display holds
F0000000through sub-threshold error events, flips to the liveE0readout at the 5th teardown (E0000105on the bench). - Check self-test display repaint (edit 6) — certified both ways:
version+check leaves
F0000000when healthy, and re-renders the E0 readout when counters are over threshold (E0000305on the bench) instead of stock's stale04000000. - Version bump (edit 7,
--reportversion=4.3) — the VersionReply now announces 4.3 (one operand byte at$C6FF). Nothing host-side validates the value (native games verified not to check it). The certification runs below were made on the pre-edit-7 bytes; the only delta is the version literal. Chips burned before this edit report 4.2 — re-burn to announce 4.3.
Certification runs (all in testlogs/ + RIOv4_2-ANALYSIS.md): two
--e0test acceptance passes (display verified by eye at each step) and
a 120 s mash at 549 presses/min sustained — zero wedges, board
counters flat, zero NAK, 247 resends all healed
(riomash-rio43rc1-9600-20260719-164901.log).
FastRIO 4.3 — RIOv4_3_fastrio.bin
Same generation for the RIOJoy-only cockpits: make_patch.py --baud31250 --widen-ackwait --e0thresh=5 --checkrepaint --reportversion=4.3 RIOv4_2.bin RIOv4_3_fastrio.bin; sha256
ee807831fe0df9dc147eb5cdc3302672ae21f6ff349da30babea27fc863234b9
(71 bytes vs stock — differs from RIOv4_3.bin in exactly two bytes:
$D62B baud 30→02 and $D9E7 ACK-wait 04→28). 31250 baud,
FTDI-class adapter required, not native-game compatible.
Disassembly-verified; run the acceptance ladder on the FastRIO cockpit
before deploying (--e0test COM1 auto-probes 31250, then a mash
spot-check at --baud 31250).
Archive
All prior generations live in archive/ with their
disassemblies: RIOv4_2_patched (wedge fix only), _31250/_31250v2
(FastRIO speed builds), _62500/_125000 (speed-ladder science runs),
and the _e0t5 pair (threshold without check-repaint). Bench verdicts
and per-edit history: RIOv4_2-ANALYSIS.md. The pristine dump
RIOv4_2.bin stays at top level — it is the source every patch builds
from. RIO 4.3 is in the cockpit socket as of 2026-07-19; the original
AMD chip and the retired e0t5 burn are labeled and preserved.