From 9efcd9a096841f78767826badc9a44f1bdb6d91e Mon Sep 17 00:00:00 2001 From: refractionpcsx2 Date: Mon, 25 Jan 2021 12:08:39 +0000 Subject: [PATCH] SPU2: Improve SPDIF Bitstream Bypass on Core 0, track MADR Required for GTA Vice City to work --- pcsx2/SPU2/Dma.cpp | 2 +- pcsx2/SPU2/ReadInput.cpp | 31 +++++++++++++++++++++---------- pcsx2/SPU2/defs.h | 1 + pcsx2/SPU2/spu2sys.cpp | 4 +++- pcsx2/SaveState.h | 2 +- 5 files changed, 27 insertions(+), 13 deletions(-) diff --git a/pcsx2/SPU2/Dma.cpp b/pcsx2/SPU2/Dma.cpp index fdd727905c..1149eb5d03 100644 --- a/pcsx2/SPU2/Dma.cpp +++ b/pcsx2/SPU2/Dma.cpp @@ -133,7 +133,7 @@ void V_Core::AutoDMAReadBuffer(int mode) //mode: 0= split stereo; 1 = do not spl if (DMAPtr != nullptr) memcpy(GetMemPtr(0x2000 + (Index << 10) + spos), DMAPtr + InputDataProgress, 0x200); - MADR += 0x200; + InputDataTransferred += 0x200; InputDataLeft -= 0x100; InputDataProgress += 0x100; leftbuffer = !leftbuffer; diff --git a/pcsx2/SPU2/ReadInput.cpp b/pcsx2/SPU2/ReadInput.cpp index ae48b03043..b59db92564 100644 --- a/pcsx2/SPU2/ReadInput.cpp +++ b/pcsx2/SPU2/ReadInput.cpp @@ -82,28 +82,39 @@ StereoOut32 V_Core::ReadInput_HiFi() StereoOut32 V_Core::ReadInput() { StereoOut32 retval; - - if ((Index != 1) || ((PlayMode & 2) == 0)) + s16 ReadIndex = OutPos; + if ((Index == 1) || ((PlayMode & 2) == 0)) { for (int i = 0; i < 2; i++) - if (Cores[i].IRQEnable && 0x2000 + (Index << 10) + OutPos == (Cores[i].IRQA & 0xfffffdff)) + if (Cores[i].IRQEnable && 0x2000 + (Index << 10) + ReadIndex == (Cores[i].IRQA & 0xfffffdff)) SetIrqCall(i); retval = StereoOut32( - (s32)(*GetMemPtr(0x2000 + (Index << 10) + OutPos)), - (s32)(*GetMemPtr(0x2200 + (Index << 10) + OutPos))); + (s32)(*GetMemPtr(0x2000 + (Index << 10) + ReadIndex)), + (s32)(*GetMemPtr(0x2200 + (Index << 10) + ReadIndex))); } #ifdef PCSX2_DEVBUILD DebugCores[Index].admaWaveformL[OutPos % 0x100] = retval.Left; DebugCores[Index].admaWaveformR[OutPos % 0x100] = retval.Right; #endif - - if (OutPos == 0x100 || OutPos == 0x0 || OutPos == 0x80 || OutPos == 0x180) + + // Simulate MADR increase, GTA VC tracks the MADR address for calculating a certain point in the buffer + if (InputDataTransferred) { - if (OutPos == 0x100) + u32 amount = std::min(InputDataTransferred, (u32)0x180); + MADR += amount; + InputDataTransferred -= amount; + } + + if (PlayMode == 2 && Index == 0) //Bitstream bypass refills twice as quickly (GTA VC) + ReadIndex = (ReadIndex * 2) & 0x1FF; + + if (ReadIndex == 0x100 || ReadIndex == 0x0 || ReadIndex == 0x80 || ReadIndex == 0x180) + { + if (ReadIndex == 0x100) InputPosWrite = 0; - else if (OutPos == 0) + else if (ReadIndex == 0) InputPosWrite = 0x100; if (InputDataLeft >= 0x100) @@ -123,7 +134,7 @@ StereoOut32 V_Core::ReadInput() } InputDataLeft = 0; - DMAICounter = 0x200 * 4; + DMAICounter = InputDataTransferred * 4; LastClock = *cyclePtr; } } diff --git a/pcsx2/SPU2/defs.h b/pcsx2/SPU2/defs.h index 3f43c98a99..9e11fc9d33 100644 --- a/pcsx2/SPU2/defs.h +++ b/pcsx2/SPU2/defs.h @@ -406,6 +406,7 @@ struct V_Core s32 DMAICounter; // DMA Interrupt Counter u32 LastClock; // DMA Interrupt Clock Cycle Counter u32 InputDataLeft; // Input Buffer + u32 InputDataTransferred; // Used for simulating MADR increase (GTA VC) u32 InputPosWrite; u32 InputDataProgress; diff --git a/pcsx2/SPU2/spu2sys.cpp b/pcsx2/SPU2/spu2sys.cpp index 38a7b9012d..9cb4bed0c4 100644 --- a/pcsx2/SPU2/spu2sys.cpp +++ b/pcsx2/SPU2/spu2sys.cpp @@ -134,8 +134,9 @@ void V_Core::Init(int index) NoiseOut = 0; AutoDMACtrl = 0; InputDataLeft = 0; - InputPosWrite = 0; + InputPosWrite = 0x100; InputDataProgress = 0; + InputDataTransferred = 0; ReverbX = 0; LastEffect.Left = 0; LastEffect.Right = 0; @@ -1530,6 +1531,7 @@ static void __fastcall RegWrite_Core(u16 value) thiscore.AdmaInProgress = 0; thiscore.InputDataLeft = 0; thiscore.DMAICounter = 0; + thiscore.InputDataTransferred = 0; } break; diff --git a/pcsx2/SaveState.h b/pcsx2/SaveState.h index be278e0e9b..52b8cf9b52 100644 --- a/pcsx2/SaveState.h +++ b/pcsx2/SaveState.h @@ -24,7 +24,7 @@ // the lower 16 bit value. IF the change is breaking of all compatibility with old // states, increment the upper 16 bit value, and clear the lower 16 bits to 0. -static const u32 g_SaveVersion = (0x9A19 << 16) | 0x0000; +static const u32 g_SaveVersion = (0x9A1A << 16) | 0x0000; // this function is meant to be used in the place of GSfreeze, and provides a safe layer // between the GS saving function and the MTGS's needs. :)