mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-27 18:52:11 -04:00
926a9e9e99
PS1 segments alias the same physical RAM. Most PS-X EXE headers carry KSEG addresses, but a header may legally carry KUSEG ones instead, and the guest then executes with a KUSEG PC. Alien Resurrection (SLUS-00633) is such a title: its header holds load address 0x00010000 and entry PC 0x000155A4, and get_registers on a live run reports PC=0x00010170. The emitted dispatch table is keyed by the recompiler's KSEG-normalized addresses, and psx_game_find_entry() compared those keys against the raw incoming address. For a KUSEG PC the comparison can never succeed, because 0x0001xxxx is always below 0x8001xxxx: the binary search walks to the start of the table and returns no entry. Every dispatch then falls through to the interpreter. The failure is silent and easy to misread. psx_game_address_in_text() does mask, so it still reports the address as game text and the interpreter runs the real RAM bytes via clean_game_text_miss. The game boots and renders correctly, just entirely interpreted. Because no entry is ever found, the text-image guard is not reached either, so its diagnostics stay at zero (text_native_blocked=0, text_exact_mismatches=0) while dirty_ram_stats reports over a billion interpreted instructions and native_handoffs=0 -- which reads as "nothing was rejected" rather than "nothing was looked up". Compare 29-bit physical addresses on both sides of the search, and sort the table by that same masked key so the binary-search invariant holds by construction rather than by every entry happening to share a segment. Adds tests/test_kuseg_dispatch_lookup.py: synthesizes a KUSEG-addressed PS-EXE, runs the emitter, and asserts the lookup masks both the incoming address and the stored key, and that the emitted table is ordered by physical address. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>