mirror of https://github.com/PCSX2/pcsx2.git
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:
parent
d9f537e9dc
commit
f26cc38b80
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue