mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-26 02:11:36 -04:00
5b3c7dd08d
Today's session work
- runtime/src/debug_server.c: freeze_check TCP cmd snapshots all liveness
counters (PC, exception entries, exception_reentry_blocks, dirty_ram
blocks/insns, fn_entry total + top-K histogram, SIO IRQ pending +
countdown, sio_stat/i_stat/i_mask, mc_max_state) for tight-loop
diagnosis when the runtime hangs
- runtime/src/debug_server.c: wtrace slot 12 covering [0x72F0..0x72F4]
(data-byte counter); measured peak=1 confirming setup_data_phase resets
the counter mid-cycle
- runtime/src/interrupts.c: exception_entries_total + exception_reentry_blocks
counters + psx_get_freeze_diag accessor
- runtime/src/sio.c: sio_get_freeze_diag accessor for IRQ pacing internals
- memory entries: phase4_card_gate_setup_writes_2026_04_28 (refutes the
prior \"missing [0x7568+slot] clearer\" framing — setup functions write
LSB=0 directly), phase4_72f0_one_byte_per_vblank_2026_04_28 (peak=1
measurement)
Overnight session work bundled in
- runtime/src/dirty_ram_interp.{c,h}: small MIPS interpreter for
install-at-runtime kernel RAM stubs (Rule 18; e.g., SIO data-byte
handler the BIOS writes to RAM 0xCF0)
- recompiler/src/full_function_emitter.{cpp,h}: 3057 jal/jalr continuation
return labels added to dispatch table (continuation fix); branch
fall-through fix for conditional-branch delay slots
- recompiler/src/strict_translator.cpp: matching translator updates
- generated/: regenerated SCPH1001 dispatch + full C output reflecting
the recompiler changes
- runtime/include/debug_server.h, src/memory.c: card_txn ring + SIO IRQ
ring + EvCB walk ring + per-PC dirty_ram counters + always-on wtrace
coverage for [0x755A], [0x7514], [0x7528], [0x7520], [0x74A4],
[0x75C0..C8], [0x74B8..C0]
- recompiler/tests/, runtime/tests/: SIO/card protocol unit tests
- tools/: 60+ Python diagnostic scripts (chain_trace analysis, SIO trace
diff, EvCB walker, wtrace dumpers, etc.)
- docs/: psx_bios_disasm reference + dynamic_handler_install rationale
- OVERNIGHT_2026_04_28.md, SUMMARY_20260412_2.md: session logs
Phase 4 status (still blocked, root cause better understood)
- BIOS card chain runs through R-handlers correctly (chain_trace shows
R1..R11 cycling 26x); shell IS retriggering _card_read
- Install handler at ROM 0xBFC15F1C increments [0x72F0] correctly per
SIO IRQ; gate at <0x80 / <0x7F is correct
- Bottleneck: SIO IRQ countdown is access-paced, fires ~1× per VBlank
vs ~128× needed; setup_data_phase (called from outer coord on VBlank)
zeroes [0x72F0] before counter reaches 128
- Both attempted fixes today caused freezes:
* VBlank deferral on [0x75C0]==1 — pending VBlank already in i_stat
delivered anyway; tighter dispatch gate also locked up
* Cycle-paced sio_tick at rates 50, 200 (and gated on [0x75C0]==1) —
runtime freezes once data phase activates, root cause unidentified
- delay=5 narrows the threshold (peak=2 vs peak=1, no freeze) but
doesn't get to 0x80
- Real fix likely requires deeper instrumentation of the freeze (call
stack / dispatch state at the moment of TCP starvation)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
68 lines
2.0 KiB
Python
68 lines
2.0 KiB
Python
#!/usr/bin/env python3
|
|
"""Decode state handler output values from hex."""
|
|
import struct
|
|
|
|
# Handler address -> first 16 bytes (hex)
|
|
handlers = {
|
|
0x0003648C: "0880013c489e20ac0680013c35000a24",
|
|
0x00036578: "0680053c4c69a58c000000002a00a010",
|
|
0x00036568: "3e0019240680013c01000010406939ac",
|
|
0x00036538: "37000e240680013c0d00001040692eac",
|
|
0x00036450: "340019240680013c486939ac0680013c",
|
|
0x0003642C: "32000f240680013c48692fac0680013c",
|
|
0x0003647C: "360009240680013c3c000010406929ac",
|
|
0x00036548: "38000f240680013c0900001040692fac",
|
|
0x00036558: "3d0018240680013c05000010406938ac",
|
|
}
|
|
|
|
# Second jump table: state -> handler
|
|
jtable = {
|
|
0x02: 0x0003648C,
|
|
0x03: 0x00036578,
|
|
0x04: 0x00036568,
|
|
0x05: 0x00036538,
|
|
0x06: 0x00036578,
|
|
0x07: 0x00036578,
|
|
0x08: 0x00036578,
|
|
0x09: 0x00036450,
|
|
0x0A: 0x00036450,
|
|
0x0B: 0x0003642C,
|
|
0x0C: 0x00036578,
|
|
0x0D: 0x00036568,
|
|
0x0E: 0x00036578,
|
|
0x0F: 0x0003647C,
|
|
0x10: 0x00036578,
|
|
0x11: 0x00036568,
|
|
0x12: 0x00036578,
|
|
0x13: 0x00036578,
|
|
0x14: 0x00036578,
|
|
0x15: 0x00036578,
|
|
0x16: 0x00036548,
|
|
0x17: 0x00036568,
|
|
0x18: 0x0003648C,
|
|
0x19: 0x00036558,
|
|
}
|
|
|
|
print("State -> Output mapping (second dispatcher):")
|
|
print(f"{'State':>7} {'Handler':>10} {'Output':>8}")
|
|
print("-" * 30)
|
|
|
|
for state in sorted(jtable.keys()):
|
|
handler_addr = jtable[state]
|
|
hex_data = handlers[handler_addr]
|
|
raw = bytes.fromhex(hex_data)
|
|
word0 = struct.unpack_from('<I', raw, 0)[0]
|
|
|
|
# Most handlers start with: addiu rN, zero, VALUE
|
|
opcode = (word0 >> 26) & 0x3F
|
|
rs = (word0 >> 21) & 0x1F
|
|
imm = word0 & 0xFFFF
|
|
|
|
if opcode == 0x09 and rs == 0: # addiu rN, $zero, imm
|
|
output = imm
|
|
print(f" 0x{state:02X} 0x{handler_addr:08X} 0x{output:02X} ({output})")
|
|
elif opcode == 0x0F: # lui (different pattern)
|
|
print(f" 0x{state:02X} 0x{handler_addr:08X} (complex)")
|
|
else:
|
|
print(f" 0x{state:02X} 0x{handler_addr:08X} (unknown op={opcode:#x})")
|