Files
psxrecomp/tools/trace_range.py
Matthew Stanley 8b0fc34714 phase4: SELECT-deassert protocol reset + slot-state instrumentation
Real card protocol restarts on every fresh 0x81 — SELECT deassert is
a bus-wide reset signal. Earlier model preserved mc_state across
deassert via mc_save_slot, which caused every subsequent 0x81 to land
on a stale non-IDLE saved state and trigger abort_reselect bookkeeping.
Audit confirmed the BIOS-visible RX was still correct (the abort path
itself reset mc_state), but the retained sector/cmd/counter context
across logically-independent transactions was wrong per no$psx.

Clear volatile protocol state on SELECT deassert (state, cmd, sector,
sector_msb, sector_lsb, data_idx, checksum on both slots). Preserve
mc_slots[].flag (persistent "new card" metadata) and mc_slots[].data
(sector buffer, harmless to retain).

Result on a 4-press boot run: 6 transactions reach READ_DATA (ts=10)
and successfully read the "MC" header magic (RX bytes 0x4D 0x43);
remaining txns continue as 4-byte presence pings. Pre-fix: 0 reads
of card data ever; post-fix: card protocol can complete the setup
phase and enter data phase.

The byte-15 abort that follows is a separate blocker — kernel chain
dispatcher interleaves pad polling into the card data read. Tracked
for next session via the chain dispatcher disassembly.

Also includes:
- Slot-state capture in SioTraceEntry + sio_trace JSON emission
- dirty_ram_interp: replace mid-block fprintf+fflush with a counter
  (CLAUDE.md §3 — synchronous Windows console I/O at high rate
  starves the dispatch loop)
- Passive Python TCP probes (raw_tcp, trace_audit, trace_range,
  txn_summary, txn_dist, txn_bytes, drs_filter, readram_test,
  step_audit{,2}, verify_card_buffer, wtrace_filter)
- docs/MEMCARD_AUDIT_2026_04_28.md (prior session's 7-layer audit)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 14:46:26 -07:00

24 lines
951 B
Python

"""Filter SIO trace to entries with seq in [smin, smax]. Args: smin smax."""
import sys, json, re
if len(sys.argv) != 3:
print('usage: trace_range.py SMIN SMAX', file=sys.stderr); sys.exit(1)
smin, smax = int(sys.argv[1]), int(sys.argv[2])
txt = sys.stdin.read()
m = re.search(r'\{.*\}', txt, re.S)
if not m:
print('parse fail'); sys.exit(1)
j = json.loads(m.group(0))
ents = j.get('entries', [])
hits = [e for e in ents if smin <= e['seq'] <= smax]
print(f'(found {len(hits)} of {len(ents)} entries in [{smin},{smax}], total seq up to {j.get("total")})')
print('seq tx rx mc(pre>post) dev(pre>post) ctrl s0 s1 abrt ctr func')
for e in hits:
print(f"{e['seq']:>6} {e['tx']:>4} {e['rx']:>4} "
f"{e['mc_pre']:>2}>{e['mc_post']:<2} "
f"{e['dev_pre']:>2}>{e['dev_post']:<2} "
f"{e['ctrl']:>6} {e['slot0']:>2} {e['slot1']:>2} "
f"{e['abort']:>4} {e['ctr']:>4} {e['func']}")