DSPHLE AX: Restructure GC AX to work in a less insane way. No major change expected, maybe less dropouts due to a smaller window for race conditions..

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3831 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
hrydgard 2009-07-18 09:29:09 +00:00
parent 9bc2e789d3
commit a8731c635b
3 changed files with 80 additions and 124 deletions

View File

@ -941,8 +941,8 @@ void CUCode_AX::Logging(short* _pBuffer, int _iSize, int a, bool Wii)
}
else
{
numberOfPBs = ReadOutPBs(m_addressPBs, PBs, NUMBER_OF_PBS);
Logging_(_pBuffer, _iSize, a, Wii, PBs, numberOfPBs, m_addressPBs);
// numberOfPBs = ReadOutPBs(m_addressPBs, PBs, NUMBER_OF_PBS);
// Logging_(_pBuffer, _iSize, a, Wii, PBs, numberOfPBs, m_addressPBs);
}
}
}

View File

@ -249,94 +249,35 @@ if(m_DebuggerFrame->ScanMails)
}
// ----------------
int ReadOutPBs(u32 pbs_address, AXParamBlock* _pPBs, int _num)
void ReadOutPB(u32 pb_address, AXParamBlock &PB)
{
int count = 0;
u32 blockAddr = pbs_address;
// reading and 'halfword' swap
for (int i = 0; i < _num; i++)
{
const short *pSrc = (const short *)g_dspInitialize.pGetMemoryPointer(blockAddr);
if (pSrc != NULL)
{
short *pDest = (short *)&_pPBs[i];
const u16 *pSrc = (const u16 *)g_dspInitialize.pGetMemoryPointer(pb_address);
u16 *pDest = (u16 *)&PB;
for (int p = 0; p < (int)sizeof(AXParamBlock) / 2; p++)
{
pDest[p] = Common::swap16(pSrc[p]);
#if defined(HAVE_WX) && HAVE_WX
#if defined(_DEBUG) || defined(DEBUGFAST)
if(m_DebuggerFrame) m_DebuggerFrame->gLastBlock = blockAddr + p*2 + 2; // save last block location
#endif
#endif
}
blockAddr = (_pPBs[i].next_pb_hi << 16) | _pPBs[i].next_pb_lo;
count++;
// Detect the last mail by checking when next_pb = 0
u32 next_pb = (Common::swap16(pSrc[0]) << 16) | Common::swap16(pSrc[1]);
if(next_pb == 0) break;
}
else
break;
}
// return the number of read PBs
return count;
}
void WriteBackPBs(u32 pbs_address, AXParamBlock* _pPBs, int _num)
void WriteBackPB(u32 pb_address, AXParamBlock &PB)
{
u32 blockAddr = pbs_address;
// write back and 'halfword'swap
for (int i = 0; i < _num; i++)
{
short* pSrc = (short*)&_pPBs[i];
short* pDest = (short*)g_dspInitialize.pGetMemoryPointer(blockAddr);
const u16 *pSrc = (const u16*)&PB;
u16 *pDest = (u16 *)g_dspInitialize.pGetMemoryPointer(pb_address);
for (size_t p = 0; p < sizeof(AXParamBlock) / 2; p++)
{
pDest[p] = Common::swap16(pSrc[p]);
}
// next block
blockAddr = (_pPBs[i].next_pb_hi << 16) | _pPBs[i].next_pb_lo;
}
}
void CUCode_AX::MixAdd(short* _pBuffer, int _iSize)
void ProcessUpdates(AXParamBlock &PB)
{
AXParamBlock PBs[NUMBER_OF_PBS];
// read out pbs
int numberOfPBs = ReadOutPBs(m_addressPBs, PBs, NUMBER_OF_PBS);
if (_iSize > 1024 * 1024)
_iSize = 1024 * 1024;
memset(templbuffer, 0, _iSize * sizeof(int));
memset(temprbuffer, 0, _iSize * sizeof(int));
#if defined(HAVE_WX) && HAVE_WX
// write logging data to debugger
if (m_DebuggerFrame && _pBuffer)
{
CUCode_AX::Logging(_pBuffer, _iSize, 0, false);
}
#endif
// ---------------------------------------------------------------------------------------
/* Make the updates we are told to do. When there are multiple updates for a block they
are placed in memory directly following updaddr. They are mostly for initial time
delays, sometimes for the FIR filter or channel volumes. We do all of them at once here.
If we get both an on and an off update we chose on. Perhaps that makes the RE1 music
work better. */
// ------------
for (int i = 0; i < numberOfPBs; i++)
{
u16 *pDest = (u16 *)&PBs[i];
u16 *pDest = (u16 *)&PB;
u16 upd0 = pDest[34]; u16 upd1 = pDest[35]; u16 upd2 = pDest[36]; // num_updates
u16 upd3 = pDest[37]; u16 upd4 = pDest[38];
u16 upd_hi = pDest[39]; // update addr
@ -345,23 +286,12 @@ void CUCode_AX::MixAdd(short* _pBuffer, int _iSize)
if (numupd > 64) numupd = 64; // prevent crazy values
const u32 updaddr = (u32)(upd_hi << 16) | upd_lo;
int on = false, off = false;
for (int j = 0; j < numupd; j++)
{
int k = 0;
if(g_Config.m_EnableRE0Fix)
{
k=0;
}
else
{
k=j;
}
int k = g_Config.m_EnableRE0Fix ? 0 : j;
const u16 updpar = Memory_Read_U16(updaddr + k);
const u16 upddata = Memory_Read_U16(updaddr + k + 2);
// some safety checks, I hope it's enough
if(updaddr > 0x80000000 && updaddr < 0x817fffff
&& updpar < 63 && updpar > 3 && upddata >= 0 // updpar > 3 because we don't want to change
@ -380,19 +310,49 @@ void CUCode_AX::MixAdd(short* _pBuffer, int _iSize)
}
}
//PrintFile(1, "%08x %04x %04x\n", updaddr, updpar, upddata);
// ------------
for (int i = 0; i < numberOfPBs; i++)
void CUCode_AX::MixAdd(short* _pBuffer, int _iSize)
{
AXParamBlock& pb = PBs[i];
MixAddVoice(pb, templbuffer, temprbuffer, _iSize, false);
if (_iSize > 1024 * 1024)
_iSize = 1024 * 1024;
memset(templbuffer, 0, _iSize * sizeof(int));
memset(temprbuffer, 0, _iSize * sizeof(int));
#if defined(HAVE_WX) && HAVE_WX
// write logging data to debugger
if (m_DebuggerFrame && _pBuffer)
{
CUCode_AX::Logging(_pBuffer, _iSize, 0, false);
}
// write back out pbs
WriteBackPBs(m_addressPBs, PBs, numberOfPBs);
#endif
if(_pBuffer) {
AXParamBlock PB;
u32 blockAddr = m_addressPBs;
// ------------
for (int i = 0; i < NUMBER_OF_PBS; i++)
{
ReadOutPB(blockAddr, PB);
ProcessUpdates(PB);
MixAddVoice(PB, templbuffer, temprbuffer, _iSize, false);
WriteBackPB(blockAddr, PB);
#if defined(HAVE_WX) && HAVE_WX
#if defined(_DEBUG) || defined(DEBUGFAST)
if(m_DebuggerFrame) m_DebuggerFrame->gLastBlock = blockAddr + p*2 + 2; // save last block location
#endif
#endif
blockAddr = (PB.next_pb_hi << 16) | PB.next_pb_lo;
if (!blockAddr) {
// Guess we're out of blocks
break;
}
}
if (_pBuffer)
{
for (int i = 0; i < _iSize; i++)
{
// Clamp into 16-bit. Maybe we should add a volume compressor here.

View File

@ -71,8 +71,4 @@ private:
void SendMail(u32 _uMail);
};
int ReadOutPBs(u32 pbs_address, AXParamBlock* _pPBs, int _num);
void WriteBackPBs(u32 pbs_address, AXParamBlock* _pPBs, int _num);
#endif // _UCODE_AX