SPU2: Improve SPDIF Bitstream Bypass on Core 0, track MADR

Required for GTA Vice City to work
This commit is contained in:
refractionpcsx2 2021-01-25 12:08:39 +00:00
parent e15807eff8
commit 9efcd9a096
5 changed files with 27 additions and 13 deletions

View File

@ -133,7 +133,7 @@ void V_Core::AutoDMAReadBuffer(int mode) //mode: 0= split stereo; 1 = do not spl
if (DMAPtr != nullptr) if (DMAPtr != nullptr)
memcpy(GetMemPtr(0x2000 + (Index << 10) + spos), DMAPtr + InputDataProgress, 0x200); memcpy(GetMemPtr(0x2000 + (Index << 10) + spos), DMAPtr + InputDataProgress, 0x200);
MADR += 0x200; InputDataTransferred += 0x200;
InputDataLeft -= 0x100; InputDataLeft -= 0x100;
InputDataProgress += 0x100; InputDataProgress += 0x100;
leftbuffer = !leftbuffer; leftbuffer = !leftbuffer;

View File

@ -82,16 +82,16 @@ StereoOut32 V_Core::ReadInput_HiFi()
StereoOut32 V_Core::ReadInput() StereoOut32 V_Core::ReadInput()
{ {
StereoOut32 retval; StereoOut32 retval;
s16 ReadIndex = OutPos;
if ((Index != 1) || ((PlayMode & 2) == 0)) if ((Index == 1) || ((PlayMode & 2) == 0))
{ {
for (int i = 0; i < 2; i++) 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); SetIrqCall(i);
retval = StereoOut32( retval = StereoOut32(
(s32)(*GetMemPtr(0x2000 + (Index << 10) + OutPos)), (s32)(*GetMemPtr(0x2000 + (Index << 10) + ReadIndex)),
(s32)(*GetMemPtr(0x2200 + (Index << 10) + OutPos))); (s32)(*GetMemPtr(0x2200 + (Index << 10) + ReadIndex)));
} }
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD
@ -99,11 +99,22 @@ StereoOut32 V_Core::ReadInput()
DebugCores[Index].admaWaveformR[OutPos % 0x100] = retval.Right; DebugCores[Index].admaWaveformR[OutPos % 0x100] = retval.Right;
#endif #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; InputPosWrite = 0;
else if (OutPos == 0) else if (ReadIndex == 0)
InputPosWrite = 0x100; InputPosWrite = 0x100;
if (InputDataLeft >= 0x100) if (InputDataLeft >= 0x100)
@ -123,7 +134,7 @@ StereoOut32 V_Core::ReadInput()
} }
InputDataLeft = 0; InputDataLeft = 0;
DMAICounter = 0x200 * 4; DMAICounter = InputDataTransferred * 4;
LastClock = *cyclePtr; LastClock = *cyclePtr;
} }
} }

View File

@ -406,6 +406,7 @@ struct V_Core
s32 DMAICounter; // DMA Interrupt Counter s32 DMAICounter; // DMA Interrupt Counter
u32 LastClock; // DMA Interrupt Clock Cycle Counter u32 LastClock; // DMA Interrupt Clock Cycle Counter
u32 InputDataLeft; // Input Buffer u32 InputDataLeft; // Input Buffer
u32 InputDataTransferred; // Used for simulating MADR increase (GTA VC)
u32 InputPosWrite; u32 InputPosWrite;
u32 InputDataProgress; u32 InputDataProgress;

View File

@ -134,8 +134,9 @@ void V_Core::Init(int index)
NoiseOut = 0; NoiseOut = 0;
AutoDMACtrl = 0; AutoDMACtrl = 0;
InputDataLeft = 0; InputDataLeft = 0;
InputPosWrite = 0; InputPosWrite = 0x100;
InputDataProgress = 0; InputDataProgress = 0;
InputDataTransferred = 0;
ReverbX = 0; ReverbX = 0;
LastEffect.Left = 0; LastEffect.Left = 0;
LastEffect.Right = 0; LastEffect.Right = 0;
@ -1530,6 +1531,7 @@ static void __fastcall RegWrite_Core(u16 value)
thiscore.AdmaInProgress = 0; thiscore.AdmaInProgress = 0;
thiscore.InputDataLeft = 0; thiscore.InputDataLeft = 0;
thiscore.DMAICounter = 0; thiscore.DMAICounter = 0;
thiscore.InputDataTransferred = 0;
} }
break; break;

View File

@ -24,7 +24,7 @@
// the lower 16 bit value. IF the change is breaking of all compatibility with old // 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. // 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 // 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. :) // between the GS saving function and the MTGS's needs. :)