mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-26 02:11:36 -04:00
fntrace: capture dispatch-level bail source (runtime-only, no BIOS regen)
The dominant Tomba 2 splash-spin bails are emitted by the generated dispatch trampoline (compiled functions C-returning wild), which the direct-call psx_call_contract ledger can't see. fntrace_record() runs at the top of every psx_dispatch_impl iteration; on a g_psx_bail_flattened delta it feeds (g_debug_current_func_addr = the just-bailed compiled fn, target = wild dest) into the traps.c bail ledger -> surfaced in the heartbeat as bail_top_site_ra / bail_top_wild_pc. Survives the bail-storm degradation (read from the file). Pinned the root cause: dominant bailing fn = 0xB0 (B0 syscall vector); a nested B0 syscall returns non-locally to its outer frame's return (0x8008AE50, the jal+8 of a `jal 0x80085900` in high RAM), the wild-return contract bails, the outer frame's $sp is not restored, and the guest degenerates to $ra=$sp=1 in an infinite bail loop -- the wild-call-contract family (Bug A/C/D) on the B0 path. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -46,6 +46,28 @@ static inline int armed_match(uint32_t target) {
|
||||
}
|
||||
|
||||
void fntrace_record(CPUState* cpu, uint32_t target) {
|
||||
/* Dispatch-level bail-source capture (Tomba 2 wild-return spin, runtime-only,
|
||||
* no BIOS regen). The generated psx_dispatch_impl calls us at the top of each
|
||||
* dispatch iteration. When a previous iteration bail-FLATTENED a compiled
|
||||
* function's wild return, g_psx_bail_flattened has incremented and
|
||||
* g_debug_current_func_addr still holds that bailing function, while `target`
|
||||
* is the wild destination it returned to. Feed (bailing_fn, wild_target) into
|
||||
* the traps.c bail ledger (surfaced in the heartbeat as bail_top_site_ra /
|
||||
* bail_top_wild_pc) so the dominant wild-returning function is readable even
|
||||
* when the bail storm makes the window "Not Responding". */
|
||||
{
|
||||
extern uint64_t g_psx_bail_flattened;
|
||||
extern uint32_t g_debug_current_func_addr;
|
||||
extern void psx_bail_record(uint32_t site_ra, uint32_t site_sp,
|
||||
uint32_t wild_pc, uint32_t guest_sp);
|
||||
static uint64_t s_last_flat = 0;
|
||||
uint64_t f = g_psx_bail_flattened;
|
||||
if (f != s_last_flat) {
|
||||
s_last_flat = f;
|
||||
psx_bail_record(g_debug_current_func_addr, cpu->gpr[29], target, cpu->gpr[31]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!s_game_started && s_game_entry_phys != 0) {
|
||||
if ((target & 0x1FFFFFFFu) == s_game_entry_phys) {
|
||||
s_game_started = 1;
|
||||
|
||||
Reference in New Issue
Block a user