SPU2: Adjust DMA timings for IRQ's and small packets

This also gets rid of a little kinda hack thing that was in there.
This commit is contained in:
refractionpcsx2 2021-08-31 11:45:46 +01:00
parent c93692a779
commit 4dc0db6ee6
2 changed files with 45 additions and 49 deletions

View File

@ -229,9 +229,6 @@ void V_Core::PlainDMAWrite(u16* pMem, u32 size)
Cores[Index].IRQEnable, Cores[Index].IRQA); Cores[Index].IRQEnable, Cores[Index].IRQA);
FinishDMAwrite(); FinishDMAwrite();
if (ReadSize == 0) //DMA Finished right away so we need a DMAICounter size to trigger the interrupt
DMAICounter = size * 4;
} }
void V_Core::FinishDMAwrite() void V_Core::FinishDMAwrite()
@ -241,6 +238,8 @@ void V_Core::FinishDMAwrite()
DMAPtr = (u16*)iopPhysMem(MADR); DMAPtr = (u16*)iopPhysMem(MADR);
} }
DMAICounter = ReadSize;
if (Index == 0) if (Index == 0)
DMA4LogWrite(DMAPtr, ReadSize << 1); DMA4LogWrite(DMAPtr, ReadSize << 1);
else else
@ -340,23 +339,20 @@ void V_Core::FinishDMAwrite()
DMAPtr += TDA - ActiveTSA; DMAPtr += TDA - ActiveTSA;
ReadSize -= TDA - ActiveTSA; ReadSize -= TDA - ActiveTSA;
if (ReadSize == 0)
DMAICounter = 0; DMAICounter = (DMAICounter - ReadSize) * 4;
else
if (((psxCounters[6].sCycleT + psxCounters[6].CycleT) - psxRegs.cycle) > (u32)DMAICounter)
{ {
DMAICounter = std::min(ReadSize, (u32)0x100) * 4; psxCounters[6].sCycleT = psxRegs.cycle;
psxCounters[6].CycleT = DMAICounter;
if (((psxCounters[6].sCycleT + psxCounters[6].CycleT) - psxRegs.cycle) > (u32)DMAICounter) psxNextCounter -= (psxRegs.cycle - psxNextsCounter);
{ psxNextsCounter = psxRegs.cycle;
psxCounters[6].sCycleT = psxRegs.cycle; if (psxCounters[6].CycleT < psxNextCounter)
psxCounters[6].CycleT = DMAICounter; psxNextCounter = psxCounters[6].CycleT;
psxNextCounter -= (psxRegs.cycle - psxNextsCounter);
psxNextsCounter = psxRegs.cycle;
if (psxCounters[6].CycleT < psxNextCounter)
psxNextCounter = psxCounters[6].CycleT;
}
} }
ActiveTSA = TDA; ActiveTSA = TDA;
ActiveTSA &= 0xfffff; ActiveTSA &= 0xfffff;
TSA = ActiveTSA; TSA = ActiveTSA;
@ -367,6 +363,7 @@ void V_Core::FinishDMAread()
u32 buff1end = ActiveTSA + std::min(ReadSize, (u32)0x100 + std::abs(DMAICounter / 4)); u32 buff1end = ActiveTSA + std::min(ReadSize, (u32)0x100 + std::abs(DMAICounter / 4));
u32 start = ActiveTSA; u32 start = ActiveTSA;
u32 buff2end = 0; u32 buff2end = 0;
if (buff1end > 0x100000) if (buff1end > 0x100000)
{ {
buff2end = buff1end - 0x100000; buff2end = buff1end - 0x100000;
@ -433,26 +430,24 @@ void V_Core::FinishDMAread()
DMARPtr += TDA - ActiveTSA; DMARPtr += TDA - ActiveTSA;
ReadSize -= TDA - ActiveTSA; ReadSize -= TDA - ActiveTSA;
if (ReadSize == 0)
{ // DMA Reads are done AFTER the delay, so to get the timing right we need to scheule one last DMA to catch IRQ's
IsDMARead = false; if (ReadSize)
DMAICounter = 0;
}
else
{
DMAICounter = std::min(ReadSize, (u32)0x100) * 4; DMAICounter = std::min(ReadSize, (u32)0x100) * 4;
else
DMAICounter = 4;
if (((psxCounters[6].sCycleT + psxCounters[6].CycleT) - psxRegs.cycle) > (u32)DMAICounter) if (((psxCounters[6].sCycleT + psxCounters[6].CycleT) - psxRegs.cycle) > (u32)DMAICounter)
{ {
psxCounters[6].sCycleT = psxRegs.cycle; psxCounters[6].sCycleT = psxRegs.cycle;
psxCounters[6].CycleT = DMAICounter; psxCounters[6].CycleT = DMAICounter;
psxNextCounter -= (psxRegs.cycle - psxNextsCounter); psxNextCounter -= (psxRegs.cycle - psxNextsCounter);
psxNextsCounter = psxRegs.cycle; psxNextsCounter = psxRegs.cycle;
if (psxCounters[6].CycleT < psxNextCounter) if (psxCounters[6].CycleT < psxNextCounter)
psxNextCounter = psxCounters[6].CycleT; psxNextCounter = psxCounters[6].CycleT;
}
} }
ActiveTSA = TDA; ActiveTSA = TDA;
ActiveTSA &= 0xfffff; ActiveTSA &= 0xfffff;
TSA = ActiveTSA; TSA = ActiveTSA;

View File

@ -463,14 +463,6 @@ __forceinline void TimeUpdate(u32 cClocks)
if (Cores[0].DMAICounter <= 0) if (Cores[0].DMAICounter <= 0)
{ {
if (((Cores[0].AutoDMACtrl & 1) != 1) && Cores[0].ReadSize)
{
if (Cores[0].IsDMARead)
Cores[0].FinishDMAread();
else
Cores[0].FinishDMAwrite();
}
for (int i = 0; i < 2; i++) for (int i = 0; i < 2; i++)
{ {
if (has_to_call_irq_dma[i]) if (has_to_call_irq_dma[i])
@ -484,6 +476,15 @@ __forceinline void TimeUpdate(u32 cClocks)
} }
} }
} }
if (((Cores[0].AutoDMACtrl & 1) != 1) && Cores[0].ReadSize)
{
if (Cores[0].IsDMARead)
Cores[0].FinishDMAread();
else
Cores[0].FinishDMAwrite();
}
if (Cores[0].DMAICounter <= 0) if (Cores[0].DMAICounter <= 0)
{ {
HW_DMA4_MADR = HW_DMA4_TADR; HW_DMA4_MADR = HW_DMA4_TADR;
@ -515,14 +516,6 @@ __forceinline void TimeUpdate(u32 cClocks)
HW_DMA7_MADR += amt / 2; HW_DMA7_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].IsDMARead)
Cores[1].FinishDMAread();
else
Cores[1].FinishDMAwrite();
}
for (int i = 0; i < 2; i++) for (int i = 0; i < 2; i++)
{ {
if (has_to_call_irq_dma[i]) if (has_to_call_irq_dma[i])
@ -537,6 +530,14 @@ __forceinline void TimeUpdate(u32 cClocks)
} }
} }
if (((Cores[1].AutoDMACtrl & 2) != 2) && Cores[1].ReadSize)
{
if (Cores[1].IsDMARead)
Cores[1].FinishDMAread();
else
Cores[1].FinishDMAwrite();
}
if (Cores[1].DMAICounter <= 0) if (Cores[1].DMAICounter <= 0)
{ {
HW_DMA7_MADR = HW_DMA7_TADR; HW_DMA7_MADR = HW_DMA7_TADR;