SPU2: Minor improvements to ADMA Timing

This commit is contained in:
refractionpcsx2 2021-01-24 17:56:14 +00:00
parent c7267d3665
commit e15807eff8
4 changed files with 38 additions and 38 deletions

View File

@ -97,14 +97,14 @@ void V_Core::LogAutoDMA(FILE* fp)
void V_Core::AutoDMAReadBuffer(int mode) //mode: 0= split stereo; 1 = do not split stereo void V_Core::AutoDMAReadBuffer(int mode) //mode: 0= split stereo; 1 = do not split stereo
{ {
int spos = ActiveTSA & 0x100; // Starting position passed by TSA int spos = InputPosWrite & 0x100; // Starting position passed by TSA
bool leftbuffer = !(ActiveTSA & 0x80); bool leftbuffer = !(InputPosWrite & 0x80);
if (spos == (OutPos & 0x100))
{ if (InputPosWrite == 0xFFFF) // Data request not made yet
//ConLog("Ignoring buffer update Pos %x OutPos %x\n", spos, OutPos);
return; return;
}
AutoDMACtrl &= 0x3;
int size = std::min(InputDataLeft, (u32)0x200); int size = std::min(InputDataLeft, (u32)0x200);
if (!leftbuffer) if (!leftbuffer)
size = 0x100; size = 0x100;
@ -117,7 +117,6 @@ void V_Core::AutoDMAReadBuffer(int mode) //mode: 0= split stereo; 1 = do not spl
if (mode) if (mode)
{ {
if (DMAPtr != nullptr) if (DMAPtr != nullptr)
//memcpy((ADMATempBuffer+(spos<<1)),DMAPtr+InputDataProgress,0x400);
memcpy(GetMemPtr(0x2000 + (Index << 10) + spos), DMAPtr + InputDataProgress, size); memcpy(GetMemPtr(0x2000 + (Index << 10) + spos), DMAPtr + InputDataProgress, size);
MADR += size; MADR += size;
InputDataLeft -= 0x200; InputDataLeft -= 0x200;
@ -131,20 +130,19 @@ void V_Core::AutoDMAReadBuffer(int mode) //mode: 0= split stereo; 1 = do not spl
spos |= 0x200; spos |= 0x200;
else else
spos &= ~0x200; spos &= ~0x200;
//ConLog("Filling %s buffer\n", leftbuffer ? "Left" : "Right");
if (DMAPtr != nullptr) if (DMAPtr != nullptr)
//memcpy((ADMATempBuffer+spos),DMAPtr+InputDataProgress,0x200);
memcpy(GetMemPtr(0x2000 + (Index << 10) + spos), DMAPtr + InputDataProgress, 0x200); memcpy(GetMemPtr(0x2000 + (Index << 10) + spos), DMAPtr + InputDataProgress, 0x200);
MADR += 0x200; MADR += 0x200;
InputDataLeft -= 0x100; InputDataLeft -= 0x100;
InputDataProgress += 0x100; InputDataProgress += 0x100;
leftbuffer = !leftbuffer; leftbuffer = !leftbuffer;
size -= 0x100; size -= 0x100;
ActiveTSA += 0x80; InputPosWrite += 0x80;
ActiveTSA &= ~0x200;
TSA = ActiveTSA;
} }
} }
if (!(InputPosWrite & 0x80))
InputPosWrite = 0xFFFF;
} }
void V_Core::StartADMAWrite(u16* pMem, u32 sz) void V_Core::StartADMAWrite(u16* pMem, u32 sz)
@ -159,6 +157,7 @@ void V_Core::StartADMAWrite(u16* pMem, u32 sz)
GetDmaIndexChar(), size << 1, ActiveTSA, DMABits, AutoDMACtrl, (~Regs.ATTR) & 0xffff, OutPos); GetDmaIndexChar(), size << 1, ActiveTSA, DMABits, AutoDMACtrl, (~Regs.ATTR) & 0xffff, OutPos);
InputDataProgress = 0; InputDataProgress = 0;
TADR = MADR + (size << 1);
if ((AutoDMACtrl & (Index + 1)) == 0) if ((AutoDMACtrl & (Index + 1)) == 0)
{ {
ActiveTSA = 0x2000 + (Index << 10); ActiveTSA = 0x2000 + (Index << 10);
@ -168,8 +167,7 @@ void V_Core::StartADMAWrite(u16* pMem, u32 sz)
else if (size >= 256) else if (size >= 256)
{ {
InputDataLeft = size; InputDataLeft = size;
AutoDMACtrl &= 3; if (InputPosWrite != 0xFFFF)
if (AdmaInProgress == 0)
{ {
#ifdef PCM24_S1_INTERLEAVE #ifdef PCM24_S1_INTERLEAVE
if ((Index == 1) && ((PlayMode & 8) == 8)) if ((Index == 1) && ((PlayMode & 8) == 8))
@ -184,16 +182,15 @@ void V_Core::StartADMAWrite(u16* pMem, u32 sz)
AutoDMAReadBuffer(0); AutoDMAReadBuffer(0);
#endif #endif
AdmaInProgress = 1;
if (!InputDataLeft) if (!InputDataLeft)
{ {
DMAICounter = size * 4; DMAICounter = size * 4;
LastClock = *cyclePtr; LastClock = *cyclePtr;
AdmaInProgress = 0;
AutoDMACtrl |= ~3; AutoDMACtrl |= ~3;
} }
} }
AdmaInProgress = 1;
} }
else else
{ {
@ -202,7 +199,6 @@ void V_Core::StartADMAWrite(u16* pMem, u32 sz)
DMAICounter = size * 4; DMAICounter = size * 4;
LastClock = *cyclePtr; LastClock = *cyclePtr;
} }
TADR = MADR + (size << 1);
} }
void V_Core::PlainDMAWrite(u16* pMem, u32 size) void V_Core::PlainDMAWrite(u16* pMem, u32 size)
@ -245,8 +241,6 @@ void V_Core::PlainDMAWrite(u16* pMem, u32 size)
void V_Core::FinishDMAwrite() void V_Core::FinishDMAwrite()
{ {
if (ActiveTSA != TSA)
ConLog("Write WTF TSA %x Active %x\n", TSA, ActiveTSA);
if (Index == 0) if (Index == 0)
DMA4LogWrite(DMAPtr, ReadSize << 1); DMA4LogWrite(DMAPtr, ReadSize << 1);
else else

View File

@ -70,7 +70,6 @@ StereoOut32 V_Core::ReadInput_HiFi()
ConLog("WARNING: adma buffer didn't finish with a whole block!!\n"); ConLog("WARNING: adma buffer didn't finish with a whole block!!\n");
} }
} }
AdmaInProgress = 0;
InputDataLeft = 0; InputDataLeft = 0;
DMAICounter = 0x200 * 4; DMAICounter = 0x200 * 4;
LastClock = *cyclePtr; LastClock = *cyclePtr;
@ -99,22 +98,20 @@ StereoOut32 V_Core::ReadInput()
DebugCores[Index].admaWaveformL[OutPos % 0x100] = retval.Left; DebugCores[Index].admaWaveformL[OutPos % 0x100] = retval.Left;
DebugCores[Index].admaWaveformR[OutPos % 0x100] = retval.Right; DebugCores[Index].admaWaveformR[OutPos % 0x100] = retval.Right;
#endif #endif
if (OutPos == 0xFF || OutPos == 0x1FF || OutPos == 0x7F || OutPos == 0x17F) if (OutPos == 0x100 || OutPos == 0x0 || OutPos == 0x80 || OutPos == 0x180)
{ {
if (OutPos == 0x100)
InputPosWrite = 0;
else if (OutPos == 0)
InputPosWrite = 0x100;
if (InputDataLeft >= 0x100) if (InputDataLeft >= 0x100)
{ {
//u8 k=InputDataLeft>=InputDataProgress;
int oldOutPos = OutPos;
OutPos = (OutPos + 1) & 0x1FF;
AutoDMAReadBuffer(0); AutoDMAReadBuffer(0);
OutPos = oldOutPos;
AdmaInProgress = 1; AdmaInProgress = 1;
if (InputDataLeft < 0x100) if (InputDataLeft < 0x100)
{ {
if ((AutoDMACtrl & (Index + 1)))
AutoDMACtrl |= ~3;
if (IsDevBuild) if (IsDevBuild)
{ {
FileLog("[%10d] AutoDMA%c block end.\n", Cycles, GetDmaIndexChar()); FileLog("[%10d] AutoDMA%c block end.\n", Cycles, GetDmaIndexChar());
@ -124,12 +121,15 @@ StereoOut32 V_Core::ReadInput()
ConLog("WARNING: adma buffer didn't finish with a whole block!!\n"); ConLog("WARNING: adma buffer didn't finish with a whole block!!\n");
} }
} }
AdmaInProgress = 0;
InputDataLeft = 0; InputDataLeft = 0;
DMAICounter = 0x200 * 4; DMAICounter = 0x200 * 4;
LastClock = *cyclePtr; LastClock = *cyclePtr;
} }
} }
else
if ((AutoDMACtrl & (Index + 1)))
AutoDMACtrl |= ~3;
} }
return retval; return retval;
} }

View File

@ -132,7 +132,8 @@ void SPU2writeDMA4Mem(u16* pMem, u32 size) // size now in 16bit units
void SPU2interruptDMA4() void SPU2interruptDMA4()
{ {
FileLog("[%10d] SPU2 interruptDMA4\n", Cycles); FileLog("[%10d] SPU2 interruptDMA4\n", Cycles);
Cores[0].Regs.STATX |= 0x80; if(Cores[0].DmaMode)
Cores[0].Regs.STATX |= 0x80;
Cores[0].Regs.STATX &= ~0x400; Cores[0].Regs.STATX &= ~0x400;
Cores[0].TSA = Cores[0].ActiveTSA; Cores[0].TSA = Cores[0].ActiveTSA;
} }
@ -140,7 +141,8 @@ void SPU2interruptDMA4()
void SPU2interruptDMA7() void SPU2interruptDMA7()
{ {
FileLog("[%10d] SPU2 interruptDMA7\n", Cycles); FileLog("[%10d] SPU2 interruptDMA7\n", Cycles);
Cores[1].Regs.STATX |= 0x80; if (Cores[1].DmaMode)
Cores[1].Regs.STATX |= 0x80;
Cores[1].Regs.STATX &= ~0x400; Cores[1].Regs.STATX &= ~0x400;
Cores[1].TSA = Cores[1].ActiveTSA; Cores[1].TSA = Cores[1].ActiveTSA;
} }

View File

@ -438,7 +438,9 @@ __forceinline void TimeUpdate(u32 cClocks)
const u32 amt = std::min(*cyclePtr - Cores[0].LastClock, (u32)Cores[0].DMAICounter); const u32 amt = std::min(*cyclePtr - Cores[0].LastClock, (u32)Cores[0].DMAICounter);
Cores[0].DMAICounter -= amt; Cores[0].DMAICounter -= amt;
Cores[0].LastClock = *cyclePtr; Cores[0].LastClock = *cyclePtr;
Cores[0].MADR += amt / 2; if(!Cores[0].AdmaInProgress)
Cores[0].MADR += amt / 2;
if (Cores[0].DMAICounter <= 0) if (Cores[0].DMAICounter <= 0)
{ {
if (((Cores[0].AutoDMACtrl & 1) != 1) && Cores[0].ReadSize) if (((Cores[0].AutoDMACtrl & 1) != 1) && Cores[0].ReadSize)
@ -463,7 +465,7 @@ __forceinline void TimeUpdate(u32 cClocks)
} }
} }
} }
if (!Cores[0].DMAICounter) if (Cores[0].DMAICounter <= 0)
{ {
Cores[0].MADR = Cores[0].TADR; Cores[0].MADR = Cores[0].TADR;
if (!SPU2_dummy_callback) if (!SPU2_dummy_callback)
@ -493,7 +495,8 @@ __forceinline void TimeUpdate(u32 cClocks)
const u32 amt = std::min(*cyclePtr - Cores[1].LastClock, (u32)Cores[1].DMAICounter); const u32 amt = std::min(*cyclePtr - Cores[1].LastClock, (u32)Cores[1].DMAICounter);
Cores[1].DMAICounter -= amt; Cores[1].DMAICounter -= amt;
Cores[1].LastClock = *cyclePtr; Cores[1].LastClock = *cyclePtr;
Cores[1].MADR += amt / 2; if (!Cores[1].AdmaInProgress)
Cores[1].MADR += amt / 2;
if (Cores[1].DMAICounter <= 0) if (Cores[1].DMAICounter <= 0)
{ {
if (((Cores[1].AutoDMACtrl & 2) != 2) && Cores[1].ReadSize) if (((Cores[1].AutoDMACtrl & 2) != 2) && Cores[1].ReadSize)
@ -519,7 +522,7 @@ __forceinline void TimeUpdate(u32 cClocks)
} }
} }
if (!Cores[1].DMAICounter) if (Cores[1].DMAICounter <= 0)
{ {
Cores[1].MADR = Cores[1].TADR; Cores[1].MADR = Cores[1].TADR;
if (!SPU2_dummy_callback) if (!SPU2_dummy_callback)
@ -1521,11 +1524,12 @@ static void __fastcall RegWrite_Core(u16 value)
return; return;
} }
thiscore.AutoDMACtrl = value; thiscore.AutoDMACtrl = value;
if (value == 0 && thiscore.AdmaInProgress) if (!(value & 0x3) && thiscore.AdmaInProgress)
{ {
// Kill the current transfer so it doesn't continue // Kill the current transfer so it doesn't continue
thiscore.AdmaInProgress = 0; thiscore.AdmaInProgress = 0;
thiscore.InputDataLeft = 0; thiscore.InputDataLeft = 0;
thiscore.DMAICounter = 0;
} }
break; break;