mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-26 02:11:36 -04:00
6889f5c5d2
Modal close on YES/NO COPY confirm now works on recomp. Cause: function
discovery (Ghidra + transitive walk) missed the function at 0xBFC1A1BC
which the BIOS shell calls indirectly during modal close. The 5 nearby
"missing" PCs the diagnostic identified are all in the same gap from
0xBFC1A1B8 to 0xBFC1A3B8; seeding 0xBFC1A1BC discovers the rest
transitively.
Status: modal closes cleanly on X. Actual copy execution still has
downstream missing-function-discovery issues (3 more PCs hit
psx_unknown_dispatch on copy: 0xBFC09890, 0xBFC0989C, 0xBFC02918)
plus likely additional bugs that softlock when those are seeded.
Those remain for follow-up; this commit is the modal-close milestone.
This is a BANDAID per user permission. The proper fix is to improve
function discovery so missed functions like 0xBFC1A1BC are found
automatically. Ghidra didn't see this function, and our transitive
walk didn't reach it either.
Tooling additions:
- psx_unknown_dispatch_record() ring buffer + unknown_dispatch_log
debug command. Replaces the prior file-based miss log per
CLAUDE.md §3 (no log files, ever). Always-on; queryable summary
(per-target counts) or tail (last N entries with addr/phys/ra/a0/a1).
- WTRACE_MAX_RANGES bumped from 16 -> 64 (boot defaults were
crowding out investigative arms).
- DirtyRamBlockLogEntry +a0/a1 fields, ring CAP 16K -> 4M
(previous 28ms eviction made retroactive press-window analysis
impossible).
Diagnostic scripts (kept):
tools/_unknown_dispatch.py — query unknown_dispatch_log
tools/_dispatch_check_v3.py — was a PC ever dispatched (RAM->ROM map)
tools/_dispatch_tail.py — last N dispatched targets
tools/_freeze_diag2.py — softlock investigator
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
39 lines
1.5 KiB
Python
39 lines
1.5 KiB
Python
"""Query psx-runtime for psx_unknown_dispatch hits since boot.
|
|
Default: per-target summary sorted by hit count.
|
|
With tail=N: most recent N entries from the ring."""
|
|
import socket, json, sys
|
|
def call(payload):
|
|
s = socket.create_connection(('127.0.0.1', 4370), timeout=10)
|
|
s.sendall((json.dumps(dict(payload, id=1))+'\n').encode())
|
|
buf = b''
|
|
while True:
|
|
c = s.recv(1<<20)
|
|
if not c: break
|
|
buf += c
|
|
try: return json.loads(buf.decode())
|
|
except: pass
|
|
raise RuntimeError("incomplete")
|
|
|
|
if len(sys.argv) > 1 and sys.argv[1] == 'tail':
|
|
r = call({'cmd':'unknown_dispatch_log','tail':50})
|
|
print(f"total={r.get('total')} unique={r.get('unique')} tail={r.get('tail')}")
|
|
for e in r.get('entries', [])[-30:]:
|
|
print(f" seq={e['seq']:>6} addr={e['addr']} phys={e['phys']} ra={e['ra']} a0={e['a0']} a1={e['a1']} frame={e['frame']}")
|
|
else:
|
|
r = call({'cmd':'unknown_dispatch_log'})
|
|
print(f"=== Unknown dispatch summary ===")
|
|
print(f"total hits={r.get('total')} unique targets={r.get('unique')}\n")
|
|
summary = r.get('summary', [])
|
|
for s in summary[:30]:
|
|
phys = s['phys']
|
|
cnt = s['count']
|
|
# Highlight modal-investigation PCs
|
|
marker = ''
|
|
for known_phys, lbl in [
|
|
(0x1FC1A1BC, 'MODAL STUB'),
|
|
(0x1FC1A300, 'cursor_mirror2 writer 2'),
|
|
]:
|
|
if int(phys, 16) == known_phys:
|
|
marker = f' <-- {lbl}'
|
|
print(f" {phys}: {cnt:>8}{marker}")
|