make_patch.py applies the two-site fix to RIOv4_2.bin (asserting original
bytes first) -> RIOv4_2_patched.bin (23 bytes changed). Re-disassembling
and diffing confirms the change is confined to $D9DD, $DA21-$DA2E, and the
$DFF0 stub with no downstream desync. Clears the reply-in-progress latch
$2521 on every teardown so a stress collision no longer leaves the board
mute to analog. Flash directly to the DIP-28 W27C512; static verification
only -- dynamic RIO_TAP mash test pending the burned chip.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
68HC11 recursive-descent disassembler (disasm_6811.py, follows the
pointer-based RX/TX state dispatch) + full disassembly + analysis doc.
Root cause of the stress wedge: an orphaned reply-in-progress latch
($2521). It gates every analog request ($D758); it is set when a reply is
generated ($D84C) but the 4-retry give-up path ($D9DD -> $DA2F) tears down
reply state without clearing it, and the success teardown ($DA00) clears
it only conditionally on $2522. Once leaked, all analog requests are
dropped -> board mute, while RX/event stays alive; only the game-start
host-reset command ($C686) clears it -- matching the field button-resync
ritual exactly. Proposed minimal in-place fix (clear $2521 on every
teardown) documented with byte patches and a hardware validation plan;
untested pending a spare EPROM. RIOv4_2-ANALYSIS.md has the details.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
RIOv4_2.bin dumped from our own board EPROM (64KB, code $C000-$FFFF).
Vector table confirms 68HC11: RESET->$C000, SCI serial interrupt->$D630 =
the protocol state machine entry for the planned disassembly. Board patch
plan steps 1-2 done (RIO-NOTES.md updated); next: disassemble from the
SCI handler, find the reply-path wedge (button/event path survives it),
patch, burn to a fresh EPROM, preserve the original.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>