made ucode saving more reliable (especially for the case of loading across boundaries where the ucode changes). I think this is related to the occasional memory corruption I was seeing upon loading a savestate.
This commit is contained in:
parent
c68c8c388c
commit
1e4e05fdc3
|
@ -131,7 +131,51 @@ void DSPHLE::SwapUCode(u32 _crc)
|
||||||
void DSPHLE::DoState(PointerWrap &p)
|
void DSPHLE::DoState(PointerWrap &p)
|
||||||
{
|
{
|
||||||
p.Do(m_InitMixer);
|
p.Do(m_InitMixer);
|
||||||
GetUCode()->DoState(p);
|
p.Do(m_DSPControl);
|
||||||
|
p.Do(m_dspState);
|
||||||
|
|
||||||
|
int ucode_crc = IUCode::GetCRC(m_pUCode);
|
||||||
|
int ucode_crc_beforeLoad = ucode_crc;
|
||||||
|
int lastucode_crc = IUCode::GetCRC(m_lastUCode);
|
||||||
|
int lastucode_crc_beforeLoad = lastucode_crc;
|
||||||
|
|
||||||
|
p.Do(ucode_crc);
|
||||||
|
p.Do(lastucode_crc);
|
||||||
|
|
||||||
|
// if a different type of ucode was being used when the savestate was created,
|
||||||
|
// we have to reconstruct the old type of ucode so that we have a valid thing to call DoState on.
|
||||||
|
IUCode* ucode = (ucode_crc == ucode_crc_beforeLoad) ? m_pUCode : UCodeFactory( ucode_crc, this, m_bWii);
|
||||||
|
IUCode* lastucode = (lastucode_crc != lastucode_crc_beforeLoad) ? m_lastUCode : UCodeFactory(lastucode_crc, this, m_bWii);
|
||||||
|
|
||||||
|
if (ucode)
|
||||||
|
ucode->DoState(p);
|
||||||
|
if (lastucode)
|
||||||
|
lastucode->DoState(p);
|
||||||
|
|
||||||
|
// if a different type of ucode was being used when the savestate was created,
|
||||||
|
// discard it if we're not loading, otherwise discard the old one and keep the new one.
|
||||||
|
if (ucode != m_pUCode)
|
||||||
|
{
|
||||||
|
if (p.GetMode() != PointerWrap::MODE_READ)
|
||||||
|
delete ucode;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
delete m_pUCode;
|
||||||
|
m_pUCode = ucode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (lastucode != m_lastUCode)
|
||||||
|
{
|
||||||
|
if (p.GetMode() != PointerWrap::MODE_READ)
|
||||||
|
delete lastucode;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
delete m_lastUCode;
|
||||||
|
m_lastUCode = lastucode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_MailHandler.DoState(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mailbox fuctions
|
// Mailbox fuctions
|
||||||
|
|
|
@ -28,9 +28,8 @@
|
||||||
#include "UCode_AX_Voice.h"
|
#include "UCode_AX_Voice.h"
|
||||||
|
|
||||||
CUCode_AX::CUCode_AX(DSPHLE *dsp_hle, u32 l_CRC)
|
CUCode_AX::CUCode_AX(DSPHLE *dsp_hle, u32 l_CRC)
|
||||||
: IUCode(dsp_hle)
|
: IUCode(dsp_hle, l_CRC)
|
||||||
, m_addressPBs(0xFFFFFFFF)
|
, m_addressPBs(0xFFFFFFFF)
|
||||||
, _CRC(l_CRC)
|
|
||||||
{
|
{
|
||||||
// we got loaded
|
// we got loaded
|
||||||
m_rMailHandler.PushMail(DSP_INIT);
|
m_rMailHandler.PushMail(DSP_INIT);
|
||||||
|
@ -175,7 +174,7 @@ void CUCode_AX::MixAdd(short* _pBuffer, int _iSize)
|
||||||
|
|
||||||
ProcessUpdates(PB);
|
ProcessUpdates(PB);
|
||||||
|
|
||||||
if (_CRC != 0x3389a79e)
|
if (m_CRC != 0x3389a79e)
|
||||||
VoiceHacks(PB);
|
VoiceHacks(PB);
|
||||||
|
|
||||||
MixAddVoice(PB, templbuffer, temprbuffer, _iSize);
|
MixAddVoice(PB, templbuffer, temprbuffer, _iSize);
|
||||||
|
@ -463,11 +462,8 @@ void CUCode_AX::DoState(PointerWrap &p)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lk(m_csMix);
|
std::lock_guard<std::mutex> lk(m_csMix);
|
||||||
|
|
||||||
p.Do(_CRC);
|
|
||||||
p.Do(numPBaddr);
|
p.Do(numPBaddr);
|
||||||
p.Do(m_addressPBs);
|
p.Do(m_addressPBs);
|
||||||
p.Do(PBaddr);
|
p.Do(PBaddr);
|
||||||
p.Do(m_UploadSetupInProgress);
|
p.Do(m_UploadSetupInProgress);
|
||||||
|
|
||||||
m_rMailHandler.DoState(p);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,6 @@ public:
|
||||||
u8 numPBaddr;
|
u8 numPBaddr;
|
||||||
u32 PBaddr[8]; //2 needed for MP2
|
u32 PBaddr[8]; //2 needed for MP2
|
||||||
u32 m_addressPBs;
|
u32 m_addressPBs;
|
||||||
u32 _CRC;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum
|
enum
|
||||||
|
|
|
@ -28,9 +28,8 @@
|
||||||
|
|
||||||
|
|
||||||
CUCode_AXWii::CUCode_AXWii(DSPHLE *dsp_hle, u32 l_CRC)
|
CUCode_AXWii::CUCode_AXWii(DSPHLE *dsp_hle, u32 l_CRC)
|
||||||
: IUCode(dsp_hle)
|
: IUCode(dsp_hle, l_CRC)
|
||||||
, m_addressPBs(0xFFFFFFFF)
|
, m_addressPBs(0xFFFFFFFF)
|
||||||
, _CRC(l_CRC)
|
|
||||||
{
|
{
|
||||||
// we got loaded
|
// we got loaded
|
||||||
m_rMailHandler.PushMail(DSP_INIT);
|
m_rMailHandler.PushMail(DSP_INIT);
|
||||||
|
@ -38,7 +37,7 @@ CUCode_AXWii::CUCode_AXWii(DSPHLE *dsp_hle, u32 l_CRC)
|
||||||
templbuffer = new int[1024 * 1024];
|
templbuffer = new int[1024 * 1024];
|
||||||
temprbuffer = new int[1024 * 1024];
|
temprbuffer = new int[1024 * 1024];
|
||||||
|
|
||||||
wiisportsHack = _CRC == 0xfa450138;
|
wiisportsHack = m_CRC == 0xfa450138;
|
||||||
}
|
}
|
||||||
|
|
||||||
CUCode_AXWii::~CUCode_AXWii()
|
CUCode_AXWii::~CUCode_AXWii()
|
||||||
|
@ -260,10 +259,7 @@ void CUCode_AXWii::DoState(PointerWrap &p)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lk(m_csMix);
|
std::lock_guard<std::mutex> lk(m_csMix);
|
||||||
|
|
||||||
p.Do(_CRC);
|
|
||||||
p.Do(m_addressPBs);
|
p.Do(m_addressPBs);
|
||||||
p.Do(wiisportsHack);
|
p.Do(wiisportsHack);
|
||||||
p.Do(m_UploadSetupInProgress);
|
p.Do(m_UploadSetupInProgress);
|
||||||
|
|
||||||
m_rMailHandler.DoState(p);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,8 +21,8 @@
|
||||||
#include "../../DSP.h"
|
#include "../../DSP.h"
|
||||||
|
|
||||||
|
|
||||||
CUCode_CARD::CUCode_CARD(DSPHLE *dsp_hle)
|
CUCode_CARD::CUCode_CARD(DSPHLE *dsp_hle, u32 crc)
|
||||||
: IUCode(dsp_hle)
|
: IUCode(dsp_hle, crc)
|
||||||
{
|
{
|
||||||
DEBUG_LOG(DSPHLE, "CUCode_CARD - initialized");
|
DEBUG_LOG(DSPHLE, "CUCode_CARD - initialized");
|
||||||
m_rMailHandler.PushMail(DSP_INIT);
|
m_rMailHandler.PushMail(DSP_INIT);
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
class CUCode_CARD : public IUCode
|
class CUCode_CARD : public IUCode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CUCode_CARD(DSPHLE *dsp_hle);
|
CUCode_CARD(DSPHLE *dsp_hle, u32 crc);
|
||||||
virtual ~CUCode_CARD();
|
virtual ~CUCode_CARD();
|
||||||
|
|
||||||
void HandleMail(u32 _uMail);
|
void HandleMail(u32 _uMail);
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
|
|
||||||
#include "../../DSP.h"
|
#include "../../DSP.h"
|
||||||
|
|
||||||
CUCode_GBA::CUCode_GBA(DSPHLE *dsp_hle)
|
CUCode_GBA::CUCode_GBA(DSPHLE *dsp_hle, u32 crc)
|
||||||
: IUCode(dsp_hle)
|
: IUCode(dsp_hle, crc)
|
||||||
{
|
{
|
||||||
m_rMailHandler.PushMail(DSP_INIT);
|
m_rMailHandler.PushMail(DSP_INIT);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
struct CUCode_GBA : public IUCode
|
struct CUCode_GBA : public IUCode
|
||||||
{
|
{
|
||||||
CUCode_GBA(DSPHLE *dsp_hle);
|
CUCode_GBA(DSPHLE *dsp_hle, u32 crc);
|
||||||
virtual ~CUCode_GBA();
|
virtual ~CUCode_GBA();
|
||||||
|
|
||||||
void HandleMail(u32 _uMail);
|
void HandleMail(u32 _uMail);
|
||||||
|
|
|
@ -18,8 +18,8 @@
|
||||||
#include "UCodes.h"
|
#include "UCodes.h"
|
||||||
#include "UCode_InitAudioSystem.h"
|
#include "UCode_InitAudioSystem.h"
|
||||||
|
|
||||||
CUCode_InitAudioSystem::CUCode_InitAudioSystem(DSPHLE *dsp_hle)
|
CUCode_InitAudioSystem::CUCode_InitAudioSystem(DSPHLE *dsp_hle, u32 crc)
|
||||||
: IUCode(dsp_hle)
|
: IUCode(dsp_hle, crc)
|
||||||
{
|
{
|
||||||
DEBUG_LOG(DSPHLE, "CUCode_InitAudioSystem - initialized");
|
DEBUG_LOG(DSPHLE, "CUCode_InitAudioSystem - initialized");
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
class CUCode_InitAudioSystem : public IUCode
|
class CUCode_InitAudioSystem : public IUCode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CUCode_InitAudioSystem(DSPHLE *dsp_hle);
|
CUCode_InitAudioSystem(DSPHLE *dsp_hle, u32 crc);
|
||||||
virtual ~CUCode_InitAudioSystem();
|
virtual ~CUCode_InitAudioSystem();
|
||||||
|
|
||||||
void HandleMail(u32 _uMail);
|
void HandleMail(u32 _uMail);
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
#include "Hash.h"
|
#include "Hash.h"
|
||||||
#include "../../Memmap.h"
|
#include "../../Memmap.h"
|
||||||
|
|
||||||
CUCode_Rom::CUCode_Rom(DSPHLE *dsp_hle)
|
CUCode_Rom::CUCode_Rom(DSPHLE *dsp_hle, u32 crc)
|
||||||
: IUCode(dsp_hle)
|
: IUCode(dsp_hle, crc)
|
||||||
, m_CurrentUCode()
|
, m_CurrentUCode()
|
||||||
, m_BootTask_numSteps(0)
|
, m_BootTask_numSteps(0)
|
||||||
, m_NextParameter(0)
|
, m_NextParameter(0)
|
||||||
|
@ -117,4 +117,10 @@ void CUCode_Rom::BootUCode()
|
||||||
m_DSPHLE->SetUCode(ector_crc);
|
m_DSPHLE->SetUCode(ector_crc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CUCode_Rom::DoState(PointerWrap &p)
|
||||||
|
{
|
||||||
|
p.Do(m_CurrentUCode);
|
||||||
|
p.Do(m_BootTask_numSteps);
|
||||||
|
p.Do(m_NextParameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,12 +23,14 @@
|
||||||
class CUCode_Rom : public IUCode
|
class CUCode_Rom : public IUCode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CUCode_Rom(DSPHLE *dsp_hle);
|
CUCode_Rom(DSPHLE *dsp_hle, u32 _crc);
|
||||||
virtual ~CUCode_Rom();
|
virtual ~CUCode_Rom();
|
||||||
|
|
||||||
void HandleMail(u32 _uMail);
|
void HandleMail(u32 _uMail);
|
||||||
void Update(int cycles);
|
void Update(int cycles);
|
||||||
|
|
||||||
|
void DoState(PointerWrap &p);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct SUCode
|
struct SUCode
|
||||||
{
|
{
|
||||||
|
|
|
@ -31,8 +31,7 @@
|
||||||
|
|
||||||
CUCode_Zelda::CUCode_Zelda(DSPHLE *dsp_hle, u32 _CRC)
|
CUCode_Zelda::CUCode_Zelda(DSPHLE *dsp_hle, u32 _CRC)
|
||||||
:
|
:
|
||||||
IUCode(dsp_hle),
|
IUCode(dsp_hle, _CRC),
|
||||||
m_CRC(_CRC),
|
|
||||||
|
|
||||||
m_bSyncInProgress(false),
|
m_bSyncInProgress(false),
|
||||||
m_MaxVoice(0),
|
m_MaxVoice(0),
|
||||||
|
@ -572,8 +571,6 @@ void CUCode_Zelda::DoState(PointerWrap &p)
|
||||||
// It's bad if we try to save during Mix()
|
// It's bad if we try to save during Mix()
|
||||||
std::lock_guard<std::mutex> lk(m_csMix);
|
std::lock_guard<std::mutex> lk(m_csMix);
|
||||||
|
|
||||||
p.Do(m_CRC);
|
|
||||||
|
|
||||||
p.Do(m_AFCCoefTable);
|
p.Do(m_AFCCoefTable);
|
||||||
p.Do(m_MiscTable);
|
p.Do(m_MiscTable);
|
||||||
|
|
||||||
|
@ -616,6 +613,4 @@ void CUCode_Zelda::DoState(PointerWrap &p)
|
||||||
p.Do(m_PBAddress2);
|
p.Do(m_PBAddress2);
|
||||||
|
|
||||||
p.Do(m_UploadSetupInProgress);
|
p.Do(m_UploadSetupInProgress);
|
||||||
|
|
||||||
m_rMailHandler.DoState(p);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -212,8 +212,6 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 m_CRC;
|
|
||||||
|
|
||||||
// These are the only dynamically allocated things allowed in the ucode.
|
// These are the only dynamically allocated things allowed in the ucode.
|
||||||
s32* m_VoiceBuffer;
|
s32* m_VoiceBuffer;
|
||||||
s16* m_ResampleBuffer;
|
s16* m_ResampleBuffer;
|
||||||
|
|
|
@ -32,19 +32,19 @@ IUCode* UCodeFactory(u32 _CRC, DSPHLE *dsp_hle, bool bWii)
|
||||||
{
|
{
|
||||||
case UCODE_ROM:
|
case UCODE_ROM:
|
||||||
INFO_LOG(DSPHLE, "Switching to ROM ucode");
|
INFO_LOG(DSPHLE, "Switching to ROM ucode");
|
||||||
return new CUCode_Rom(dsp_hle);
|
return new CUCode_Rom(dsp_hle, _CRC);
|
||||||
|
|
||||||
case UCODE_INIT_AUDIO_SYSTEM:
|
case UCODE_INIT_AUDIO_SYSTEM:
|
||||||
INFO_LOG(DSPHLE, "Switching to INIT ucode");
|
INFO_LOG(DSPHLE, "Switching to INIT ucode");
|
||||||
return new CUCode_InitAudioSystem(dsp_hle);
|
return new CUCode_InitAudioSystem(dsp_hle, _CRC);
|
||||||
|
|
||||||
case 0x65d6cc6f: // CARD
|
case 0x65d6cc6f: // CARD
|
||||||
INFO_LOG(DSPHLE, "Switching to CARD ucode");
|
INFO_LOG(DSPHLE, "Switching to CARD ucode");
|
||||||
return new CUCode_CARD(dsp_hle);
|
return new CUCode_CARD(dsp_hle, _CRC);
|
||||||
|
|
||||||
case 0xdd7e72d5:
|
case 0xdd7e72d5:
|
||||||
INFO_LOG(DSPHLE, "Switching to GBA ucode");
|
INFO_LOG(DSPHLE, "Switching to GBA ucode");
|
||||||
return new CUCode_GBA(dsp_hle);
|
return new CUCode_GBA(dsp_hle, _CRC);
|
||||||
|
|
||||||
case 0x3ad3b7ac: // Naruto3, Paper Mario - The Thousand Year Door
|
case 0x3ad3b7ac: // Naruto3, Paper Mario - The Thousand Year Door
|
||||||
case 0x3daf59b9: // Alien Hominid
|
case 0x3daf59b9: // Alien Hominid
|
||||||
|
@ -103,6 +103,9 @@ IUCode* UCodeFactory(u32 _CRC, DSPHLE *dsp_hle, bool bWii)
|
||||||
PanicAlert("DSPHLE: Unknown ucode (CRC = %08x) - forcing AX.\n\nTry LLE emulator if this is homebrew.", _CRC);
|
PanicAlert("DSPHLE: Unknown ucode (CRC = %08x) - forcing AX.\n\nTry LLE emulator if this is homebrew.", _CRC);
|
||||||
return new CUCode_AX(dsp_hle, _CRC);
|
return new CUCode_AX(dsp_hle, _CRC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case UCODE_NULL:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -25,8 +25,9 @@
|
||||||
#include "../DSPHLE.h"
|
#include "../DSPHLE.h"
|
||||||
#include "../../Memmap.h"
|
#include "../../Memmap.h"
|
||||||
|
|
||||||
#define UCODE_ROM 0x0000000
|
#define UCODE_ROM 0x00000000
|
||||||
#define UCODE_INIT_AUDIO_SYSTEM 0x0000001
|
#define UCODE_INIT_AUDIO_SYSTEM 0x00000001
|
||||||
|
#define UCODE_NULL 0xFFFFFFFF
|
||||||
|
|
||||||
class CMailHandler;
|
class CMailHandler;
|
||||||
|
|
||||||
|
@ -73,10 +74,11 @@ inline void* HLEMemory_Get_Pointer(u32 _uAddress)
|
||||||
class IUCode
|
class IUCode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IUCode(DSPHLE *dsphle)
|
IUCode(DSPHLE *dsphle, u32 _crc)
|
||||||
: m_rMailHandler(dsphle->AccessMailHandler())
|
: m_rMailHandler(dsphle->AccessMailHandler())
|
||||||
, m_UploadSetupInProgress(false)
|
, m_UploadSetupInProgress(false)
|
||||||
, m_DSPHLE(dsphle)
|
, m_DSPHLE(dsphle)
|
||||||
|
, m_CRC(_crc)
|
||||||
, m_NextUCode()
|
, m_NextUCode()
|
||||||
, m_NextUCode_steps(0)
|
, m_NextUCode_steps(0)
|
||||||
, m_NeedsResumeMail(false)
|
, m_NeedsResumeMail(false)
|
||||||
|
@ -93,6 +95,8 @@ public:
|
||||||
|
|
||||||
virtual void DoState(PointerWrap &p) {}
|
virtual void DoState(PointerWrap &p) {}
|
||||||
|
|
||||||
|
static u32 GetCRC(IUCode* pUCode) { return pUCode ? pUCode->m_CRC : UCODE_NULL; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void PrepareBootUCode(u32 mail);
|
void PrepareBootUCode(u32 mail);
|
||||||
|
|
||||||
|
@ -121,6 +125,10 @@ protected:
|
||||||
// Need a pointer back to DSPHLE to switch ucodes.
|
// Need a pointer back to DSPHLE to switch ucodes.
|
||||||
DSPHLE *m_DSPHLE;
|
DSPHLE *m_DSPHLE;
|
||||||
|
|
||||||
|
// used for reconstruction when loading saves,
|
||||||
|
// and for variations within certain ucodes.
|
||||||
|
u32 m_CRC;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct SUCode
|
struct SUCode
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue