..and replace with some different dma detection hack
spuAddr+=2;\r
if(spuAddr>0x7ffff) spuAddr=0;\r
\r
spuAddr+=2;\r
if(spuAddr>0x7ffff) spuAddr=0;\r
\r
spuAddr+=2; // inc spu addr\r
if(spuAddr>0x7ffff) spuAddr=0; // wrap\r
}\r
spuAddr+=2; // inc spu addr\r
if(spuAddr>0x7ffff) spuAddr=0; // wrap\r
}\r
}\r
\r
////////////////////////////////////////////////////////////////////////\r
}\r
\r
////////////////////////////////////////////////////////////////////////\r
\r
spuAddr+=2; // inc spu addr\r
if(spuAddr>0x7ffff) spuAddr=0; // wrap\r
\r
spuAddr+=2; // inc spu addr\r
if(spuAddr>0x7ffff) spuAddr=0; // wrap\r
}\r
\r
////////////////////////////////////////////////////////////////////////\r
}\r
\r
////////////////////////////////////////////////////////////////////////\r
void CALLBACK SPUwriteDMAMem(unsigned short * pusPSXMem,int iSize)\r
{\r
int i;\r
void CALLBACK SPUwriteDMAMem(unsigned short * pusPSXMem,int iSize)\r
{\r
int i;\r
+ \r
+ had_dma = 1;\r
+\r
+ if(spuAddr + iSize*2 < 0x80000)\r
+ {\r
+ memcpy(&spuMem[spuAddr>>1], pusPSXMem, iSize*2);\r
+ spuAddr += iSize*2;\r
+ return;\r
+ }\r
\r
for(i=0;i<iSize;i++)\r
{\r
spuMem[spuAddr>>1] = *pusPSXMem++; // spu addr got by writeregister\r
spuAddr+=2; // inc spu addr\r
\r
for(i=0;i<iSize;i++)\r
{\r
spuMem[spuAddr>>1] = *pusPSXMem++; // spu addr got by writeregister\r
spuAddr+=2; // inc spu addr\r
- if(spuAddr>0x7ffff) spuAddr=0; // wrap\r
+ spuAddr&=0x7ffff; // wrap\r
- \r
- iSpuAsyncWait=0;\r
}\r
\r
////////////////////////////////////////////////////////////////////////\r
}\r
\r
////////////////////////////////////////////////////////////////////////\r
// num of channels\r
#define MAXCHAN 24\r
\r
// num of channels\r
#define MAXCHAN 24\r
\r
+// ~ FRAG_MSECS ms of data\r
// note: must be even due to the way reverb works now\r
#define FRAG_MSECS 2\r
#define NSSIZE ((44100 * FRAG_MSECS / 1000 + 1) & ~1)\r
// note: must be even due to the way reverb works now\r
#define FRAG_MSECS 2\r
#define NSSIZE ((44100 * FRAG_MSECS / 1000 + 1) & ~1)\r
extern int iUseInterpolation;\r
// MISC\r
\r
extern int iUseInterpolation;\r
// MISC\r
\r
-extern int iSpuAsyncWait;\r
\r
extern SPUCHAN s_chan[];\r
extern REVERBInfo rvb;\r
\r
extern SPUCHAN s_chan[];\r
extern REVERBInfo rvb;\r
break;\r
//------------------------------------------------//\r
}\r
break;\r
//------------------------------------------------//\r
}\r
\r
if ((r & ~0x3f) == H_Reverb)\r
rvb.dirty = 1; // recalculate on next update\r
\r
if ((r & ~0x3f) == H_Reverb)\r
rvb.dirty = 1; // recalculate on next update\r
}\r
\r
////////////////////////////////////////////////////////////////////////\r
}\r
\r
////////////////////////////////////////////////////////////////////////\r
{\r
const unsigned long r=reg&0xfff;\r
\r
{\r
const unsigned long r=reg&0xfff;\r
\r
if(r>=0x0c00 && r<0x0d80)\r
{\r
switch(r&0x0f)\r
if(r>=0x0c00 && r<0x0d80)\r
{\r
switch(r&0x0f)\r
+#define PSXCLK 33868800 /* 33.8688 MHz */
+
/*
#if defined (USEMACOSX)
static char * libraryName = N_("Mac OS X Sound");
/*
#if defined (USEMACOSX)
static char * libraryName = N_("Mac OS X Sound");
unsigned int dwNoiseVal; // global noise generator
unsigned int dwNoiseCount;
unsigned int dwNoiseVal; // global noise generator
unsigned int dwNoiseCount;
unsigned short spuCtrl=0; // some vars to store psx reg infos
unsigned short spuStat=0;
unsigned short spuCtrl=0; // some vars to store psx reg infos
unsigned short spuStat=0;
int iCycle = 0;
short * pS;
int iCycle = 0;
short * pS;
int lastch=-1; // last channel processed on spu irq in timer mode
static int lastns=0; // last ns pos
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
#define CDDA_BUFFER_SIZE (16384 * sizeof(uint32_t)) // must be power of 2
// basically the whole sound processing is done in this fat func!
////////////////////////////////////////////////////////////////////////
// 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;
{
int volmult = iVolume;
int ns,ns_from,ns_to;
// until enuff free place is available/a new channel gets
// started
// 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?
+ cycles_since_update = 0;
+ if(forced_updates > 0)
+ forced_updates--;
+
//--------------------------------------------------// continue from irq handling in timer mode?
ns_from=0;
//--------------------------------------------------// continue from irq handling in timer mode?
ns_from=0;
unsigned char *start = s_chan[ch].pCurr;
// no need for bIRQReturn since the channel is silent
unsigned char *start = s_chan[ch].pCurr;
// no need for bIRQReturn since the channel is silent
- iSpuAsyncWait |= skip_block(ch);
if(start == s_chan[ch].pCurr)
{
// looping on self
if(start == s_chan[ch].pCurr)
{
// looping on self
}
if(bIRQReturn && iSPUIRQWait) // special return for "spu irq - wait for cpu action"
}
if(bIRQReturn && iSPUIRQWait) // special return for "spu irq - wait for cpu action"
- {
- iSpuAsyncWait=1;
- bIRQReturn=0;
//---------------------------------------------------//
//---------------------------------------------------//
void CALLBACK SPUasync(unsigned long cycle)
{
void CALLBACK SPUasync(unsigned long cycle)
{
+ int forced_updates = 0;
+ int do_update = 0;
+
if(!bSpuInit) return; // -> no init, no call
if(!bSpuInit) return; // -> no init, no call
+ 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;
+ // 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
}
// SPU UPDATE... new epsxe func