mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-26 02:11:36 -04:00
e8094affb4
EvCB write-trace instrumentation confirmed OpenEvent is never called for
any event class during boot, not only VBlank. Static ROM analysis found
that the only instruction in SCPH1001.BIN that stores to the VSync
counter at 0x80079D9C lives in an unrecompiled 15-instruction function
at 0xBFC425BC (identified as the VBlank chain handler: increments the
counter, optionally calls the user callback at *0x800DFF40). Added as a
seed so the function is now compiled and present in the dispatch table.
Recompile alone does not unblock the boot — no JAL, literal, or
lui 0xBFC4 exists in ROM that would load this address, so the kernel
registrar that enqueues it on the root-counter chain is itself missing
and needs to be found (next session, via DuckStation cross-reference).
Changes:
- recompiler/seeds: +0xBFC425BC (vblank_chain_handler), 825 seeds total
- debug_server: wtrace_range / wtrace_dump / wtrace_clear TCP commands,
1024-entry ring buffer capturing (addr, old, new, ra, width); default
range 0x0000E000..0x0000E1F0 active from process start so early-boot
writes are captured before a TCP client can attach
- memory.c: inline bounds check + hook call in psx_write_{word,half,byte}
- tools: print_wtrace.py, sample_ra.py, sample_ra_long.py,
scan_f2_sites.py — investigation helpers
Runtime behaviour unchanged (still hangs in VSync spin at Sony logo) —
the seed is a prerequisite; the upstream registrar is the next bug.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
45 lines
1.1 KiB
Python
45 lines
1.1 KiB
Python
#!/usr/bin/env python3
|
|
"""Sample $ra + EPC over N seconds to profile hot code regions."""
|
|
import socket, json, sys, time, collections
|
|
|
|
HOST, PORT = "127.0.0.1", 4370
|
|
DURATION = float(sys.argv[1]) if len(sys.argv) > 1 else 5.0
|
|
|
|
s = socket.socket()
|
|
s.connect((HOST, PORT))
|
|
s.settimeout(2.0)
|
|
buf = b""
|
|
ra_hist = collections.Counter()
|
|
epc_hist = collections.Counter()
|
|
n_samples = 0
|
|
t_end = time.time() + DURATION
|
|
|
|
def read_line():
|
|
global buf
|
|
while b"\n" not in buf:
|
|
chunk = s.recv(16384)
|
|
if not chunk: return None
|
|
buf += chunk
|
|
line, _, buf = buf.partition(b"\n")
|
|
return line.decode()
|
|
|
|
while time.time() < t_end:
|
|
s.sendall(b'{"cmd":"get_registers"}\n')
|
|
line = read_line()
|
|
if not line: break
|
|
d = json.loads(line)
|
|
ra = d['gpr'][31]
|
|
epc = d['cop0_epc']
|
|
ra_hist[ra] += 1
|
|
epc_hist[epc] += 1
|
|
n_samples += 1
|
|
|
|
s.close()
|
|
print(f"samples: {n_samples}")
|
|
print(f"--- top 15 $ra ---")
|
|
for ra, cnt in ra_hist.most_common(15):
|
|
print(f" {ra} {cnt:5} ({100.0*cnt/n_samples:.1f}%)")
|
|
print(f"--- top 15 EPC ---")
|
|
for epc, cnt in epc_hist.most_common(15):
|
|
print(f" {epc} {cnt:5} ({100.0*cnt/n_samples:.1f}%)")
|