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)
memcpy(GetMemPtr(0x2000 + (Index << 10) + spos), DMAPtr + InputDataProgress, 0x200);
MADR += 0x200;
InputDataTransferred += 0x200;
InputDataLeft -= 0x100;
InputDataProgress += 0x100;
leftbuffer = !leftbuffer;

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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. :)