diff --git a/libretro.cpp b/libretro.cpp index 99b87c80..e9c867c8 100644 --- a/libretro.cpp +++ b/libretro.cpp @@ -511,6 +511,7 @@ 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; diff --git a/mednafen/psx/cdc.cpp b/mednafen/psx/cdc.cpp index 1daaa5b7..a6b31b66 100644 --- a/mednafen/psx/cdc.cpp +++ b/mednafen/psx/cdc.cpp @@ -1318,6 +1318,16 @@ int32_t PS_CDC::Update(const int32_t timestamp) else { const CDC_CTEntry *command = &Commands[PendingCommand]; + /* PSXRecomp oracle hook: CD command about to execute. + * PC of the guest at dispatch time — the command was + * WRITTEN earlier (latency), so this is the poll/idle + * PC, but it still localizes kernel vs shell vs game. */ + 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, + PSX_CPU ? PSX_CPU->GetRegister(PS_CPU::GSREG_PC, NULL, 0) : 0); next_time = (this->*(command->func))(ArgsReceiveIn, ArgsReceiveBuf); PendingCommandPhase = 2; } diff --git a/mednafen/psx/psx.h b/mednafen/psx/psx.h index e16a230f..fc53362d 100644 --- a/mednafen/psx/psx.h +++ b/mednafen/psx/psx.h @@ -167,4 +167,15 @@ typedef void (*psxrecomp_fntrace_cb_t)(uint32_t caller_pc, uint32_t target_pc, 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, + uint32_t pc); +extern psxrecomp_cdcmd_cb_t g_psxrecomp_cdcmd_cb; + #endif