From 4dc0db6ee6e49448d90410cf947b82d7eeed0c69 Mon Sep 17 00:00:00 2001 From: refractionpcsx2 Date: Tue, 31 Aug 2021 11:45:46 +0100 Subject: [PATCH] SPU2: Adjust DMA timings for IRQ's and small packets This also gets rid of a little kinda hack thing that was in there. --- pcsx2/SPU2/Dma.cpp | 61 +++++++++++++++++++----------------------- pcsx2/SPU2/spu2sys.cpp | 33 ++++++++++++----------- 2 files changed, 45 insertions(+), 49 deletions(-) diff --git a/pcsx2/SPU2/Dma.cpp b/pcsx2/SPU2/Dma.cpp index 921a0d5438..6a7d541fdc 100644 --- a/pcsx2/SPU2/Dma.cpp +++ b/pcsx2/SPU2/Dma.cpp @@ -229,9 +229,6 @@ void V_Core::PlainDMAWrite(u16* pMem, u32 size) Cores[Index].IRQEnable, Cores[Index].IRQA); 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() @@ -241,6 +238,8 @@ void V_Core::FinishDMAwrite() DMAPtr = (u16*)iopPhysMem(MADR); } + DMAICounter = ReadSize; + if (Index == 0) DMA4LogWrite(DMAPtr, ReadSize << 1); else @@ -340,23 +339,20 @@ void V_Core::FinishDMAwrite() DMAPtr += TDA - ActiveTSA; ReadSize -= TDA - ActiveTSA; - if (ReadSize == 0) - DMAICounter = 0; - else + + DMAICounter = (DMAICounter - ReadSize) * 4; + + 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) - { - psxCounters[6].sCycleT = psxRegs.cycle; - psxCounters[6].CycleT = DMAICounter; - - psxNextCounter -= (psxRegs.cycle - psxNextsCounter); - psxNextsCounter = psxRegs.cycle; - if (psxCounters[6].CycleT < psxNextCounter) - psxNextCounter = psxCounters[6].CycleT; - } + psxNextCounter -= (psxRegs.cycle - psxNextsCounter); + psxNextsCounter = psxRegs.cycle; + if (psxCounters[6].CycleT < psxNextCounter) + psxNextCounter = psxCounters[6].CycleT; } + ActiveTSA = TDA; ActiveTSA &= 0xfffff; TSA = ActiveTSA; @@ -367,6 +363,7 @@ void V_Core::FinishDMAread() u32 buff1end = ActiveTSA + std::min(ReadSize, (u32)0x100 + std::abs(DMAICounter / 4)); u32 start = ActiveTSA; u32 buff2end = 0; + if (buff1end > 0x100000) { buff2end = buff1end - 0x100000; @@ -433,26 +430,24 @@ void V_Core::FinishDMAread() DMARPtr += TDA - ActiveTSA; ReadSize -= TDA - ActiveTSA; - if (ReadSize == 0) - { - IsDMARead = false; - DMAICounter = 0; - } - else - { + + // DMA Reads are done AFTER the delay, so to get the timing right we need to scheule one last DMA to catch IRQ's + if (ReadSize) DMAICounter = std::min(ReadSize, (u32)0x100) * 4; + else + DMAICounter = 4; - if (((psxCounters[6].sCycleT + psxCounters[6].CycleT) - psxRegs.cycle) > (u32)DMAICounter) - { - psxCounters[6].sCycleT = psxRegs.cycle; - psxCounters[6].CycleT = DMAICounter; + if (((psxCounters[6].sCycleT + psxCounters[6].CycleT) - psxRegs.cycle) > (u32)DMAICounter) + { + psxCounters[6].sCycleT = psxRegs.cycle; + psxCounters[6].CycleT = DMAICounter; - psxNextCounter -= (psxRegs.cycle - psxNextsCounter); - psxNextsCounter = psxRegs.cycle; - if (psxCounters[6].CycleT < psxNextCounter) - psxNextCounter = psxCounters[6].CycleT; - } + psxNextCounter -= (psxRegs.cycle - psxNextsCounter); + psxNextsCounter = psxRegs.cycle; + if (psxCounters[6].CycleT < psxNextCounter) + psxNextCounter = psxCounters[6].CycleT; } + ActiveTSA = TDA; ActiveTSA &= 0xfffff; TSA = ActiveTSA; diff --git a/pcsx2/SPU2/spu2sys.cpp b/pcsx2/SPU2/spu2sys.cpp index 7d0b14b4e8..e43870aaa4 100644 --- a/pcsx2/SPU2/spu2sys.cpp +++ b/pcsx2/SPU2/spu2sys.cpp @@ -463,14 +463,6 @@ __forceinline void TimeUpdate(u32 cClocks) 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++) { 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) { HW_DMA4_MADR = HW_DMA4_TADR; @@ -515,14 +516,6 @@ __forceinline void TimeUpdate(u32 cClocks) HW_DMA7_MADR += amt / 2; 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++) { 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) { HW_DMA7_MADR = HW_DMA7_TADR;