From 20ed712f92d53fa7d51a4b805af997f5770077ae Mon Sep 17 00:00:00 2001 From: notaz Date: Thu, 16 Nov 2023 21:07:21 +0200 Subject: [PATCH] spu: patch up more savestate issues notaz/pcsx_rearmed#329 --- plugins/dfsound/freeze.c | 36 +++++++++++++++++++++++++++++++++--- plugins/dfsound/registers.c | 3 ++- plugins/dfsound/reverb.c | 2 +- plugins/dfsound/spu.c | 4 ++-- plugins/dfsound/xa.c | 4 +++- 5 files changed, 41 insertions(+), 8 deletions(-) diff --git a/plugins/dfsound/freeze.c b/plugins/dfsound/freeze.c index 8816a51c..32c07dbd 100644 --- a/plugins/dfsound/freeze.c +++ b/plugins/dfsound/freeze.c @@ -130,6 +130,14 @@ typedef struct SPUCHAN_orig s_chan[MAXCHAN]; + uint32_t cycles_dma_end; + uint32_t decode_dirty_ch; + uint32_t dwNoiseVal; + uint32_t dwNoiseCount; + uint32_t XARepeat; + uint32_t XALastVal; + uint32_t last_keyon_cycles; + } SPUOSSFreeze_t; //////////////////////////////////////////////////////////////////////// @@ -250,6 +258,8 @@ long CALLBACK SPUfreeze(uint32_t ulFreezeMode, SPUFreeze_t * pF, if(ulFreezeMode==2) return 1; // info mode? ok, bye // save mode: + regAreaGet(H_SPUctrl) = spu.spuCtrl; + regAreaGet(H_SPUstat) = spu.spuStat; memcpy(pF->cSPURam,spu.spuMem,0x80000); // copy common infos memcpy(pF->cSPUPort,spu.regArea,0x200); @@ -312,6 +322,8 @@ long CALLBACK SPUfreeze(uint32_t ulFreezeMode, SPUFreeze_t * pF, memcpy(spu.spuMem,pF->cSPURam,0x80000); // get ram memcpy(spu.regArea,pF->cSPUPort,0x200); spu.bMemDirty = 1; + spu.spuCtrl = regAreaGet(H_SPUctrl); + spu.spuStat = regAreaGet(H_SPUstat); if (!strcmp(pF->szSPUName,"PBOSS") && pF->ulFreezeVersion==5) pFO = LoadStateV5(pF, cycles); @@ -329,18 +341,35 @@ long CALLBACK SPUfreeze(uint32_t ulFreezeMode, SPUFreeze_t * pF, FeedCDDA((void *)pF->xaS.pcm, pFO->cdda_left * 4); } + // not in old savestates + spu.cycles_dma_end = 0; + spu.decode_dirty_ch = spu.dwChannelsAudible & 0x0a; + spu.dwNoiseVal = 0; + spu.dwNoiseCount = 0; + spu.XARepeat = 0; + spu.XALastVal = 0; + spu.last_keyon_cycles = cycles - 16*786u; + if (pFO && pF->ulFreezeSize >= sizeof(*pF) + sizeof(*pFO)) { + spu.cycles_dma_end = pFO->cycles_dma_end; + spu.decode_dirty_ch = pFO->decode_dirty_ch; + spu.dwNoiseVal = pFO->dwNoiseVal; + spu.dwNoiseCount = pFO->dwNoiseCount; + spu.XARepeat = pFO->XARepeat; + spu.XALastVal = pFO->XALastVal; + spu.last_keyon_cycles = pFO->last_keyon_cycles; + } + // repair some globals for(i=0;i<=62;i+=2) load_register(H_Reverb+i, cycles); load_register(H_SPUReverbAddr, cycles); load_register(H_SPUrvolL, cycles); load_register(H_SPUrvolR, cycles); - - load_register(H_SPUctrl, cycles); - load_register(H_SPUstat, cycles); load_register(H_CDLeft, cycles); load_register(H_CDRight, cycles); + // reverb + spu.rvb->StartAddr = regAreaGet(H_SPUReverbAddr) << 2; if (spu.rvb->CurrAddr < spu.rvb->StartAddr) spu.rvb->CurrAddr = spu.rvb->StartAddr; // fix to prevent new interpolations from crashing @@ -383,6 +412,7 @@ static SPUOSSFreeze_t * LoadStateV5(SPUFreeze_t * pF, uint32_t cycles) spu.s_chan[i].pCurr+=(uintptr_t)spu.spuMemC; spu.s_chan[i].pLoop+=(uintptr_t)spu.spuMemC; } + return pFO; } diff --git a/plugins/dfsound/registers.c b/plugins/dfsound/registers.c index 5d79f251..1e79c0e6 100644 --- a/plugins/dfsound/registers.c +++ b/plugins/dfsound/registers.c @@ -144,6 +144,7 @@ void CALLBACK SPUwriteRegister(unsigned long reg, unsigned short val, break; //-------------------------------------------------// case H_SPUctrl: + spu.spuStat = (spu.spuStat & ~0x3f) | (val & 0x3f); spu.spuStat &= ~STAT_IRQ | val; if (!(spu.spuCtrl & CTRL_IRQ)) { if (val & CTRL_IRQ) @@ -365,7 +366,7 @@ unsigned short CALLBACK SPUreadRegister(unsigned long reg, unsigned int cycles) return spu.spuCtrl; case H_SPUstat: - return (spu.spuStat & ~0x3F) | (spu.spuCtrl & 0x3F); + return spu.spuStat; case H_SPUaddr: return (unsigned short)(spu.spuAddr>>3); diff --git a/plugins/dfsound/reverb.c b/plugins/dfsound/reverb.c index de9b804a..c0ecea1d 100644 --- a/plugins/dfsound/reverb.c +++ b/plugins/dfsound/reverb.c @@ -177,7 +177,7 @@ static void REVERBPrep(void) REVERBInfo *rvb = spu.rvb; int space, t; - t = spu.regArea[(H_SPUReverbAddr - 0xc00) >> 1]; + t = regAreaGet(H_SPUReverbAddr); if (t == 0xFFFF || t <= 0x200) spu.rvb->StartAddr = spu.rvb->CurrAddr = 0; else if (spu.rvb->StartAddr != (t << 2)) diff --git a/plugins/dfsound/spu.c b/plugins/dfsound/spu.c index f2023881..7501df8b 100644 --- a/plugins/dfsound/spu.c +++ b/plugins/dfsound/spu.c @@ -1147,7 +1147,7 @@ void do_samples(unsigned int cycles_to, int do_direct) cycle_diff = cycles_to - spu.cycles_played; if (cycle_diff < -2*1048576 || cycle_diff > 2*1048576) { - //xprintf("desync %u %d\n", cycles_to, cycle_diff); + log_unhandled("desync %u %d\n", cycles_to, cycle_diff); spu.cycles_played = cycles_to; return; } @@ -1164,7 +1164,7 @@ void do_samples(unsigned int cycles_to, int do_direct) ns_to = (cycle_diff / 768 + 1) & ~1; if (ns_to > NSSIZE) { // should never happen - //xprintf("ns_to oflow %d %d\n", ns_to, NSSIZE); + log_unhandled("ns_to oflow %d %d\n", ns_to, NSSIZE); ns_to = NSSIZE; } diff --git a/plugins/dfsound/xa.c b/plugins/dfsound/xa.c index 08afc009..b3ac01d9 100644 --- a/plugins/dfsound/xa.c +++ b/plugins/dfsound/xa.c @@ -413,8 +413,10 @@ void FeedCDDA(unsigned char *pcm, int nBytes) { int space; space=(spu.CDDAPlay-spu.CDDAFeed-1)*4 & (CDDA_BUFFER_SIZE - 1); - if(space0) { -- 2.39.2