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 else
{ {
numberOfPBs = ReadOutPBs(m_addressPBs, PBs, NUMBER_OF_PBS); // numberOfPBs = ReadOutPBs(m_addressPBs, PBs, NUMBER_OF_PBS);
Logging_(_pBuffer, _iSize, a, Wii, PBs, numberOfPBs, m_addressPBs); // Logging_(_pBuffer, _iSize, a, Wii, PBs, numberOfPBs, m_addressPBs);
} }
} }
} }

View File

@ -249,94 +249,35 @@ if(m_DebuggerFrame->ScanMails)
} }
// ---------------- // ----------------
void ReadOutPB(u32 pb_address, AXParamBlock &PB)
int ReadOutPBs(u32 pbs_address, AXParamBlock* _pPBs, int _num)
{ {
int count = 0; const u16 *pSrc = (const u16 *)g_dspInitialize.pGetMemoryPointer(pb_address);
u32 blockAddr = pbs_address; u16 *pDest = (u16 *)&PB;
// 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];
for (int p = 0; p < (int)sizeof(AXParamBlock) / 2; p++) for (int p = 0; p < (int)sizeof(AXParamBlock) / 2; p++)
{ {
pDest[p] = Common::swap16(pSrc[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 void WriteBackPB(u32 pb_address, AXParamBlock &PB)
return count;
}
void WriteBackPBs(u32 pbs_address, AXParamBlock* _pPBs, int _num)
{ {
u32 blockAddr = pbs_address; const u16 *pSrc = (const u16*)&PB;
u16 *pDest = (u16 *)g_dspInitialize.pGetMemoryPointer(pb_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);
for (size_t p = 0; p < sizeof(AXParamBlock) / 2; p++) for (size_t p = 0; p < sizeof(AXParamBlock) / 2; p++)
{ {
pDest[p] = Common::swap16(pSrc[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 /* 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 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. 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 If we get both an on and an off update we chose on. Perhaps that makes the RE1 music
work better. */ work better. */
// ------------ u16 *pDest = (u16 *)&PB;
for (int i = 0; i < numberOfPBs; i++)
{
u16 *pDest = (u16 *)&PBs[i];
u16 upd0 = pDest[34]; u16 upd1 = pDest[35]; u16 upd2 = pDest[36]; // num_updates u16 upd0 = pDest[34]; u16 upd1 = pDest[35]; u16 upd2 = pDest[36]; // num_updates
u16 upd3 = pDest[37]; u16 upd4 = pDest[38]; u16 upd3 = pDest[37]; u16 upd4 = pDest[38];
u16 upd_hi = pDest[39]; // update addr 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 if (numupd > 64) numupd = 64; // prevent crazy values
const u32 updaddr = (u32)(upd_hi << 16) | upd_lo; const u32 updaddr = (u32)(upd_hi << 16) | upd_lo;
int on = false, off = false; int on = false, off = false;
for (int j = 0; j < numupd; j++) for (int j = 0; j < numupd; j++)
{ {
int k = 0; int k = g_Config.m_EnableRE0Fix ? 0 : j;
if(g_Config.m_EnableRE0Fix)
{
k=0;
}
else
{
k=j;
}
const u16 updpar = Memory_Read_U16(updaddr + k); const u16 updpar = Memory_Read_U16(updaddr + k);
const u16 upddata = Memory_Read_U16(updaddr + k + 2); const u16 upddata = Memory_Read_U16(updaddr + k + 2);
// some safety checks, I hope it's enough // some safety checks, I hope it's enough
if(updaddr > 0x80000000 && updaddr < 0x817fffff if(updaddr > 0x80000000 && updaddr < 0x817fffff
&& updpar < 63 && updpar > 3 && upddata >= 0 // updpar > 3 because we don't want to change && 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]; if (_iSize > 1024 * 1024)
MixAddVoice(pb, templbuffer, temprbuffer, _iSize, false); _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 #endif
WriteBackPBs(m_addressPBs, PBs, numberOfPBs);
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++) for (int i = 0; i < _iSize; i++)
{ {
// Clamp into 16-bit. Maybe we should add a volume compressor here. // Clamp into 16-bit. Maybe we should add a volume compressor here.

View File

@ -71,8 +71,4 @@ private:
void SendMail(u32 _uMail); 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 #endif // _UCODE_AX