mirror of https://github.com/PCSX2/pcsx2.git
SPU2: Improve ADMA behaviour/timing
This commit is contained in:
parent
b9a6dca4b4
commit
4497532edb
|
@ -97,8 +97,10 @@ void V_Core::LogAutoDMA(FILE* fp)
|
|||
|
||||
void V_Core::AutoDMAReadBuffer(int mode) //mode: 0= split stereo; 1 = do not split stereo
|
||||
{
|
||||
int spos = ((InputPosRead + 0xff) & 0x100); //starting position of the free buffer
|
||||
int spos = ActiveTSA & 0x100;// ((InputPosRead + 0xff) & 0x100); //starting position of the free buffer
|
||||
|
||||
if (spos == (OutPos & 0x100))
|
||||
return;
|
||||
LogAutoDMA(Index ? ADMA7LogFile : ADMA4LogFile);
|
||||
|
||||
// HACKFIX!! DMAPtr can be invalid after a savestate load, so the savestate just forces it
|
||||
|
@ -129,6 +131,9 @@ void V_Core::AutoDMAReadBuffer(int mode) //mode: 0= split stereo; 1 = do not spl
|
|||
MADR += 0x200;
|
||||
InputDataLeft -= 0x100;
|
||||
InputDataProgress += 0x100;
|
||||
ActiveTSA += 0x100;
|
||||
ActiveTSA &= ~0x200;
|
||||
TSA = ActiveTSA;
|
||||
}
|
||||
// See ReadInput at mixer.cpp for explanation on the commented out lines
|
||||
//
|
||||
|
@ -155,6 +160,7 @@ void V_Core::StartADMAWrite(u16* pMem, u32 sz)
|
|||
else if (size >= 512)
|
||||
{
|
||||
InputDataLeft = size;
|
||||
AutoDMACtrl &= 3;
|
||||
if (AdmaInProgress == 0)
|
||||
{
|
||||
#ifdef PCM24_S1_INTERLEAVE
|
||||
|
@ -172,15 +178,18 @@ void V_Core::StartADMAWrite(u16* pMem, u32 sz)
|
|||
|
||||
AutoDMAReadBuffer(0);
|
||||
#endif
|
||||
|
||||
AdmaInProgress = 1;
|
||||
|
||||
// Klonoa 2
|
||||
if (size == 512)
|
||||
if (!InputDataLeft)
|
||||
{
|
||||
DMAICounter = size * 4;
|
||||
LastClock = *cyclePtr;
|
||||
AdmaInProgress = 0;
|
||||
AutoDMACtrl |= ~3;
|
||||
}
|
||||
}
|
||||
|
||||
AdmaInProgress = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -357,8 +366,6 @@ void V_Core::FinishDMAwrite()
|
|||
|
||||
void V_Core::FinishDMAread()
|
||||
{
|
||||
if (ActiveTSA != TSA)
|
||||
ConLog("Read WTF TSA %x Active %x\n", TSA, ActiveTSA);
|
||||
u32 buff1end = ActiveTSA + std::min(ReadSize, (u32)0x100 + std::abs(DMAICounter / 4));
|
||||
u32 start = ActiveTSA;
|
||||
u32 buff2end = 0;
|
||||
|
@ -520,7 +527,7 @@ void V_Core::DoDMAwrite(u16* pMem, u32 size)
|
|||
else
|
||||
{
|
||||
PlainDMAWrite(pMem, size);
|
||||
Regs.STATX &= ~0x80;
|
||||
Regs.STATX |= 0x400;
|
||||
}
|
||||
Regs.STATX &= ~0x80;
|
||||
Regs.STATX |= 0x400;
|
||||
}
|
||||
|
|
|
@ -123,7 +123,7 @@ StereoOut32 V_Core::ReadInput()
|
|||
if ((Index != 1) || ((PlayMode & 2) == 0))
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
if (Cores[i].IRQEnable && 0x2000 + (Index << 10) + InputPosRead == (Cores[i].IRQA & 0xfffffdff))
|
||||
if (Cores[i].IRQEnable && 0x2000 + (Index << 10) + OutPos == (Cores[i].IRQA & 0xfffffdff))
|
||||
SetIrqCall(i);
|
||||
|
||||
//retval = StereoOut32(
|
||||
|
@ -131,8 +131,8 @@ StereoOut32 V_Core::ReadInput()
|
|||
// (s32)ADMATempBuffer[InputPosRead+0x200]
|
||||
//);
|
||||
retval = StereoOut32(
|
||||
(s32)(*GetMemPtr(0x2000 + (Index << 10) + InputPosRead)),
|
||||
(s32)(*GetMemPtr(0x2200 + (Index << 10) + InputPosRead)));
|
||||
(s32)(*GetMemPtr(0x2000 + (Index << 10) + OutPos)),
|
||||
(s32)(*GetMemPtr(0x2200 + (Index << 10) + OutPos)));
|
||||
}
|
||||
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
|
@ -142,21 +142,19 @@ StereoOut32 V_Core::ReadInput()
|
|||
|
||||
InputPosRead++;
|
||||
|
||||
if ((AutoDMACtrl & (Index + 1)) && (InputPosRead == 0x100 || InputPosRead == 0x200))
|
||||
if ((OutPos == 0xFF || OutPos == 0x1FF))
|
||||
{
|
||||
AdmaInProgress = 0;
|
||||
if (InputDataLeft >= 0x200)
|
||||
{
|
||||
//u8 k=InputDataLeft>=InputDataProgress;
|
||||
|
||||
int oldOutPos = OutPos;
|
||||
OutPos = (OutPos + 1) & 0x1FF;
|
||||
AutoDMAReadBuffer(0);
|
||||
|
||||
OutPos = oldOutPos;
|
||||
AdmaInProgress = 1;
|
||||
ActiveTSA = (Index << 10) + InputPosRead;
|
||||
TSA = ActiveTSA;
|
||||
if (InputDataLeft < 0x200)
|
||||
{
|
||||
if((AutoDMACtrl & (Index + 1)))
|
||||
if ((AutoDMACtrl & (Index + 1)))
|
||||
AutoDMACtrl |= ~3;
|
||||
|
||||
if (IsDevBuild)
|
||||
|
@ -168,24 +166,10 @@ StereoOut32 V_Core::ReadInput()
|
|||
ConLog("WARNING: adma buffer didn't finish with a whole block!!\n");
|
||||
}
|
||||
}
|
||||
|
||||
AdmaInProgress = 0;
|
||||
InputDataLeft = 0;
|
||||
// Hack, kinda. We call the interrupt early here, since PCSX2 doesn't like them delayed.
|
||||
//DMAICounter = 1;
|
||||
if (Index == 0)
|
||||
{
|
||||
if (!SPU2_dummy_callback)
|
||||
spu2DMA4Irq();
|
||||
else
|
||||
SPU2interruptDMA4();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!SPU2_dummy_callback)
|
||||
spu2DMA7Irq();
|
||||
else
|
||||
SPU2interruptDMA7();
|
||||
}
|
||||
DMAICounter = 0x200 * 4;
|
||||
LastClock = *cyclePtr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1522,11 +1522,11 @@ static void __fastcall RegWrite_Core(u16 value)
|
|||
return;
|
||||
}
|
||||
thiscore.AutoDMACtrl = value;
|
||||
if (value == 0 && thiscore.AdmaInProgress && (thiscore.Regs.STATX & 0x400))
|
||||
if (value == 0 && thiscore.AdmaInProgress)
|
||||
{
|
||||
// Kill the current transfer so it doesn't continue
|
||||
thiscore.AdmaInProgress = 0;
|
||||
thiscore.Regs.STATX &= ~0x400; // Set DMA as not busy transferring
|
||||
// No need to end the DMA here, the IOP seems to handle that
|
||||
thiscore.InputDataLeft = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
Loading…
Reference in New Issue