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; }
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);
DIRECT_SPU(SPUplayADPCMchannel),
DIRECT_SPU(SPUfreeze),
DIRECT_SPU(SPUregisterCallback),
+ DIRECT_SPU(SPUregisterScheduleCb),
DIRECT_SPU(SPUasync),
DIRECT_SPU(SPUplayCDDAchannel),
/* PAD */
[PSXINT_CDRDMA] = cdrDmaInterrupt,
[PSXINT_CDRLID] = cdrLidSeekInterrupt,
[PSXINT_CDRPLAY] = cdrPlayInterrupt,
+ [PSXINT_SPU_UPDATE] = spuUpdate,
[PSXINT_RCNT] = psxRcntUpdate,
};
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
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
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
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
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
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)) {
PSXINT_RCNT,
PSXINT_CDRLID,
PSXINT_CDRPLAY,
+ PSXINT_SPU_UPDATE,
PSXINT_COUNT
};
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);
+}
#define H_SPUoff2 0x0d8e
void CALLBACK SPUirq(void);
+void CALLBACK SPUschedule(unsigned int cycles_after);
+void spuUpdate();
#ifdef __cplusplus
}
cddavCallback = CDDAVcallback;
}
+void CALLBACK SPUregisterScheduleCb(void (CALLBACK *callback)(unsigned int))
+{
+}
+
// COMMON PLUGIN INFO FUNCS
/*
char * CALLBACK PSEgetLibName(void)