spu: add a schedule callback
authornotaz <notasas@gmail.com>
Thu, 18 Dec 2014 01:56:01 +0000 (03:56 +0200)
committernotaz <notasas@gmail.com>
Sat, 20 Dec 2014 00:57:25 +0000 (02:57 +0200)
frontend/main.c
frontend/plugin.c
libpcsxcore/new_dynarec/emu_if.c
libpcsxcore/plugins.c
libpcsxcore/plugins.h
libpcsxcore/r3000a.c
libpcsxcore/r3000a.h
libpcsxcore/spu.c
libpcsxcore/spu.h
plugins/dfsound/spu.c

index 1caec4b..acebaae 100644 (file)
@@ -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; }
index 7e8e5c3..1980ef5 100644 (file)
@@ -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 */
index cb95cb1..89e2bd6 100644 (file)
@@ -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,
 };
 
index 57078ba..e6d8a11 100644 (file)
@@ -88,6 +88,7 @@ SPUreadDMAMem         SPU_readDMAMem;
 SPUplayADPCMchannel   SPU_playADPCMchannel;\r
 SPUfreeze             SPU_freeze;\r
 SPUregisterCallback   SPU_registerCallback;\r
+SPUregisterScheduleCb SPU_registerScheduleCb;\r
 SPUasync              SPU_async;\r
 SPUplayCDDAchannel    SPU_playCDDAchannel;\r
 \r
@@ -320,6 +321,7 @@ void *hSPUDriver = NULL;
 long CALLBACK SPU__configure(void) { return 0; }\r
 void CALLBACK SPU__about(void) {}\r
 long CALLBACK SPU__test(void) { return 0; }\r
+void CALLBACK SPU__registerScheduleCb(void (CALLBACK *cb)(unsigned int)) {}\r
 \r
 #define LoadSpuSym1(dest, name) \\r
        LoadSym(SPU_##dest, SPU##dest, name, TRUE);\r
@@ -356,6 +358,7 @@ static int LoadSPUplugin(const char *SPUdll) {
        LoadSpuSym1(playADPCMchannel, "SPUplayADPCMchannel");\r
        LoadSpuSym1(freeze, "SPUfreeze");\r
        LoadSpuSym1(registerCallback, "SPUregisterCallback");\r
+       LoadSpuSym0(registerScheduleCb, "SPUregisterScheduleCb");\r
        LoadSpuSymN(async, "SPUasync");\r
        LoadSpuSymN(playCDDAchannel, "SPUplayCDDAchannel");\r
 \r
index dfa8722..9df55bf 100644 (file)
@@ -192,6 +192,7 @@ typedef void (CALLBACK* SPUwriteDMAMem)(unsigned short *, int);
 typedef void (CALLBACK* SPUreadDMAMem)(unsigned short *, int);\r
 typedef void (CALLBACK* SPUplayADPCMchannel)(xa_decode_t *);\r
 typedef void (CALLBACK* SPUregisterCallback)(void (CALLBACK *callback)(void));\r
+typedef void (CALLBACK* SPUregisterScheduleCb)(void (CALLBACK *callback)(unsigned int cycles_after));\r
 typedef long (CALLBACK* SPUconfigure)(void);\r
 typedef long (CALLBACK* SPUtest)(void);\r
 typedef void (CALLBACK* SPUabout)(void);\r
@@ -226,6 +227,7 @@ extern SPUreadDMAMem       SPU_readDMAMem;
 extern SPUplayADPCMchannel SPU_playADPCMchannel;\r
 extern SPUfreeze           SPU_freeze;\r
 extern SPUregisterCallback SPU_registerCallback;\r
+extern SPUregisterScheduleCb SPU_registerScheduleCb;\r
 extern SPUasync            SPU_async;\r
 extern SPUplayCDDAchannel  SPU_playCDDAchannel;\r
 \r
index f5996ac..82eb885 100644 (file)
@@ -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)) {
index 13aaa59..a6a6254 100644 (file)
@@ -160,6 +160,7 @@ enum {
        PSXINT_RCNT,
        PSXINT_CDRLID,
        PSXINT_CDRPLAY,
+       PSXINT_SPU_UPDATE,
        PSXINT_COUNT
 };
 
index a60c047..f23051e 100644 (file)
 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);
+}
index 85010cb..44a35d5 100644 (file)
@@ -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
 }
index 8f6ed13..7d3f1a0 100644 (file)
@@ -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)