summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authornitsuja <nitsuja-@hotmail.com>2011-12-17 16:56:23 -0800
committernitsuja <nitsuja-@hotmail.com>2011-12-18 00:22:21 -0800
commit1e4e05fdc3475a7873ec2806cad00a8671201a23 (patch)
tree84598fa389c6f5d5e94493d8b0e01b97c1f356e2 /Source/Core
parentc68c8c388cc29cfd4e97be8fc7f5ea7534508672 (diff)
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.
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/Src/HW/DSPHLE/DSPHLE.cpp46
-rw-r--r--Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_AX.cpp8
-rw-r--r--Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_AX.h1
-rw-r--r--Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_AXWii.cpp8
-rw-r--r--Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_CARD.cpp4
-rw-r--r--Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_CARD.h2
-rw-r--r--Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_GBA.cpp4
-rw-r--r--Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_GBA.h2
-rw-r--r--Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_InitAudioSystem.cpp4
-rw-r--r--Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_InitAudioSystem.h2
-rw-r--r--Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_ROM.cpp10
-rw-r--r--Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_ROM.h4
-rw-r--r--Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_Zelda.cpp7
-rw-r--r--Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_Zelda.h2
-rw-r--r--Source/Core/Core/Src/HW/DSPHLE/UCodes/UCodes.cpp11
-rw-r--r--Source/Core/Core/Src/HW/DSPHLE/UCodes/UCodes.h14
16 files changed, 88 insertions, 41 deletions
diff --git a/Source/Core/Core/Src/HW/DSPHLE/DSPHLE.cpp b/Source/Core/Core/Src/HW/DSPHLE/DSPHLE.cpp
index 069bbedc63..65362a19a0 100644
--- a/Source/Core/Core/Src/HW/DSPHLE/DSPHLE.cpp
+++ b/Source/Core/Core/Src/HW/DSPHLE/DSPHLE.cpp
@@ -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
diff --git a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_AX.cpp b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_AX.cpp
index 8c88217494..33f0d2f1e6 100644
--- a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_AX.cpp
+++ b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_AX.cpp
@@ -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);
}
diff --git a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_AX.h b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_AX.h
index 6386e3ce6a..edb52a2801 100644
--- a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_AX.h
+++ b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_AX.h
@@ -41,7 +41,6 @@ public:
u8 numPBaddr;
u32 PBaddr[8]; //2 needed for MP2
u32 m_addressPBs;
- u32 _CRC;
private:
enum
diff --git a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_AXWii.cpp b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_AXWii.cpp
index 41f044f9be..6300b35b4a 100644
--- a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_AXWii.cpp
+++ b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_AXWii.cpp
@@ -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);
}
diff --git a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_CARD.cpp b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_CARD.cpp
index 442d77ab85..dcd4e24e3f 100644
--- a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_CARD.cpp
+++ b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_CARD.cpp
@@ -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);
diff --git a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_CARD.h b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_CARD.h
index 0246d4680a..a6f90124ad 100644
--- a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_CARD.h
+++ b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_CARD.h
@@ -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);
diff --git a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_GBA.cpp b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_GBA.cpp
index b82c7ac0b2..42bc18ff49 100644
--- a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_GBA.cpp
+++ b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_GBA.cpp
@@ -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);
}
diff --git a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_GBA.h b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_GBA.h
index 412036835d..c61917339f 100644
--- a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_GBA.h
+++ b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_GBA.h
@@ -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);
diff --git a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_InitAudioSystem.cpp b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_InitAudioSystem.cpp
index 663d4beadd..ae7716012a 100644
--- a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_InitAudioSystem.cpp
+++ b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_InitAudioSystem.cpp
@@ -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");
}
diff --git a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_InitAudioSystem.h b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_InitAudioSystem.h
index 09b54a4a4b..8dc237f1d0 100644
--- a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_InitAudioSystem.h
+++ b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_InitAudioSystem.h
@@ -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);
diff --git a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_ROM.cpp b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_ROM.cpp
index 48dba7e28b..c1544792f5 100644
--- a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_ROM.cpp
+++ b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_ROM.cpp
@@ -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);
+}
diff --git a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_ROM.h b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_ROM.h
index ecec9f87ea..f1e7b8ec7a 100644
--- a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_ROM.h
+++ b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_ROM.h
@@ -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
{
diff --git a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_Zelda.cpp b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_Zelda.cpp
index 913de7107b..713236180d 100644
--- a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_Zelda.cpp
+++ b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_Zelda.cpp
@@ -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);
}
diff --git a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_Zelda.h b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_Zelda.h
index 3abe711c5b..f8a69536c2 100644
--- a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_Zelda.h
+++ b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_Zelda.h
@@ -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;
diff --git a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCodes.cpp b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCodes.cpp
index c982b97f51..62620253aa 100644
--- a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCodes.cpp
+++ b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCodes.cpp
@@ -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;
diff --git a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCodes.h b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCodes.h
index cb3bc6a4f0..faea895609 100644
--- a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCodes.h
+++ b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCodes.h
@@ -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
{