aboutsummaryrefslogtreecommitdiff
path: root/plugins/dfsound
diff options
context:
space:
mode:
authornotaz2012-07-06 20:25:51 +0300
committernotaz2012-07-09 02:35:59 +0300
commitfb552464f06137102fd9ca69a05492265bbdcea7 (patch)
tree5c9fd1c37051384bce15f58c0c3c636f0baefcc3 /plugins/dfsound
parentf8edb5bc279ba09aa7bc762da51236fd368827b0 (diff)
downloadpcsx_rearmed-fb552464f06137102fd9ca69a05492265bbdcea7.tar.gz
pcsx_rearmed-fb552464f06137102fd9ca69a05492265bbdcea7.tar.bz2
pcsx_rearmed-fb552464f06137102fd9ca69a05492265bbdcea7.zip
spu: get rid of iSpuAsyncWait hack
..and replace with some different dma detection hack
Diffstat (limited to 'plugins/dfsound')
-rw-r--r--plugins/dfsound/dma.c19
-rw-r--r--plugins/dfsound/externals.h4
-rw-r--r--plugins/dfsound/registers.c5
-rw-r--r--plugins/dfsound/spu.c39
4 files changed, 38 insertions, 29 deletions
diff --git a/plugins/dfsound/dma.c b/plugins/dfsound/dma.c
index f92d066..7c164ac 100644
--- a/plugins/dfsound/dma.c
+++ b/plugins/dfsound/dma.c
@@ -31,8 +31,6 @@ unsigned short CALLBACK SPUreadDMA(void)
spuAddr+=2;
if(spuAddr>0x7ffff) spuAddr=0;
- iSpuAsyncWait=0;
-
return s;
}
@@ -50,8 +48,6 @@ void CALLBACK SPUreadDMAMem(unsigned short * pusPSXMem,int iSize)
spuAddr+=2; // inc spu addr
if(spuAddr>0x7ffff) spuAddr=0; // wrap
}
-
- iSpuAsyncWait=0;
}
////////////////////////////////////////////////////////////////////////
@@ -72,8 +68,6 @@ void CALLBACK SPUwriteDMA(unsigned short val)
spuAddr+=2; // inc spu addr
if(spuAddr>0x7ffff) spuAddr=0; // wrap
-
- iSpuAsyncWait=0;
}
////////////////////////////////////////////////////////////////////////
@@ -83,15 +77,22 @@ void CALLBACK SPUwriteDMA(unsigned short val)
void CALLBACK SPUwriteDMAMem(unsigned short * pusPSXMem,int iSize)
{
int i;
+
+ had_dma = 1;
+
+ if(spuAddr + iSize*2 < 0x80000)
+ {
+ memcpy(&spuMem[spuAddr>>1], pusPSXMem, iSize*2);
+ spuAddr += iSize*2;
+ return;
+ }
for(i=0;i<iSize;i++)
{
spuMem[spuAddr>>1] = *pusPSXMem++; // spu addr got by writeregister
spuAddr+=2; // inc spu addr
- if(spuAddr>0x7ffff) spuAddr=0; // wrap
+ spuAddr&=0x7ffff; // wrap
}
-
- iSpuAsyncWait=0;
}
////////////////////////////////////////////////////////////////////////
diff --git a/plugins/dfsound/externals.h b/plugins/dfsound/externals.h
index bdf5956..dd582ff 100644
--- a/plugins/dfsound/externals.h
+++ b/plugins/dfsound/externals.h
@@ -38,7 +38,7 @@
// num of channels
#define MAXCHAN 24
-// ~ 1 ms of data
+// ~ FRAG_MSECS ms of data
// note: must be even due to the way reverb works now
#define FRAG_MSECS 2
#define NSSIZE ((44100 * FRAG_MSECS / 1000 + 1) & ~1)
@@ -204,7 +204,7 @@ extern int iUseReverb;
extern int iUseInterpolation;
// MISC
-extern int iSpuAsyncWait;
+extern int had_dma;
extern SPUCHAN s_chan[];
extern REVERBInfo rvb;
diff --git a/plugins/dfsound/registers.c b/plugins/dfsound/registers.c
index 669c70f..1a51cd7 100644
--- a/plugins/dfsound/registers.c
+++ b/plugins/dfsound/registers.c
@@ -180,7 +180,6 @@ void CALLBACK SPUwriteRegister(unsigned long reg, unsigned short val)
break;
//------------------------------------------------//
}
- iSpuAsyncWait=0;
return;
}
@@ -347,8 +346,6 @@ void CALLBACK SPUwriteRegister(unsigned long reg, unsigned short val)
if ((r & ~0x3f) == H_Reverb)
rvb.dirty = 1; // recalculate on next update
-
- iSpuAsyncWait=0;
}
////////////////////////////////////////////////////////////////////////
@@ -359,8 +356,6 @@ unsigned short CALLBACK SPUreadRegister(unsigned long reg)
{
const unsigned long r=reg&0xfff;
- iSpuAsyncWait=0;
-
if(r>=0x0c00 && r<0x0d80)
{
switch(r&0x0f)
diff --git a/plugins/dfsound/spu.c b/plugins/dfsound/spu.c
index b087cdf..4930e53 100644
--- a/plugins/dfsound/spu.c
+++ b/plugins/dfsound/spu.c
@@ -46,6 +46,8 @@
} while (0)
#endif
+#define PSXCLK 33868800 /* 33.8688 MHz */
+
/*
#if defined (USEMACOSX)
static char * libraryName = N_("Mac OS X Sound");
@@ -92,7 +94,6 @@ REVERBInfo rvb;
unsigned int dwNoiseVal; // global noise generator
unsigned int dwNoiseCount;
-int iSpuAsyncWait=0;
unsigned short spuCtrl=0; // some vars to store psx reg infos
unsigned short spuStat=0;
@@ -122,8 +123,10 @@ int iFMod[NSSIZE];
int iCycle = 0;
short * pS;
+int had_dma;
int lastch=-1; // last channel processed on spu irq in timer mode
static int lastns=0; // last ns pos
+static int cycles_since_update;
#define CDDA_BUFFER_SIZE (16384 * sizeof(uint32_t)) // must be power of 2
@@ -665,7 +668,7 @@ static void mix_chan_rvb(int start, int count, int lv, int rv)
// basically the whole sound processing is done in this fat func!
////////////////////////////////////////////////////////////////////////
-static int do_samples(void)
+static int do_samples(int forced_updates)
{
int volmult = iVolume;
int ns,ns_from,ns_to;
@@ -681,11 +684,15 @@ static int do_samples(void)
// until enuff free place is available/a new channel gets
// started
- if(!dwNewChannel && SoundGetBytesBuffered()) // still enuff data in sound buffer?
+ if(!forced_updates && SoundGetBytesBuffered()) // still enuff data in sound buffer?
{
return 0;
}
+ cycles_since_update = 0;
+ if(forced_updates > 0)
+ forced_updates--;
+
//--------------------------------------------------// continue from irq handling in timer mode?
ns_from=0;
@@ -751,7 +758,7 @@ static int do_samples(void)
unsigned char *start = s_chan[ch].pCurr;
// no need for bIRQReturn since the channel is silent
- iSpuAsyncWait |= skip_block(ch);
+ skip_block(ch);
if(start == s_chan[ch].pCurr)
{
// looping on self
@@ -765,11 +772,7 @@ static int do_samples(void)
}
if(bIRQReturn && iSPUIRQWait) // special return for "spu irq - wait for cpu action"
- {
- iSpuAsyncWait=1;
- bIRQReturn=0;
return 0;
- }
//---------------------------------------------------//
@@ -863,16 +866,26 @@ static int do_samples(void)
void CALLBACK SPUasync(unsigned long cycle)
{
+ int forced_updates = 0;
+ int do_update = 0;
+
if(!bSpuInit) return; // -> no init, no call
- if(iSpuAsyncWait)
+ cycles_since_update += cycle;
+
+ if(dwNewChannel || had_dma)
{
- iSpuAsyncWait++;
- if(iSpuAsyncWait<=16/FRAG_MSECS) return;
- iSpuAsyncWait=0;
+ forced_updates = 1;
+ do_update = 1;
+ had_dma = 0;
}
- do_samples();
+ // once per frame should be fine (using a bit more because of BIAS)
+ if(cycles_since_update > PSXCLK/60 * 5/4)
+ do_update = 1;
+
+ if(do_update)
+ do_samples(forced_updates);
}
// SPU UPDATE... new epsxe func