mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-26 02:11:36 -04:00
99a4002ffb
Adds a CD-command trace to psx-beetle (beetle_cdcmd_trace_hook.patch: callback in cdc.cpp's command dispatch, wired through beetle_libretro.cpp into cdrom_cmd_dump / cdrom_cmd_reset on the oracle debug server). This is the two-process oracle-diff the setup is built for, now working on Linux. Live-diff result (docs/kula-world-findings.md, bug 3): the oracle's game reads level data with a clean Setloc->SeekL->Setmode->ReadN->Pause per sector (SeekL x18, ReadN x22, GetlocL x89). Our runtime's game, in the wedge, issues NEITHER SeekL NOR ReadN — only GetStat/Init/Setloc/Pause, an error/retry branch the oracle never enters. Crucial: our runtime DID deliver 307 sectors during early boot (ReadN + data delivery work). Reads only stop at frame ~890 — the BIOS mid-game region revalidation (ReadTOC+GetID). The region fix made that PASS, but the post-ReadTOC CD state still stops the game resuming reads. Prime suspect: our ReadTOC (case 0x1E) is a bare stat+COMPLETE stub that does not model drive repositioning / the track table the game reads to recompute its seek. Documented for the next session. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BdjxoRB1f9VQsNzZayCgGS
83 lines
4.0 KiB
Diff
83 lines
4.0 KiB
Diff
diff --git a/libretro.cpp b/libretro.cpp
|
|
index d2e82bca..e9c867c8 100644
|
|
--- a/libretro.cpp
|
|
+++ b/libretro.cpp
|
|
@@ -508,6 +508,11 @@ PS_SPU *PSX_SPU = NULL;
|
|
PS_CDC *PSX_CDC = NULL;
|
|
FrontIO *PSX_FIO = NULL;
|
|
|
|
+/* PSXRecomp oracle hooks: NULL when no listener attached. */
|
|
+psxrecomp_wtrace_cb_t g_psxrecomp_wtrace_cb = NULL;
|
|
+psxrecomp_fntrace_cb_t g_psxrecomp_fntrace_cb = NULL;
|
|
+psxrecomp_cdcmd_cb_t g_psxrecomp_cdcmd_cb = NULL;
|
|
+
|
|
MultiAccessSizeMem<512 * 1024, uint32, false> *BIOSROM = NULL;
|
|
MultiAccessSizeMem<65536, uint32, false> *PIOMem = NULL;
|
|
MultiAccessSizeMem<2048 * 1024, uint32, false> *MainRAM = NULL;
|
|
diff --git a/mednafen/psx/cdc.cpp b/mednafen/psx/cdc.cpp
|
|
index 1daaa5b7..d62c7ee9 100644
|
|
--- a/mednafen/psx/cdc.cpp
|
|
+++ b/mednafen/psx/cdc.cpp
|
|
@@ -1318,6 +1318,12 @@ int32_t PS_CDC::Update(const int32_t timestamp)
|
|
else
|
|
{
|
|
const CDC_CTEntry *command = &Commands[PendingCommand];
|
|
+ /* PSXRecomp oracle hook: CD command about to execute. */
|
|
+ if(MDFN_UNLIKELY(g_psxrecomp_cdcmd_cb))
|
|
+ g_psxrecomp_cdcmd_cb(PendingCommand, ArgsReceiveIn,
|
|
+ ArgsReceiveIn > 0 ? ArgsReceiveBuf[0] : 0,
|
|
+ ArgsReceiveIn > 1 ? ArgsReceiveBuf[1] : 0,
|
|
+ ArgsReceiveIn > 2 ? ArgsReceiveBuf[2] : 0);
|
|
next_time = (this->*(command->func))(ArgsReceiveIn, ArgsReceiveBuf);
|
|
PendingCommandPhase = 2;
|
|
}
|
|
diff --git a/mednafen/psx/psx.h b/mednafen/psx/psx.h
|
|
index 704c0a19..d9538c13 100644
|
|
--- a/mednafen/psx/psx.h
|
|
+++ b/mednafen/psx/psx.h
|
|
@@ -137,4 +137,44 @@ extern unsigned psx_gpu_overclock_shift;
|
|
extern uint8_t analog_combo[2];
|
|
extern uint8_t analog_combo_hold;
|
|
|
|
+/* PSXRecomp oracle: SIO byte trace callback.
|
|
+ * Fired by FrontIO when a complete byte exchange finishes. */
|
|
+class FrontIO;
|
|
+extern FrontIO *PSX_FIO;
|
|
+typedef void (*psxrecomp_sio_trace_cb_t)(uint8_t tx, uint8_t rx, uint16_t ctrl);
|
|
+
|
|
+/* PSXRecomp oracle: RAM write trace callback.
|
|
+ * Fired by PS_CPU::SB/SH/SW after the write completes.
|
|
+ * addr = virtual address (caller masks for physical filter)
|
|
+ * value = stored value (sized by `size`)
|
|
+ * pc = PC of the executing store instruction
|
|
+ * ra = $ra (GPR[31]) at time of store, for one frame of caller context
|
|
+ * size = 1, 2, or 4 (byte / halfword / word) */
|
|
+typedef void (*psxrecomp_wtrace_cb_t)(uint32_t addr, uint32_t value,
|
|
+ uint32_t pc, uint32_t ra, uint8_t size);
|
|
+extern psxrecomp_wtrace_cb_t g_psxrecomp_wtrace_cb;
|
|
+
|
|
+/* PSXRecomp oracle: function-call (JAL/JALR/J/JR) trace callback.
|
|
+ * Fired by PS_CPU on every J/JAL/JR/JALR retire, BEFORE the link write.
|
|
+ * Caller filters by target_pc to keep volume bounded.
|
|
+ * caller_pc = PC of the J/JAL/JR/JALR instruction
|
|
+ * target_pc = computed branch target
|
|
+ * parent_ra = GPR[31] at time of call (parent's return address)
|
|
+ * a0, a1 = argument registers at time of call
|
|
+ * kind = 1=J, 2=JAL, 3=JR, 4=JALR */
|
|
+typedef void (*psxrecomp_fntrace_cb_t)(uint32_t caller_pc, uint32_t target_pc,
|
|
+ uint32_t parent_ra, uint32_t a0,
|
|
+ uint32_t a1, uint8_t kind);
|
|
+extern psxrecomp_fntrace_cb_t g_psxrecomp_fntrace_cb;
|
|
+
|
|
+/* PSXRecomp oracle: CD command trace callback.
|
|
+ * Fired by PS_CDC just before a command handler executes.
|
|
+ * cmd = command byte (0x01 GetStat, 0x02 Setloc, 0x06 ReadN, 0x09 Pause,
|
|
+ * 0x0A Init, 0x0E Setmode, 0x15 SeekL, 0x1A GetID, 0x1B ReadS, ...)
|
|
+ * nargs = number of argument bytes
|
|
+ * arg0..arg2 = first three argument bytes (0 if absent) */
|
|
+typedef void (*psxrecomp_cdcmd_cb_t)(uint8_t cmd, uint8_t nargs,
|
|
+ uint8_t arg0, uint8_t arg1, uint8_t arg2);
|
|
+extern psxrecomp_cdcmd_cb_t g_psxrecomp_cdcmd_cb;
|
|
+
|
|
#endif
|