mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-26 02:11:36 -04:00
ae47e69902
Oracle disambiguation (RECURSION_BUG.md §23–§24). Traced one func_8001A954 invocation on real HW (psx-beetle) vs the recomp in the IDENTICAL Tomba idle state (New Game village dialogue; object 0x801FD950, state/scene/jumptable=0). VERDICT: real HW's per-frame chain is BALANCED — func_8001A954 is entered once per frame from main_loop (JAL 0x8001A630, sp=0x801FE3E0) and RETURNS once per frame (jr ra @0x8001A9E8 -> 0x8001A638, SP fully restored); no re-entry, the overlay 0x80063864 never calls back (refutes §21/§22's "call-cycle"). The recomp runs the same guest flow and the guest SP unwinds identically, but the HOST stack leaks +1.17 KB/frame (ce_profile, live-reconfirmed: 20099->22215 KB / 1807 frames) because the per-frame compiled chain (func_8001A954->AC00->B2B4->B5A8->func_80046264, emitted as DIRECT func_X(cpu) host calls) re-enters itself via func_80046264's CD-DMA-dirty hop and never unwinds. native_stack early-trip (PSX_STACK_GUARD_KB=6144, frame 7592, 6 MB) pins the leaking host cycle. Cross-checked: xprobe mixed_depth bounded at 6, dirty-insn/ dirty-block show NO literal func_8001A954 transfer, and a954=1/frame is a SURFACED guest tail-transfer (j/jr) to func_8001A954 that the oracle proves real HW never makes — i.e. there is both (A) a correctness divergence (spurious per-frame re-entry) and (B) the architectural host-mirroring limitation that amplifies it. Fix scope CORRECTED from §23's "quick contained runtime patch": the UNIVERSAL fix is §11 — route in-range guest calls through the depth-managed psx_dispatch_impl trampoline instead of mirroring them as direct host calls, so the host stack stays bounded regardless of guest re-entrancy (real or fabricated). §12 (CD-DMA dirty precision) and fixing the specific divergence are surgical mitigations, not universal. Performance loss accepted for now (static recomp: right before fast). Instruments added (runtime-only, no regen): - SP capture in the fntrace control-flow ring on BOTH backends (GPR[29] read live): psx-beetle (beetle_libretro.cpp + beetle_debug_server.c) and the recomp (fntrace.h/.c + debug_server.c) — enables the func_8001A954 SP/RA-lifecycle oracle. - psx-beetle default debug port 4380 -> 4382 (+ --port N override): 4380 collided with psxref and cdirecomp/CdiRuntime.exe; two LISTENers on one port silently misroute connections (the phantom "oracle keeps dying" early in the session). Oracle tooling: the control-flow oracle is psx-beetle (Beetle interprets -> records every J/JAL/JR/JALR), NOT psxref (no PC trace; the assumed emu_step/emu_trace_addr never existed). Loads Tomba via: psx-beetle.exe --disc tomba.cue <bios> --port 4382. Next: implement the §11 universal fix (codegen + full regen). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>