mirror of https://github.com/PCSX2/pcsx2.git
SPU2: Minor improvements to ADMA Timing
This commit is contained in:
parent
c7267d3665
commit
e15807eff8
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue