aboutsummaryrefslogtreecommitdiff
path: root/plugins/dfsound/freeze.c
diff options
context:
space:
mode:
authorTwinaphex2014-12-20 20:43:18 +0100
committerTwinaphex2014-12-20 20:43:18 +0100
commit247fc699be6b3bd95fd9126541e0804cc8dffdd4 (patch)
treed38e169e68e48a3ccbf8a3805f9cb87197ed894a /plugins/dfsound/freeze.c
parent3e5b01fcef8ef20dacca45ea7a7b0c461e6bd666 (diff)
parent7931825ed8ef51dab3e37475d8126103ebc9fb6f (diff)
downloadpcsx_rearmed-247fc699be6b3bd95fd9126541e0804cc8dffdd4.tar.gz
pcsx_rearmed-247fc699be6b3bd95fd9126541e0804cc8dffdd4.tar.bz2
pcsx_rearmed-247fc699be6b3bd95fd9126541e0804cc8dffdd4.zip
Merge pull request #11 from notaz/upstream_merge
Upstream merge
Diffstat (limited to 'plugins/dfsound/freeze.c')
-rw-r--r--plugins/dfsound/freeze.c103
1 files changed, 56 insertions, 47 deletions
diff --git a/plugins/dfsound/freeze.c b/plugins/dfsound/freeze.c
index 0601bf5..b865b84 100644
--- a/plugins/dfsound/freeze.c
+++ b/plugins/dfsound/freeze.c
@@ -132,16 +132,14 @@ typedef struct
////////////////////////////////////////////////////////////////////////
void LoadStateV5(SPUFreeze_t * pF); // newest version
-void LoadStateUnknown(SPUFreeze_t * pF); // unknown format
-
-extern int lastch;
+void LoadStateUnknown(SPUFreeze_t * pF, uint32_t cycles); // unknown format
// we want to retain compatibility between versions,
// so use original channel struct
static void save_channel(SPUCHAN_orig *d, const SPUCHAN *s, int ch)
{
memset(d, 0, sizeof(*d));
- d->bNew = !!(dwNewChannel & (1<<ch));
+ d->bNew = !!(spu.dwNewChannel & (1<<ch));
d->iSBPos = s->iSBPos;
d->spos = s->spos;
d->sinc = s->sinc;
@@ -149,7 +147,7 @@ static void save_channel(SPUCHAN_orig *d, const SPUCHAN *s, int ch)
d->iStart = (regAreaGet(ch,6)&~1)<<3;
d->iCurr = 0; // set by the caller
d->iLoop = 0; // set by the caller
- d->bOn = !!(dwChannelOn & (1<<ch));
+ d->bOn = !!(spu.dwChannelOn & (1<<ch));
d->bStop = s->bStop;
d->bReverb = s->bReverb;
d->iActFreq = 1;
@@ -181,10 +179,12 @@ static void save_channel(SPUCHAN_orig *d, const SPUCHAN *s, int ch)
static void load_channel(SPUCHAN *d, const SPUCHAN_orig *s, int ch)
{
memset(d, 0, sizeof(*d));
- if (s->bNew) dwNewChannel |= 1<<ch;
+ if (s->bNew) spu.dwNewChannel |= 1<<ch;
d->iSBPos = s->iSBPos;
+ if ((uint32_t)d->iSBPos >= 28) d->iSBPos = 27;
d->spos = s->spos;
d->sinc = s->sinc;
+ d->sinc_inv = 0;
memcpy(d->SB, s->SB, sizeof(d->SB));
d->pCurr = (void *)((long)s->iCurr & 0x7fff0);
d->pLoop = (void *)((long)s->iLoop & 0x7fff0);
@@ -208,15 +208,24 @@ static void load_channel(SPUCHAN *d, const SPUCHAN_orig *s, int ch)
d->ADSRX.ReleaseModeExp = s->ADSRX.ReleaseModeExp;
d->ADSRX.ReleaseRate = s->ADSRX.ReleaseRate;
d->ADSRX.EnvelopeVol = s->ADSRX.EnvelopeVol;
- if (s->bOn) dwChannelOn |= 1<<ch;
+ if (s->bOn) spu.dwChannelOn |= 1<<ch;
else d->ADSRX.EnvelopeVol = 0;
}
+// force load from regArea to variables
+static void load_register(unsigned long reg, unsigned int cycles)
+{
+ unsigned short *r = &spu.regArea[((reg & 0xfff) - 0xc00) >> 1];
+ *r ^= 1;
+ SPUwriteRegister(reg, *r ^ 1, cycles);
+}
+
////////////////////////////////////////////////////////////////////////
// SPUFREEZE: called by main emu on savestate load/save
////////////////////////////////////////////////////////////////////////
-long CALLBACK SPUfreeze(uint32_t ulFreezeMode,SPUFreeze_t * pF)
+long CALLBACK SPUfreeze(uint32_t ulFreezeMode, SPUFreeze_t * pF,
+ uint32_t cycles)
{
int i;SPUOSSFreeze_t * pFO;
@@ -233,31 +242,33 @@ long CALLBACK SPUfreeze(uint32_t ulFreezeMode,SPUFreeze_t * pF)
if(ulFreezeMode==2) return 1; // info mode? ok, bye
// save mode:
- memcpy(pF->cSPURam,spuMem,0x80000); // copy common infos
- memcpy(pF->cSPUPort,regArea,0x200);
+ do_samples(cycles);
+
+ memcpy(pF->cSPURam,spu.spuMem,0x80000); // copy common infos
+ memcpy(pF->cSPUPort,spu.regArea,0x200);
- if(xapGlobal && XAPlay!=XAFeed) // some xa
+ if(spu.xapGlobal && spu.XAPlay!=spu.XAFeed) // some xa
{
- pF->xaS=*xapGlobal;
+ pF->xaS=*spu.xapGlobal;
}
else
memset(&pF->xaS,0,sizeof(xa_decode_t)); // or clean xa
pFO=(SPUOSSFreeze_t *)(pF+1); // store special stuff
- pFO->spuIrq=spuIrq;
- if(pSpuIrq) pFO->pSpuIrq = (unsigned long)pSpuIrq-(unsigned long)spuMemC;
+ pFO->spuIrq = spu.regArea[(H_SPUirqAddr - 0x0c00) / 2];
+ if(spu.pSpuIrq) pFO->pSpuIrq = (unsigned long)spu.pSpuIrq-(unsigned long)spu.spuMemC;
- pFO->spuAddr=spuAddr;
+ pFO->spuAddr=spu.spuAddr;
if(pFO->spuAddr==0) pFO->spuAddr=0xbaadf00d;
for(i=0;i<MAXCHAN;i++)
{
save_channel(&pFO->s_chan[i],&s_chan[i],i);
if(s_chan[i].pCurr)
- pFO->s_chan[i].iCurr=s_chan[i].pCurr-spuMemC;
+ pFO->s_chan[i].iCurr=s_chan[i].pCurr-spu.spuMemC;
if(s_chan[i].pLoop)
- pFO->s_chan[i].iLoop=s_chan[i].pLoop-spuMemC;
+ pFO->s_chan[i].iLoop=s_chan[i].pLoop-spu.spuMemC;
}
return 1;
@@ -266,36 +277,35 @@ long CALLBACK SPUfreeze(uint32_t ulFreezeMode,SPUFreeze_t * pF)
if(ulFreezeMode!=0) return 0; // bad mode? bye
- memcpy(spuMem,pF->cSPURam,0x80000); // get ram
- memcpy(regArea,pF->cSPUPort,0x200);
+ memcpy(spu.spuMem,pF->cSPURam,0x80000); // get ram
+ memcpy(spu.regArea,pF->cSPUPort,0x200);
if(pF->xaS.nsamples<=4032) // start xa again
SPUplayADPCMchannel(&pF->xaS);
- xapGlobal=0;
+ spu.xapGlobal=0;
if(!strcmp(pF->szSPUName,"PBOSS") && pF->ulFreezeVersion==5)
LoadStateV5(pF);
- else LoadStateUnknown(pF);
-
- lastch = -1;
+ else LoadStateUnknown(pF, cycles);
// repair some globals
for(i=0;i<=62;i+=2)
- SPUwriteRegister(H_Reverb+i,regArea[(H_Reverb+i-0xc00)>>1]);
- SPUwriteRegister(H_SPUReverbAddr,regArea[(H_SPUReverbAddr-0xc00)>>1]);
- SPUwriteRegister(H_SPUrvolL,regArea[(H_SPUrvolL-0xc00)>>1]);
- SPUwriteRegister(H_SPUrvolR,regArea[(H_SPUrvolR-0xc00)>>1]);
+ load_register(H_Reverb+i, cycles);
+ load_register(H_SPUReverbAddr, cycles);
+ load_register(H_SPUrvolL, cycles);
+ load_register(H_SPUrvolR, cycles);
- SPUwriteRegister(H_SPUctrl,(unsigned short)(regArea[(H_SPUctrl-0xc00)>>1]|0x4000));
- SPUwriteRegister(H_SPUstat,regArea[(H_SPUstat-0xc00)>>1]);
- SPUwriteRegister(H_CDLeft,regArea[(H_CDLeft-0xc00)>>1]);
- SPUwriteRegister(H_CDRight,regArea[(H_CDRight-0xc00)>>1]);
+ load_register(H_SPUctrl, cycles);
+ load_register(H_SPUstat, cycles);
+ load_register(H_CDLeft, cycles);
+ load_register(H_CDRight, cycles);
// fix to prevent new interpolations from crashing
for(i=0;i<MAXCHAN;i++) s_chan[i].SB[28]=0;
ClearWorkingState();
+ spu.cycles_played = cycles;
return 1;
}
@@ -308,47 +318,46 @@ void LoadStateV5(SPUFreeze_t * pF)
pFO=(SPUOSSFreeze_t *)(pF+1);
- spuIrq = pFO->spuIrq;
- if(pFO->pSpuIrq) pSpuIrq = spuMemC+((long)pFO->pSpuIrq&0x7fff0); else pSpuIrq=NULL;
+ if(pFO->pSpuIrq) spu.pSpuIrq = spu.spuMemC+((long)pFO->pSpuIrq&0x7fff0); else spu.pSpuIrq=NULL;
if(pFO->spuAddr)
{
- spuAddr = pFO->spuAddr;
- if (spuAddr == 0xbaadf00d) spuAddr = 0;
+ spu.spuAddr = pFO->spuAddr;
+ if (spu.spuAddr == 0xbaadf00d) spu.spuAddr = 0;
}
- dwNewChannel=0;
- dwChannelOn=0;
- dwChannelDead=0;
+ spu.dwNewChannel=0;
+ spu.dwChannelOn=0;
+ spu.dwChannelDead=0;
for(i=0;i<MAXCHAN;i++)
{
load_channel(&s_chan[i],&pFO->s_chan[i],i);
- s_chan[i].pCurr+=(unsigned long)spuMemC;
- s_chan[i].pLoop+=(unsigned long)spuMemC;
+ s_chan[i].pCurr+=(unsigned long)spu.spuMemC;
+ s_chan[i].pLoop+=(unsigned long)spu.spuMemC;
}
}
////////////////////////////////////////////////////////////////////////
-void LoadStateUnknown(SPUFreeze_t * pF)
+void LoadStateUnknown(SPUFreeze_t * pF, uint32_t cycles)
{
int i;
for(i=0;i<MAXCHAN;i++)
{
s_chan[i].bStop=0;
- s_chan[i].pLoop=spuMemC;
+ s_chan[i].pLoop=spu.spuMemC;
}
- dwNewChannel=0;
- dwChannelOn=0;
- dwChannelDead=0;
- pSpuIrq=0;
+ spu.dwNewChannel=0;
+ spu.dwChannelOn=0;
+ spu.dwChannelDead=0;
+ spu.pSpuIrq=0;
for(i=0;i<0xc0;i++)
{
- SPUwriteRegister(0x1f801c00+i*2,regArea[i]);
+ load_register(0x1f801c00 + i*2, cycles);
}
}