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

View File

@ -70,7 +70,6 @@ StereoOut32 V_Core::ReadInput_HiFi()
ConLog("WARNING: adma buffer didn't finish with a whole block!!\n");
}
}
AdmaInProgress = 0;
InputDataLeft = 0;
DMAICounter = 0x200 * 4;
LastClock = *cyclePtr;
@ -99,22 +98,20 @@ StereoOut32 V_Core::ReadInput()
DebugCores[Index].admaWaveformL[OutPos % 0x100] = retval.Left;
DebugCores[Index].admaWaveformR[OutPos % 0x100] = retval.Right;
#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)
{
//u8 k=InputDataLeft>=InputDataProgress;
int oldOutPos = OutPos;
OutPos = (OutPos + 1) & 0x1FF;
AutoDMAReadBuffer(0);
OutPos = oldOutPos;
AdmaInProgress = 1;
if (InputDataLeft < 0x100)
{
if ((AutoDMACtrl & (Index + 1)))
AutoDMACtrl |= ~3;
if (IsDevBuild)
{
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");
}
}
AdmaInProgress = 0;
InputDataLeft = 0;
DMAICounter = 0x200 * 4;
LastClock = *cyclePtr;
}
}
else
if ((AutoDMACtrl & (Index + 1)))
AutoDMACtrl |= ~3;
}
return retval;
}

View File

@ -132,7 +132,8 @@ void SPU2writeDMA4Mem(u16* pMem, u32 size) // size now in 16bit units
void SPU2interruptDMA4()
{
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].TSA = Cores[0].ActiveTSA;
}
@ -140,7 +141,8 @@ void SPU2interruptDMA4()
void SPU2interruptDMA7()
{
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].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);
Cores[0].DMAICounter -= amt;
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].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;
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);
Cores[1].DMAICounter -= amt;
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].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;
if (!SPU2_dummy_callback)
@ -1521,11 +1524,12 @@ static void __fastcall RegWrite_Core(u16 value)
return;
}
thiscore.AutoDMACtrl = value;
if (value == 0 && thiscore.AdmaInProgress)
if (!(value & 0x3) && thiscore.AdmaInProgress)
{
// Kill the current transfer so it doesn't continue
thiscore.AdmaInProgress = 0;
thiscore.InputDataLeft = 0;
thiscore.DMAICounter = 0;
}
break;