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:
nitsuja 2011-12-17 16:56:23 -08:00
parent c68c8c388c
commit 1e4e05fdc3
16 changed files with 88 additions and 41 deletions

View File

@ -131,7 +131,51 @@ void DSPHLE::SwapUCode(u32 _crc)
void DSPHLE::DoState(PointerWrap &p)
{
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

View File

@ -28,9 +28,8 @@
#include "UCode_AX_Voice.h"
CUCode_AX::CUCode_AX(DSPHLE *dsp_hle, u32 l_CRC)
: IUCode(dsp_hle)
: IUCode(dsp_hle, l_CRC)
, m_addressPBs(0xFFFFFFFF)
, _CRC(l_CRC)
{
// we got loaded
m_rMailHandler.PushMail(DSP_INIT);
@ -175,7 +174,7 @@ void CUCode_AX::MixAdd(short* _pBuffer, int _iSize)
ProcessUpdates(PB);
if (_CRC != 0x3389a79e)
if (m_CRC != 0x3389a79e)
VoiceHacks(PB);
MixAddVoice(PB, templbuffer, temprbuffer, _iSize);
@ -463,11 +462,8 @@ void CUCode_AX::DoState(PointerWrap &p)
{
std::lock_guard<std::mutex> lk(m_csMix);
p.Do(_CRC);
p.Do(numPBaddr);
p.Do(m_addressPBs);
p.Do(PBaddr);
p.Do(m_UploadSetupInProgress);
m_rMailHandler.DoState(p);
}

View File

@ -41,7 +41,6 @@ public:
u8 numPBaddr;
u32 PBaddr[8]; //2 needed for MP2
u32 m_addressPBs;
u32 _CRC;
private:
enum

View File

@ -28,9 +28,8 @@
CUCode_AXWii::CUCode_AXWii(DSPHLE *dsp_hle, u32 l_CRC)
: IUCode(dsp_hle)
: IUCode(dsp_hle, l_CRC)
, m_addressPBs(0xFFFFFFFF)
, _CRC(l_CRC)
{
// we got loaded
m_rMailHandler.PushMail(DSP_INIT);
@ -38,7 +37,7 @@ CUCode_AXWii::CUCode_AXWii(DSPHLE *dsp_hle, u32 l_CRC)
templbuffer = new int[1024 * 1024];
temprbuffer = new int[1024 * 1024];
wiisportsHack = _CRC == 0xfa450138;
wiisportsHack = m_CRC == 0xfa450138;
}
CUCode_AXWii::~CUCode_AXWii()
@ -260,10 +259,7 @@ void CUCode_AXWii::DoState(PointerWrap &p)
{
std::lock_guard<std::mutex> lk(m_csMix);
p.Do(_CRC);
p.Do(m_addressPBs);
p.Do(wiisportsHack);
p.Do(m_UploadSetupInProgress);
m_rMailHandler.DoState(p);
}

View File

@ -21,8 +21,8 @@
#include "../../DSP.h"
CUCode_CARD::CUCode_CARD(DSPHLE *dsp_hle)
: IUCode(dsp_hle)
CUCode_CARD::CUCode_CARD(DSPHLE *dsp_hle, u32 crc)
: IUCode(dsp_hle, crc)
{
DEBUG_LOG(DSPHLE, "CUCode_CARD - initialized");
m_rMailHandler.PushMail(DSP_INIT);

View File

@ -23,7 +23,7 @@
class CUCode_CARD : public IUCode
{
public:
CUCode_CARD(DSPHLE *dsp_hle);
CUCode_CARD(DSPHLE *dsp_hle, u32 crc);
virtual ~CUCode_CARD();
void HandleMail(u32 _uMail);

View File

@ -20,8 +20,8 @@
#include "../../DSP.h"
CUCode_GBA::CUCode_GBA(DSPHLE *dsp_hle)
: IUCode(dsp_hle)
CUCode_GBA::CUCode_GBA(DSPHLE *dsp_hle, u32 crc)
: IUCode(dsp_hle, crc)
{
m_rMailHandler.PushMail(DSP_INIT);
}

View File

@ -21,7 +21,7 @@
struct CUCode_GBA : public IUCode
{
CUCode_GBA(DSPHLE *dsp_hle);
CUCode_GBA(DSPHLE *dsp_hle, u32 crc);
virtual ~CUCode_GBA();
void HandleMail(u32 _uMail);

View File

@ -18,8 +18,8 @@
#include "UCodes.h"
#include "UCode_InitAudioSystem.h"
CUCode_InitAudioSystem::CUCode_InitAudioSystem(DSPHLE *dsp_hle)
: IUCode(dsp_hle)
CUCode_InitAudioSystem::CUCode_InitAudioSystem(DSPHLE *dsp_hle, u32 crc)
: IUCode(dsp_hle, crc)
{
DEBUG_LOG(DSPHLE, "CUCode_InitAudioSystem - initialized");
}

View File

@ -23,7 +23,7 @@
class CUCode_InitAudioSystem : public IUCode
{
public:
CUCode_InitAudioSystem(DSPHLE *dsp_hle);
CUCode_InitAudioSystem(DSPHLE *dsp_hle, u32 crc);
virtual ~CUCode_InitAudioSystem();
void HandleMail(u32 _uMail);

View File

@ -20,8 +20,8 @@
#include "Hash.h"
#include "../../Memmap.h"
CUCode_Rom::CUCode_Rom(DSPHLE *dsp_hle)
: IUCode(dsp_hle)
CUCode_Rom::CUCode_Rom(DSPHLE *dsp_hle, u32 crc)
: IUCode(dsp_hle, crc)
, m_CurrentUCode()
, m_BootTask_numSteps(0)
, m_NextParameter(0)
@ -117,4 +117,10 @@ void CUCode_Rom::BootUCode()
m_DSPHLE->SetUCode(ector_crc);
}
void CUCode_Rom::DoState(PointerWrap &p)
{
p.Do(m_CurrentUCode);
p.Do(m_BootTask_numSteps);
p.Do(m_NextParameter);
}

View File

@ -23,12 +23,14 @@
class CUCode_Rom : public IUCode
{
public:
CUCode_Rom(DSPHLE *dsp_hle);
CUCode_Rom(DSPHLE *dsp_hle, u32 _crc);
virtual ~CUCode_Rom();
void HandleMail(u32 _uMail);
void Update(int cycles);
void DoState(PointerWrap &p);
private:
struct SUCode
{

View File

@ -31,8 +31,7 @@
CUCode_Zelda::CUCode_Zelda(DSPHLE *dsp_hle, u32 _CRC)
:
IUCode(dsp_hle),
m_CRC(_CRC),
IUCode(dsp_hle, _CRC),
m_bSyncInProgress(false),
m_MaxVoice(0),
@ -572,8 +571,6 @@ void CUCode_Zelda::DoState(PointerWrap &p)
// It's bad if we try to save during Mix()
std::lock_guard<std::mutex> lk(m_csMix);
p.Do(m_CRC);
p.Do(m_AFCCoefTable);
p.Do(m_MiscTable);
@ -616,6 +613,4 @@ void CUCode_Zelda::DoState(PointerWrap &p)
p.Do(m_PBAddress2);
p.Do(m_UploadSetupInProgress);
m_rMailHandler.DoState(p);
}

View File

@ -212,8 +212,6 @@ private:
}
}
u32 m_CRC;
// These are the only dynamically allocated things allowed in the ucode.
s32* m_VoiceBuffer;
s16* m_ResampleBuffer;

View File

@ -32,19 +32,19 @@ IUCode* UCodeFactory(u32 _CRC, DSPHLE *dsp_hle, bool bWii)
{
case UCODE_ROM:
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:
INFO_LOG(DSPHLE, "Switching to INIT ucode");
return new CUCode_InitAudioSystem(dsp_hle);
return new CUCode_InitAudioSystem(dsp_hle, _CRC);
case 0x65d6cc6f: // CARD
INFO_LOG(DSPHLE, "Switching to CARD ucode");
return new CUCode_CARD(dsp_hle);
return new CUCode_CARD(dsp_hle, _CRC);
case 0xdd7e72d5:
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 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);
return new CUCode_AX(dsp_hle, _CRC);
}
case UCODE_NULL:
break;
}
return NULL;

View File

@ -25,8 +25,9 @@
#include "../DSPHLE.h"
#include "../../Memmap.h"
#define UCODE_ROM 0x0000000
#define UCODE_INIT_AUDIO_SYSTEM 0x0000001
#define UCODE_ROM 0x00000000
#define UCODE_INIT_AUDIO_SYSTEM 0x00000001
#define UCODE_NULL 0xFFFFFFFF
class CMailHandler;
@ -73,10 +74,11 @@ inline void* HLEMemory_Get_Pointer(u32 _uAddress)
class IUCode
{
public:
IUCode(DSPHLE *dsphle)
IUCode(DSPHLE *dsphle, u32 _crc)
: m_rMailHandler(dsphle->AccessMailHandler())
, m_UploadSetupInProgress(false)
, m_DSPHLE(dsphle)
, m_CRC(_crc)
, m_NextUCode()
, m_NextUCode_steps(0)
, m_NeedsResumeMail(false)
@ -93,6 +95,8 @@ public:
virtual void DoState(PointerWrap &p) {}
static u32 GetCRC(IUCode* pUCode) { return pUCode ? pUCode->m_CRC : UCODE_NULL; }
protected:
void PrepareBootUCode(u32 mail);
@ -121,6 +125,10 @@ protected:
// Need a pointer back to DSPHLE to switch ucodes.
DSPHLE *m_DSPHLE;
// used for reconstruction when loading saves,
// and for variations within certain ucodes.
u32 m_CRC;
private:
struct SUCode
{