diff --git a/pcsx2/SPU2/Dma.cpp b/pcsx2/SPU2/Dma.cpp index 1f42c37ff6..fdd727905c 100644 --- a/pcsx2/SPU2/Dma.cpp +++ b/pcsx2/SPU2/Dma.cpp @@ -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 diff --git a/pcsx2/SPU2/ReadInput.cpp b/pcsx2/SPU2/ReadInput.cpp index 72966f428f..ae48b03043 100644 --- a/pcsx2/SPU2/ReadInput.cpp +++ b/pcsx2/SPU2/ReadInput.cpp @@ -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; } diff --git a/pcsx2/SPU2/spu2.cpp b/pcsx2/SPU2/spu2.cpp index f5529c96ac..601553bc1f 100644 --- a/pcsx2/SPU2/spu2.cpp +++ b/pcsx2/SPU2/spu2.cpp @@ -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; } diff --git a/pcsx2/SPU2/spu2sys.cpp b/pcsx2/SPU2/spu2sys.cpp index 3f8f326df7..38a7b9012d 100644 --- a/pcsx2/SPU2/spu2sys.cpp +++ b/pcsx2/SPU2/spu2sys.cpp @@ -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;