From 2b30c1291db9d9801d51cf85f71f40fe54958898 Mon Sep 17 00:00:00 2001 From: notaz Date: Thu, 18 Dec 2014 03:56:01 +0200 Subject: [PATCH 1/1] spu: add a schedule callback --- frontend/main.c | 1 + frontend/plugin.c | 4 +++- libpcsxcore/new_dynarec/emu_if.c | 1 + libpcsxcore/plugins.c | 3 +++ libpcsxcore/plugins.h | 2 ++ libpcsxcore/r3000a.c | 6 ++++++ libpcsxcore/r3000a.h | 1 + libpcsxcore/spu.c | 12 ++++++++++++ libpcsxcore/spu.h | 2 ++ plugins/dfsound/spu.c | 4 ++++ 10 files changed, 35 insertions(+), 1 deletion(-) diff --git a/frontend/main.c b/frontend/main.c index 1caec4b3..acebaaee 100644 --- a/frontend/main.c +++ b/frontend/main.c @@ -853,6 +853,7 @@ static int _OpenPlugins(void) { ret = SPU_open(); if (ret < 0) { SysMessage(_("Error opening SPU plugin!")); return -1; } SPU_registerCallback(SPUirq); + SPU_registerScheduleCb(SPUschedule); // pcsx-rearmed: we handle gpu elsewhere //ret = GPU_open(&gpuDisp, "PCSX", NULL); //if (ret < 0) { SysMessage(_("Error opening GPU plugin!")); return -1; } diff --git a/frontend/plugin.c b/frontend/plugin.c index 7e8e5c3f..1980ef5b 100644 --- a/frontend/plugin.c +++ b/frontend/plugin.c @@ -32,7 +32,8 @@ extern unsigned short SPUreadDMA(void); extern void SPUwriteDMAMem(unsigned short *, int); extern void SPUreadDMAMem(unsigned short *, int); extern void SPUplayADPCMchannel(void *); -extern void SPUregisterCallback(void (*callback)(void)); +extern void SPUregisterCallback(void (*cb)(void)); +extern void SPUregisterScheduleCb(void (*cb)(unsigned int)); extern long SPUconfigure(void); extern long SPUtest(void); extern void SPUabout(void); @@ -135,6 +136,7 @@ static const struct { DIRECT_SPU(SPUplayADPCMchannel), DIRECT_SPU(SPUfreeze), DIRECT_SPU(SPUregisterCallback), + DIRECT_SPU(SPUregisterScheduleCb), DIRECT_SPU(SPUasync), DIRECT_SPU(SPUplayCDDAchannel), /* PAD */ diff --git a/libpcsxcore/new_dynarec/emu_if.c b/libpcsxcore/new_dynarec/emu_if.c index cb95cb1c..89e2bd6f 100644 --- a/libpcsxcore/new_dynarec/emu_if.c +++ b/libpcsxcore/new_dynarec/emu_if.c @@ -60,6 +60,7 @@ static irq_func * const irq_funcs[] = { [PSXINT_CDRDMA] = cdrDmaInterrupt, [PSXINT_CDRLID] = cdrLidSeekInterrupt, [PSXINT_CDRPLAY] = cdrPlayInterrupt, + [PSXINT_SPU_UPDATE] = spuUpdate, [PSXINT_RCNT] = psxRcntUpdate, }; diff --git a/libpcsxcore/plugins.c b/libpcsxcore/plugins.c index 57078bad..e6d8a11e 100644 --- a/libpcsxcore/plugins.c +++ b/libpcsxcore/plugins.c @@ -88,6 +88,7 @@ SPUreadDMAMem SPU_readDMAMem; SPUplayADPCMchannel SPU_playADPCMchannel; SPUfreeze SPU_freeze; SPUregisterCallback SPU_registerCallback; +SPUregisterScheduleCb SPU_registerScheduleCb; SPUasync SPU_async; SPUplayCDDAchannel SPU_playCDDAchannel; @@ -320,6 +321,7 @@ void *hSPUDriver = NULL; long CALLBACK SPU__configure(void) { return 0; } void CALLBACK SPU__about(void) {} long CALLBACK SPU__test(void) { return 0; } +void CALLBACK SPU__registerScheduleCb(void (CALLBACK *cb)(unsigned int)) {} #define LoadSpuSym1(dest, name) \ LoadSym(SPU_##dest, SPU##dest, name, TRUE); @@ -356,6 +358,7 @@ static int LoadSPUplugin(const char *SPUdll) { LoadSpuSym1(playADPCMchannel, "SPUplayADPCMchannel"); LoadSpuSym1(freeze, "SPUfreeze"); LoadSpuSym1(registerCallback, "SPUregisterCallback"); + LoadSpuSym0(registerScheduleCb, "SPUregisterScheduleCb"); LoadSpuSymN(async, "SPUasync"); LoadSpuSymN(playCDDAchannel, "SPUplayCDDAchannel"); diff --git a/libpcsxcore/plugins.h b/libpcsxcore/plugins.h index dfa87221..9df55bf1 100644 --- a/libpcsxcore/plugins.h +++ b/libpcsxcore/plugins.h @@ -192,6 +192,7 @@ typedef void (CALLBACK* SPUwriteDMAMem)(unsigned short *, int); typedef void (CALLBACK* SPUreadDMAMem)(unsigned short *, int); typedef void (CALLBACK* SPUplayADPCMchannel)(xa_decode_t *); typedef void (CALLBACK* SPUregisterCallback)(void (CALLBACK *callback)(void)); +typedef void (CALLBACK* SPUregisterScheduleCb)(void (CALLBACK *callback)(unsigned int cycles_after)); typedef long (CALLBACK* SPUconfigure)(void); typedef long (CALLBACK* SPUtest)(void); typedef void (CALLBACK* SPUabout)(void); @@ -226,6 +227,7 @@ extern SPUreadDMAMem SPU_readDMAMem; extern SPUplayADPCMchannel SPU_playADPCMchannel; extern SPUfreeze SPU_freeze; extern SPUregisterCallback SPU_registerCallback; +extern SPUregisterScheduleCb SPU_registerScheduleCb; extern SPUasync SPU_async; extern SPUplayCDDAchannel SPU_playCDDAchannel; diff --git a/libpcsxcore/r3000a.c b/libpcsxcore/r3000a.c index f5996acf..82eb8857 100644 --- a/libpcsxcore/r3000a.c +++ b/libpcsxcore/r3000a.c @@ -185,6 +185,12 @@ void psxBranchTest() { cdrLidSeekInterrupt(); } } + if (psxRegs.interrupt & (1 << PSXINT_SPU_UPDATE)) { // scheduled spu update + if ((psxRegs.cycle - psxRegs.intCycle[PSXINT_SPU_UPDATE].sCycle) >= psxRegs.intCycle[PSXINT_SPU_UPDATE].cycle) { + psxRegs.interrupt &= ~(1 << PSXINT_SPU_UPDATE); + spuUpdate(); + } + } } if (psxHu32(0x1070) & psxHu32(0x1074)) { diff --git a/libpcsxcore/r3000a.h b/libpcsxcore/r3000a.h index 13aaa595..a6a6254e 100644 --- a/libpcsxcore/r3000a.h +++ b/libpcsxcore/r3000a.h @@ -160,6 +160,7 @@ enum { PSXINT_RCNT, PSXINT_CDRLID, PSXINT_CDRPLAY, + PSXINT_SPU_UPDATE, PSXINT_COUNT }; diff --git a/libpcsxcore/spu.c b/libpcsxcore/spu.c index a60c0478..f23051ec 100644 --- a/libpcsxcore/spu.c +++ b/libpcsxcore/spu.c @@ -26,3 +26,15 @@ void CALLBACK SPUirq(void) { psxHu32ref(0x1070) |= SWAPu32(0x200); } + +// spuUpdate +void CALLBACK SPUschedule(unsigned int cycles_after) { + psxRegs.interrupt |= (1 << PSXINT_SPU_UPDATE); + psxRegs.intCycle[PSXINT_SPU_UPDATE].cycle = cycles_after; + psxRegs.intCycle[PSXINT_SPU_UPDATE].sCycle = psxRegs.cycle; + new_dyna_set_event(PSXINT_SPU_UPDATE, cycles_after); +} + +void spuUpdate() { + SPU_async(psxRegs.cycle); +} diff --git a/libpcsxcore/spu.h b/libpcsxcore/spu.h index 85010cbd..44a35d5f 100644 --- a/libpcsxcore/spu.h +++ b/libpcsxcore/spu.h @@ -40,6 +40,8 @@ extern "C" { #define H_SPUoff2 0x0d8e void CALLBACK SPUirq(void); +void CALLBACK SPUschedule(unsigned int cycles_after); +void spuUpdate(); #ifdef __cplusplus } diff --git a/plugins/dfsound/spu.c b/plugins/dfsound/spu.c index 8f6ed139..7d3f1a0e 100644 --- a/plugins/dfsound/spu.c +++ b/plugins/dfsound/spu.c @@ -1121,6 +1121,10 @@ void CALLBACK SPUregisterCDDAVolume(void (CALLBACK *CDDAVcallback)(unsigned shor cddavCallback = CDDAVcallback; } +void CALLBACK SPUregisterScheduleCb(void (CALLBACK *callback)(unsigned int)) +{ +} + // COMMON PLUGIN INFO FUNCS /* char * CALLBACK PSEgetLibName(void) -- 2.39.2