mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-26 02:11:36 -04:00
overlay ABI v12: forward psx_rfe_mark_escape into overlay DLLs
The emitter emits psx_rfe_mark_escape() at every rfe — including in overlay-resident exception-context code — but the dispatch preamble never provided it, so any rfe-containing overlay failed to LINK (undefined reference) and ran interpreted forever: the gte_read_ctrl silent-coverage-blocker class again (11 of Tomba's vault shards hit it). It mutates shared RFE-pending escape state (interrupts.c), so the shim forwards unconditionally through OverlayCallbacks; ABI bump to 12 rejects pre-shim caches. Found live during LOAD_TIME_ZERO E0 bring-up: the user's first pig load triggered autocapture and the compile died on this link error. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -46,7 +46,14 @@
|
||||
/* v11 batches per-instruction cycle charges inside overlay DLLs and flushes at
|
||||
* block/device/store boundaries, removing a cross-DLL callback per instruction
|
||||
* without changing the shared guest-cycle timeline. */
|
||||
#define PSX_OVERLAY_ABI_VERSION 11
|
||||
/* v12: rfe_mark_escape callback — the emitter emits psx_rfe_mark_escape() at
|
||||
* every `rfe` (code_generator.cpp COP0 case), including in overlay-resident
|
||||
* exception-context code (Tomba kernel-window overlays hit this). It mutates
|
||||
* the runtime's shared RFE-pending escape state (interrupts.c), so the DLL
|
||||
* MUST forward — a local no-op would swallow exception returns. Without the
|
||||
* shim any rfe-containing overlay fails to LINK (undefined psx_rfe_mark_escape)
|
||||
* and that variant runs interpreted forever — the gte_read_ctrl class again. */
|
||||
#define PSX_OVERLAY_ABI_VERSION 12
|
||||
|
||||
/* Codegen flavor of the recompiled output the overlays + runtime were built
|
||||
* against. Overlays are keyed in the cache by guest-bytes CRC, which is
|
||||
@@ -196,6 +203,10 @@ typedef struct {
|
||||
uint32_t (*gte_read_ctrl)(CPUState *cpu, uint8_t reg);
|
||||
void (*gte_write_data)(CPUState *cpu, uint8_t reg, uint32_t value);
|
||||
void (*gte_write_ctrl)(CPUState *cpu, uint8_t reg, uint32_t value);
|
||||
/* RFE escape marker (ABI v12; see the version-history note above).
|
||||
* Appended last; forwards unconditionally — v12 hosts always supply it
|
||||
* and the ABI gate rejects DLL/host mixes that don't. */
|
||||
void (*rfe_mark_escape)(void);
|
||||
} OverlayCallbacks;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -1746,6 +1746,13 @@ static void init_callbacks(void) {
|
||||
s_callbacks.gte_write_data = gte_write_data;
|
||||
s_callbacks.gte_write_ctrl = gte_write_ctrl;
|
||||
}
|
||||
/* ABI v12: rfe escape marker — emitted at every `rfe`, including in
|
||||
* overlay-resident exception-context code; mutates the runtime's
|
||||
* shared RFE-pending state so it must forward. */
|
||||
{
|
||||
extern void psx_rfe_mark_escape(void);
|
||||
s_callbacks.rfe_mark_escape = psx_rfe_mark_escape;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -953,6 +953,15 @@ void psx_restore_state_escape(void) {
|
||||
overlay_flush_cycles();
|
||||
if (g_cbs.psx_restore_state_escape) g_cbs.psx_restore_state_escape();
|
||||
}
|
||||
/* RFE escape marker (ABI v12): emitted at every `rfe`, including in
|
||||
* overlay-resident exception-context code. Mutates the runtime's shared
|
||||
* RFE-pending state, so it MUST forward (a local no-op would swallow
|
||||
* exception returns). Unconditional — v12 hosts always supply it; the
|
||||
* ABI gate rejects mixes that don't. */
|
||||
void psx_rfe_mark_escape(void) {
|
||||
overlay_flush_cycles();
|
||||
g_cbs.rfe_mark_escape();
|
||||
}
|
||||
/* Faithful-timing functions (ABI v9): overlay code built with PSX_ENABLE_BLOCK_CYCLES
|
||||
* emits these; forward to the runtime's real impls so native overlays charge cycles on
|
||||
* the SAME timeline as the interp/BIOS (a local copy would diverge). NULL-guarded so a
|
||||
|
||||
Reference in New Issue
Block a user