SPU2: Store DMA pointers as offsets in save state

[SAVEVERSION+] Sadly need to bump save state, don't want to have a mess
of different version handling here.
This commit is contained in:
Stenzek 2023-04-09 16:17:48 +10:00 committed by refractionpcsx2
parent d9f537e9dc
commit f26cc38b80
2 changed files with 47 additions and 10 deletions

View File

@ -14,8 +14,9 @@
*/
#include "PrecompiledHeader.h"
#include "Global.h"
#include "spu2.h" // hopefully temporary, until I resolve lClocks depdendency
#include "SPU2/Global.h"
#include "SPU2/spu2.h" // hopefully temporary, until I resolve lClocks depdendency
#include "IopMem.h"
namespace SPU2Savestate
{
@ -63,6 +64,28 @@ s32 SPU2Savestate::FreezeIt(DataBlock& spud)
memcpy(spud.Cores, Cores, sizeof(Cores));
memcpy(&spud.Spdif, &Spdif, sizeof(Spdif));
// Convert pointers to offsets so we can safely restore them when loading.
// We use -1 for null, and anything else as an offset from iop memory.
#define FIX_POINTER(x) \
if (!(x)) \
{ \
x = reinterpret_cast<decltype(x)>(-1); \
} \
else \
{ \
pxAssert(reinterpret_cast<const u8*>((x)) >= iopPhysMem(0) && reinterpret_cast<const u8*>((x)) < iopPhysMem(0x1fffff)); \
x = reinterpret_cast<decltype(x)>(reinterpret_cast<const u8*>((x)) - iopPhysMem(0)); \
}
for (u32 i = 0; i < 2; i++)
{
V_Core& core = spud.Cores[i];
FIX_POINTER(core.DMAPtr);
FIX_POINTER(core.DMARPtr);
}
#undef FIX_POINTER
spud.OutPos = OutPos;
spud.InputPos = InputPos;
spud.Cycles = Cycles;
@ -115,6 +138,27 @@ s32 SPU2Savestate::ThawIt(DataBlock& spud)
memcpy(Cores, spud.Cores, sizeof(Cores));
memcpy(&Spdif, &spud.Spdif, sizeof(Spdif));
// Reverse the pointer offset from above.
#define FIX_POINTER(x) \
if ((x) == reinterpret_cast<decltype(x)>(-1)) \
{ \
x = nullptr; \
} \
else \
{ \
pxAssert(reinterpret_cast<size_t>((x)) <= 0x1fffff); \
x = reinterpret_cast<decltype(x)>(iopPhysMem(0) + reinterpret_cast<size_t>((x))); \
}
for (u32 i = 0; i < 2; i++)
{
V_Core& core = spud.Cores[i];
FIX_POINTER(core.DMAPtr);
FIX_POINTER(core.DMARPtr);
}
#undef FIX_POINTER
OutPos = spud.OutPos;
InputPos = spud.InputPos;
Cycles = spud.Cycles;
@ -134,13 +178,6 @@ s32 SPU2Savestate::ThawIt(DataBlock& spud)
Cores[c].Voices[v].SBuffer = pcm_cache_data[cacheIdx].Sampledata;
}
}
// HACKFIX!! DMAPtr can be invalid after a savestate load, so force it to nullptr and
// ignore it on any pending ADMA writes. (the DMAPtr concept used to work in old VM
// editions of PCSX2 with fixed addressing, but new PCSX2s have dynamic memory
// addressing).
Cores[0].DMAPtr = Cores[1].DMAPtr = nullptr;
}
return 0;
}

View File

@ -36,7 +36,7 @@ enum class FreezeAction
// [SAVEVERSION+]
// This informs the auto updater that the users savestates will be invalidated.
static const u32 g_SaveVersion = (0x9A34 << 16) | 0x0000;
static const u32 g_SaveVersion = (0x9A35 << 16) | 0x0000;
// the freezing data between submodules and core