Save states - more boring groundwork. Far from done.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@263 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
hrydgard
2008-08-21 23:28:07 +00:00
parent 28edd4d31b
commit 465ee5fd86
45 changed files with 677 additions and 87 deletions

View File

@ -1174,6 +1174,14 @@
RelativePath=".\Src\SConscript"
>
</File>
<File
RelativePath=".\Src\State.cpp"
>
</File>
<File
RelativePath=".\Src\State.h"
>
</File>
<File
RelativePath=".\Src\stdafx.cpp"
>

View File

@ -61,7 +61,7 @@ int RegisterEvent(const char *name, TimedCallback callback)
type.name = name;
type.callback = callback;
event_types.push_back(type);
return event_types.size() - 1;
return (int)event_types.size() - 1;
}
void UnregisterAllEvents()
@ -71,6 +71,18 @@ void UnregisterAllEvents()
event_types.clear();
}
void DoState(ChunkFile &f)
{
externalEventSection.Enter();
f.Descend("TIME");
f.Do(downcount);
f.Do(slicelength);
f.Do(maxSliceLength);
f.Do(globalTimer);
f.Do(idledCycles);
f.Ascend();
externalEventSection.Leave();
}
u64 GetTicks()
{

View File

@ -25,6 +25,7 @@
// callback. You then schedule events using the type id you get back.
#include "Common.h"
#include "ChunkFile.h"
namespace CoreTiming
{
@ -34,6 +35,7 @@ typedef void (*TimedCallback)(u64 userdata, int cyclesLate);
u64 GetTicks();
u64 GetIdleTicks();
void DoState(ChunkFile &f);
// The int that the callbacks get is how many cycles late it was.
// So to schedule a new event on a regular basis:
// inside callback:

View File

@ -87,18 +87,29 @@ struct SAudioRegister
u32 m_InterruptTiming;
};
SAudioRegister g_AudioRegister;
// STATE_TO_SAVE
static SAudioRegister g_AudioRegister;
static u64 g_LastCPUTime = 0;
static int g_SampleRate = 32000;
static int g_DSPSampleRate = 32000;
static u64 g_CPUCyclesPerSample = 0xFFFFFFFFFFFULL;
void DoState(ChunkFile &f)
{
f.Descend("AI ");
f.Do(g_AudioRegister);
f.Do(g_LastCPUTime);
f.Do(g_SampleRate);
f.Do(g_DSPSampleRate);
f.Do(g_CPUCyclesPerSample);
f.Ascend();
}
void GenerateAudioInterrupt();
void UpdateInterrupts();
void IncreaseSampleCount(const u32 _uAmount);
void ReadStreamBlock(short* _pPCM);
static u64 g_LastCPUTime = 0;
static int g_SampleRate = 32000;
static int g_DSPSampleRate = 32000;
static u64 g_CPUCyclesPerSample = 0xFFFFFFFFFFFULL;
void Init()
{
g_AudioRegister.m_SampleCounter = 0;

View File

@ -20,32 +20,28 @@
#ifndef _AUDIOINTERFACE_H
#define _AUDIOINTERFACE_H
class ChunkFile;
namespace AudioInterface
{
// Init
void Init();
// Shutdown
void Shutdown();
void DoState(ChunkFile &f);
// Update
void Update();
// Calls by DSP plugin
unsigned __int32 Callback_GetStreaming(short* _pDestBuffer, unsigned __int32 _numSamples);
// Read32
void HWCALL Read32(u32& _uReturnValue, const u32 _iAddress);
// Write32
void HWCALL Write32(const u32 _iValue, const u32 _iAddress);
// Get the Audio Rate (48000 or 32000)
// Get the audio rates (48000 or 32000 only)
u32 GetAISampleRate();
u32 GetDSPSampleRate();
} // end of namespace AudioInterface
} // namespace
#endif

View File

@ -105,6 +105,20 @@ u16 m_tokenReg;
CPFifo fifo; //This one is shared between gfx thread and emulator thread
void DoState(ChunkFile &f)
{
f.Descend("CP ");
f.Do(m_CPStatusReg);
f.Do(m_CPCtrlReg);
f.Do(m_CPClearReg);
f.Do(m_bboxleft);
f.Do(m_bboxtop);
f.Do(m_bboxright);
f.Do(m_bboxbottom);
f.Do(m_tokenReg);
f.Do(fifo);
f.Ascend();
}
// function
void UpdateFifoRegister();

View File

@ -18,6 +18,9 @@
#ifndef _COMMANDPROCESSOR_H
#define _COMMANDPROCESSOR_H
#include "Common.h"
class ChunkFile;
#ifdef _WIN32
#include <windows.h>
#endif
@ -79,6 +82,7 @@ extern CPFifo fifo;
// Init
void Init();
void Shutdown();
void DoState(ChunkFile &f);
// Read
void HWCALL Read16(u16& _rReturnValue, const u32 _Address);

View File

@ -175,6 +175,19 @@ u16 g_AR_MODE = 0x43; // 0x23 -> Zelda standard mode (standard ARAM access ??)
// 0x43 -> written by OSAudioInit at the UCode upload (upload UCode)
// 0x63 -> ARCheckSize Mode (access AR-registers ??) or no exception ??
void DoState(ChunkFile &f)
{
f.Descend("DSP ");
f.Do(g_ARAM, ARAM_SIZE);
f.Do(g_dspState);
f.Do(g_audioDMA);
f.Do(g_arDMA);
f.Do(g_AR_READY_FLAG);
f.Do(g_AR_MODE);
f.Ascend();
}
void UpdateInterrupts();
void Update_ARAM_DMA();
void WriteARAM(u8 _iValue, u32 _iAddress);

View File

@ -19,6 +19,7 @@
#define _DSPINTERFACE_H
#include "Common.h"
class ChunkFile;
namespace DSP
{
@ -32,6 +33,8 @@ enum DSPInterruptType
void Init();
void Shutdown();
void DoState(ChunkFile &f);
void GenerateDSPInterrupt(DSPInterruptType _DSPInterruptType, bool _bSet = true);
void GenerateDSPInterruptFromPlugin(DSPInterruptType _DSPInterruptType, bool _bSet = true);

View File

@ -15,6 +15,9 @@
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include "Common.h"
#include "ChunkFile.h"
#include "StreamADPCM.H"
#include "DVDInterface.h"
@ -44,7 +47,7 @@ namespace DVDInterface
20993: 00000000 DVD (zzz_80146e44 ??, 0x80146fcc) : DVD(r): 0xcc006018
After this, Cubivore infinitely calls DVDGetDriveStatus, which does not even
bother to check any DVD regs
bother to check any DVD regs. Waiting for interrupt?
*/
// internal hardware addresses
@ -69,7 +72,7 @@ enum DVDInterruptType
INT_DEINT = 0,
INT_TCINT = 1,
INT_BRKINT = 2,
INT_CVRINT
INT_CVRINT = 3,
};
// DI Status Register
@ -78,14 +81,14 @@ union UDISR
u32 Hex;
struct
{
unsigned BREAK : 1; // Stop the Device + Interrupt
unsigned DEINITMASK : 1; // Access Device Error Int Mask
unsigned DEINT : 1; // Access Device Error Int
unsigned TCINTMASK : 1; // Transfer Complete Int Mask
unsigned TCINT : 1; // Transfer Complete Int
unsigned BRKINTMASK : 1;
unsigned BRKINT : 1; // w 1: clear brkint
unsigned : 25;
unsigned BREAK : 1; // Stop the Device + Interrupt
unsigned DEINITMASK : 1; // Access Device Error Int Mask
unsigned DEINT : 1; // Access Device Error Int
unsigned TCINTMASK : 1; // Transfer Complete Int Mask
unsigned TCINT : 1; // Transfer Complete Int
unsigned BRKINTMASK : 1;
unsigned BRKINT : 1; // w 1: clear brkint
unsigned : 25;
};
UDISR() {Hex = 0;}
UDISR(u32 _hex) {Hex = _hex;}
@ -97,10 +100,10 @@ union UDICVR
u32 Hex;
struct
{
unsigned CVR : 1; // 0: Cover closed 1: Cover open
unsigned CVRINTMASK : 1; // 1: Interrupt enabled;
unsigned CVRINT : 1; // 1: Interrupt clear
unsigned : 29;
unsigned CVR : 1; // 0: Cover closed 1: Cover open
unsigned CVRINTMASK : 1; // 1: Interrupt enabled;
unsigned CVRINT : 1; // 1: Interrupt clear
unsigned : 29;
};
UDICVR() {Hex = 0;}
UDICVR(u32 _hex) {Hex = _hex;}
@ -170,11 +173,19 @@ struct DVDMemStruct
u32 AudioLength;
};
// STATE_TO_SAVE
DVDMemStruct dvdMem;
u32 g_ErrorCode = 0x00;
bool g_bDiscInside = true;
// helper
u32 g_ErrorCode = 0x00;
bool g_bDiscInside = true;
void DoState(ChunkFile &f)
{
f.Descend("DI ");
f.Do(dvdMem);
f.Do(g_ErrorCode);
f.Do(g_bDiscInside);
f.Ascend();
}
void UpdateInterrupts();
void GenerateDVDInterrupt(DVDInterruptType _DVDInterrupt);

View File

@ -19,13 +19,14 @@
#define _DVDINTERFACE_H
#include "Common.h"
class ChunkFile;
namespace DVDInterface
{
// Init
void Init();
void Shutdown();
void DoState(ChunkFile &f);
void SetDiscInside(bool _DiscInside);

View File

@ -15,6 +15,9 @@
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include "Common.h"
#include "ChunkFile.h"
#include "PeripheralInterface.h"
#include "../PowerPC/PowerPC.h"
@ -50,6 +53,13 @@ void Shutdown()
g_Channels = 0;
}
void DoState(ChunkFile &f)
{
f.Descend("EXI ");
// TODO: descend all the devices recursively.
f.Ascend();
}
void Update()
{
g_Channels[0].Update();

View File

@ -18,12 +18,15 @@
#define _EXIINTERFACE_H
#include "Common.h"
class ChunkFile;
namespace ExpansionInterface
{
void Init();
void Shutdown();
void DoState(ChunkFile &f);
void Update();
void UpdateInterrupts();

View File

@ -289,7 +289,7 @@ void CEXIMemoryCard::TransferByte(u8 &byte)
break;
case cmdSetInterrupt:
if (m_uPosition==1)
if (m_uPosition == 1)
{
interruptSwitch = byte;
}

View File

@ -15,13 +15,15 @@
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include "GPFifo.h"
#include "Common.h"
#include "ChunkFile.h"
#include "PeripheralInterface.h"
#include "CommandProcessor.h"
#include "Memmap.h"
#include "../PowerPC/PowerPC.h"
#include "GPFifo.h"
namespace GPFifo
{
@ -42,6 +44,14 @@ u8 GC_ALIGNED32(m_gatherPipe[GATHER_PIPE_SIZE*16]); //more room, for the fastmod
// pipe counter
u32 m_gatherPipeCount = 0;
void DoState(ChunkFile &f)
{
f.Descend("FIFO");
f.Do(m_gatherPipe);
f.Do(m_gatherPipeCount);
f.Ascend();
}
void Init()
{
ResetGatherPipe();

View File

@ -19,6 +19,7 @@
#define _GPFIFO_H
#include "Common.h"
class ChunkFile;
namespace GPFifo
{
@ -35,6 +36,7 @@ extern u32 m_gatherPipeCount;
// Init
void Init();
void DoState(ChunkFile &f);
// ResetGatherPipe
void ResetGatherPipe();

View File

@ -37,6 +37,7 @@
#include "../CoreTiming.h"
#include "SystemTimers.h"
#include "../IPC_HLE/WII_IPC_HLE.h"
#include "../State.h"
#define CURVERSION 0x0001
@ -45,7 +46,10 @@ namespace HW
void Init()
{
Thunk_Init(); // not really hw, but this way we know it's inited first :P
State_Init();
// Init the whole Hardware
AudioInterface::Init();
PixelEngine::Init();
CommandProcessor::Init();
VideoInterface::Init();
@ -72,11 +76,32 @@ namespace HW
DSP::Shutdown();
Memory::Shutdown();
SerialInterface::Shutdown();
AudioInterface::Shutdown();
WII_IPC_HLE_Interface::Shutdown();
WII_IPCInterface::Shutdown();
State_Shutdown();
Thunk_Shutdown();
CoreTiming::UnregisterAllEvents();
}
void DoState(ChunkFile &f)
{
f.Descend("HWst");
PixelEngine::DoState(f);
CommandProcessor::DoState(f);
VideoInterface::DoState(f);
SerialInterface::DoState(f);
CPeripheralInterface::DoState(f);
DSP::DoState(f);
DVDInterface::DoState(f);
GPFifo::DoState(f);
ExpansionInterface::DoState(f);
AudioInterface::DoState(f);
CoreTiming::DoState(f);
WII_IPCInterface::DoState(f);
f.Ascend();
}
}

View File

@ -19,15 +19,13 @@
#define _HW_H
#include "Common.h"
#include "ChunkFile.h"
namespace HW
{
void Init();
void Shutdown();
/*
void LoadState(const char* _szFilename);
void SaveState(const char* _szFilename);
*/
void DoState(ChunkFile &f);
}
#endif

View File

@ -21,6 +21,8 @@
#include "Common.h"
class ChunkFile;
typedef void (HWCALL *writeFn8 )(const u8, const u32);
typedef void (HWCALL *writeFn16)(const u16,const u32);
typedef void (HWCALL *writeFn32)(const u32,const u32);
@ -63,6 +65,8 @@ namespace Memory
bool IsInitialized();
bool Init();
bool Shutdown();
void DoState(ChunkFile &f);
void Clear();
bool AreMemoryBreakpointsActivated();

View File

@ -15,6 +15,9 @@
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include "Common.h"
#include "ChunkFile.h"
#include "../PowerPC/PowerPC.h"
#include "MemoryInterface.h"
@ -47,6 +50,13 @@ struct MIMemStruct
// STATE_TO_SAVE
static MIMemStruct miMem;
void DoState(ChunkFile &f)
{
f.Descend("MI ");
f.Do(miMem);
f.Ascend();
}
void Read16(u16& _uReturnValue, const u32 _iAddress)
{
//0x30 -> 0x5a : gp memory metrics

View File

@ -17,8 +17,13 @@
#ifndef _MEMORYINTERFACE_H
#define _MEMORYINTERFACE_H
#include "Common.h"
class ChunkFile;
namespace MemoryInterface
{
void DoState(ChunkFile &f);
void HWCALL Read16(u16& _uReturnValue, const u32 _iAddress);
void HWCALL Read32(u32& _uReturnValue, const u32 _iAddress);
void HWCALL Write32(const u32 _iValue, const u32 _iAddress);

View File

@ -16,6 +16,8 @@
// http://code.google.com/p/dolphin-emu/
#include <stdio.h>
#include "Common.h"
#include "ChunkFile.h"
#include "../PowerPC/PowerPC.h"
#include "../HW/CPU.h"
@ -31,6 +33,17 @@ u32 CPeripheralInterface::Fifo_CPUBase;
u32 CPeripheralInterface::Fifo_CPUEnd;
u32 CPeripheralInterface::Fifo_CPUWritePointer;
void CPeripheralInterface::DoState(ChunkFile &f)
{
f.Descend("PI ");
f.Do(m_InterruptMask);
f.Do(m_InterruptCause);
f.Do(Fifo_CPUBase);
f.Do(Fifo_CPUEnd);
f.Do(Fifo_CPUWritePointer);
f.Ascend();
}
void CPeripheralInterface::Init()
{
m_InterruptMask = 0;

View File

@ -19,6 +19,8 @@
#define _PERIPHERALINTERFACE_H
#include "Common.h"
class ChunkFile;
//
// PERIPHERALINTERFACE
// Handles communication with cpu services like the write gatherer used for fifos, and interrupts
@ -96,6 +98,7 @@ public:
static u32 Fifo_CPUWritePointer;
static void Init();
static void DoState(ChunkFile &f);
static void SetInterrupt(InterruptCause _causemask, bool _bSet=true);

View File

@ -15,6 +15,9 @@
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include "Common.h"
#include "ChunkFile.h"
#include "PixelEngine.h"
#include "../CoreTiming.h"
@ -60,6 +63,16 @@ static bool g_bSignalFinishInterrupt;
int et_SetTokenOnMainThread;
int et_SetFinishOnMainThread;
void DoState(ChunkFile &f)
{
f.Descend("PE ");
f.Do(g_ctrlReg);
f.Do(g_token);
f.Do(g_bSignalTokenInterrupt);
f.Do(g_bSignalFinishInterrupt);
f.Ascend();
}
void UpdateInterrupts();
void SetToken_OnMainThread(u64 userdata, int cyclesLate);

View File

@ -18,10 +18,12 @@
#define _PIXELENGINE_H
#include "Common.h"
class ChunkFile;
namespace PixelEngine
{
void Init();
void DoState(ChunkFile &f);
// Read
void HWCALL Read16(u16& _uReturnValue, const u32 _iAddress);

View File

@ -17,6 +17,9 @@
#include <string.h>
#include "Common.h"
#include "ChunkFile.h"
#include "SerialInterface.h"
#include "SerialInterface_Devices.h"
@ -215,6 +218,18 @@ static USIStatusReg g_StatusReg;
static USIEXIClockCount g_EXIClockCount;
static u8 g_SIBuffer[128];
void DoState(ChunkFile &f)
{
f.Descend("SI ");
f.Do(g_Channel);
f.Do(g_Poll);
f.Do(g_ComCSR);
f.Do(g_StatusReg);
f.Do(g_EXIClockCount);
f.Do(g_SIBuffer);
f.Ascend();
}
static void GenerateSIInterrupt(SIInterruptType _SIInterrupt);
void RunSIBuffer();
void UpdateInterrupts();
@ -228,10 +243,10 @@ void Init()
g_Channel[i].m_InLo.Hex = 0;
}
unsigned int AttachedPasMask = PluginPAD::PAD_GetAttachedPads();
for (int i=0; i<4; i++)
unsigned int AttachedPadMask = PluginPAD::PAD_GetAttachedPads();
for (int i = 0; i < 4; i++)
{
if (AttachedPasMask & (1 << i))
if (AttachedPadMask & (1 << i))
g_Channel[i].m_pDevice = new CSIDevice_GCController(i);
else
g_Channel[i].m_pDevice = new CSIDevice_Dummy(i);
@ -246,7 +261,7 @@ void Init()
void Shutdown()
{
for (int i=0; i<NUMBER_OF_CHANNELS; i++)
for (int i = 0; i < NUMBER_OF_CHANNELS; i++)
{
delete g_Channel[i].m_pDevice;
g_Channel[i].m_pDevice = NULL;

View File

@ -19,22 +19,18 @@
#define _SERIALINTERFACE_H
#include "Common.h"
class ChunkFile;
namespace SerialInterface
{
// Init
void Init();
// Shutdown
void Shutdown();
void DoState(ChunkFile &f);
void UpdateDevices();
// Read32
void HWCALL Read32(u32& _uReturnValue, const u32 _iAddress);
// Write32
void HWCALL Write32(const u32 _iValue, const u32 _iAddress);
}; // end of namespace SerialInterface

View File

@ -19,6 +19,7 @@
#define _SERIALINTERFACE_DEVICES_H
#include "Common.h"
class ChunkFile;
class ISIDevice
{

View File

@ -12,6 +12,7 @@
#define _STREAMADPCM_H
#include "Common.h"
class ChunkFile;
#define ONE_BLOCK_SIZE 32
#define SAMPLES_PER_BLOCK 28

View File

@ -7,7 +7,9 @@
#include "StreamADPCM.H"
float NGCADPCM::iir1[STEREO], NGCADPCM::iir2[STEREO];
// STATE_TO_SAVE
float NGCADPCM::iir1[STEREO],
NGCADPCM::iir2[STEREO];
void NGCADPCM::InitFilter()
{

View File

@ -15,6 +15,9 @@
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include "Common.h"
#include "ChunkFile.h"
#include "../PowerPC/PowerPC.h"
#include "PeripheralInterface.h"
@ -83,30 +86,44 @@ union UVIInterruptRegister
};
// STATE_TO_SAVE
UVIDisplayControlRegister m_VIDisplayControlRegister;
static UVIDisplayControlRegister m_VIDisplayControlRegister;
// Framebuffers
u32 m_FrameBuffer1; // normal framebuffer address
u32 m_FrameBuffer2; // framebuffer for 3d buffer address
static u32 m_FrameBuffer1; // normal framebuffer address
static u32 m_FrameBuffer2; // framebuffer for 3d buffer address
// VI Interrupt Registers
UVIInterruptRegister m_VIInterruptRegister[4];
static UVIInterruptRegister m_VIInterruptRegister[4];
u8 m_UVIUnknownRegs[0x1000];
u8 m_UVIUnknownRegs[0x1000];
u16 HorizontalBeamPos = 0;
u16 VerticalBeamPos = 0;
static u16 HorizontalBeamPos = 0;
static u16 VerticalBeamPos = 0;
u32 TicksPerFrame = 0;
u32 LineCount = 0;
u64 LastTime = 0;
static u32 TicksPerFrame = 0;
static u32 LineCount = 0;
static u64 LastTime = 0;
void DoState(ChunkFile &f)
{
f.Descend("VI ");
f.Do(m_VIDisplayControlRegister);
f.Do(m_FrameBuffer1);
f.Do(m_FrameBuffer2);
f.Do(m_VIInterruptRegister);
f.Do(m_UVIUnknownRegs, 0x1000);
f.Do(HorizontalBeamPos);
f.Do(VerticalBeamPos);
f.Do(TicksPerFrame);
f.Do(LineCount);
f.Do(LastTime);
f.Ascend();
}
void Init()
{
for (int i=0; i<4; i++)
{
for (int i = 0; i < 4; i++)
m_VIInterruptRegister[i].Hex = 0x00;
}
m_VIDisplayControlRegister.Hex = 0x0000;
m_VIDisplayControlRegister.ENB = 0;

View File

@ -18,6 +18,7 @@
#define _VIDEOINTERFACE_H
#include "Common.h"
class ChunkFile;
namespace VideoInterface
{
@ -29,20 +30,18 @@ namespace VideoInterface
INT_REG_3,
};
// Init
void Init();
void DoState(ChunkFile &f);
// Read
void HWCALL Read16(u16& _uReturnValue, const u32 _uAddress);
void HWCALL Read32(u32& _uReturnValue, const u32 _uAddress);
// Write
void HWCALL Write16(const u16 _uValue, const u32 _uAddress);
void HWCALL Write32(const u32 _uValue, const u32 _uAddress);
void GenerateVIInterrupt(VIInterruptType _VIInterrupt);
// returns a pointer to the framebuffer
// returns a pointer to the current visible framebuffer
u8* GetFrameBufferPointer();
// pre init
@ -51,7 +50,6 @@ namespace VideoInterface
// VI Unknown Regs
extern u8 m_UVIUnknownRegs[0x1000];
// ??????
void Update();
@ -59,7 +57,6 @@ namespace VideoInterface
// UpdateInterrupts: check if we have to generate a new VI Interrupt
void UpdateInterrupts();
// ??????
void UpdateTiming();
};

View File

@ -16,6 +16,7 @@
// http://code.google.com/p/dolphin-emu/
#include "Common.h"
#include "ChunkFile.h"
#include "WII_IOB.h"
namespace WII_IOBridge

View File

@ -17,16 +17,16 @@
#ifndef _WII_IOBRIDGE_H_
#define _WII_IOBRIDGE_H_
#include "Common.h"
class ChunkFile;
namespace WII_IOBridge
{
// Init
void Init();
// Shutdown
void Shutdown();
void DoState(ChunkFile &f);
// Update
void Update();
void HWCALL Read8(u8& _rReturnValue, const u32 _Address);

View File

@ -18,13 +18,14 @@
#include <map>
#include "Common.h"
#include "WII_IPC.h"
#include "ChunkFile.h"
#include "CPU.h"
#include "Memmap.h"
#include "PeripheralInterface.h"
#include "../IPC_HLE/WII_IPC_HLE.h"
#include "WII_IPC.h"
namespace WII_IPCInterface
{
@ -92,6 +93,17 @@ u32 g_Address = 0;
u32 g_Reply = 0;
u32 g_SensorBarPower = 0;
void DoState(ChunkFile &f)
{
f.Descend("WIPC");
f.Do(g_IPC_Status);
f.Do(g_IPC_Config);
f.Do(g_IPC_Control);
f.Do(g_Address);
f.Do(g_Reply);
f.Do(g_SensorBarPower);
f.Ascend();
}
void UpdateInterrupts();

View File

@ -17,18 +17,17 @@
#ifndef _WII_IPC_H_
#define _WII_IPC_H_
#include "Common.h"
class ChunkFile;
namespace WII_IPCInterface
{
// Init
void Init();
// Shutdown
void Shutdown();
void DoState(ChunkFile &f);
// Update
void Update();
bool IsReady();
void GenerateReply(u32 _AnswerAddress);
void GenerateAck(u32 _AnswerAddress);

View File

@ -15,6 +15,9 @@
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include "Common.h"
#include "ChunkFile.h"
#include "../HW/Memmap.h"
#include "../HW/CPU.h"
#include "../Core.h"
@ -29,10 +32,19 @@
namespace PowerPC
{
// STATE_TO_SAVE
PowerPCState GC_ALIGNED16(ppcState);
volatile CPUState state = CPU_STEPPING;
ICPUCore* m_pCore = NULL;
volatile CPUState state = CPU_STEPPING;
void DoState(ChunkFile &f)
{
f.Descend("PPC ");
f.Do(ppcState);
f.Do(state);
f.Ascend();
}
void ResetRegisters()
{

View File

@ -29,6 +29,8 @@
#include "Gekko.h"
#include "ICPUCore.h"
class ChunkFile;
namespace PowerPC
{
enum ECoreType
@ -85,6 +87,8 @@ namespace PowerPC
void Init();
void Shutdown();
void DoState(ChunkFile &f);
void SetCore(ECoreType _coreType);
ICPUCore& GetCore();

View File

@ -4,11 +4,12 @@ files = ["Console.cpp",
"Core.cpp",
"CoreTiming.cpp",
"CoreParameter.cpp",
"LogManager.cpp",
"PatchEngine.cpp",
"MemTools.cpp",
"Tracer.cpp",
"Host.cpp",
"LogManager.cpp",
"MemTools.cpp",
"PatchEngine.cpp",
"State.cpp",
"Tracer.cpp",
"VolumeHandler.cpp",
"Boot/Boot.cpp",
"Boot/Boot_DOL.cpp",

View File

@ -0,0 +1,54 @@
#include "Common.h"
#include "State.h"
#include "CoreTiming.h"
#include "HW/HW.h"
#include "PowerPC/PowerPC.h"
static int ev_Save;
static int ev_Load;
static std::string cur_filename;
void DoState(ChunkFile &f)
{
f.Descend("DOLP");
PowerPC::DoState(f);
HW::DoState(f);
f.Ascend();
}
void SaveStateCallback(u64 userdata, int cyclesLate)
{
ChunkFile f(cur_filename.c_str(), ChunkFile::MODE_WRITE);
DoState(f);
}
void LoadStateCallback(u64 userdata, int cyclesLate)
{
ChunkFile f(cur_filename.c_str(), ChunkFile::MODE_READ);
DoState(f);
}
void State_Init()
{
ev_Load = CoreTiming::RegisterEvent("LoadState", &LoadStateCallback);
ev_Save = CoreTiming::RegisterEvent("SaveState", &SaveStateCallback);
}
void State_Shutdown()
{
// nothing to do, here for consistency.
}
void SaveState(const char *filename)
{
cur_filename = filename;
CoreTiming::ScheduleEvent_Threadsafe(0, ev_Save);
}
void LoadState(const char *filename)
{
cur_filename = filename;
CoreTiming::ScheduleEvent_Threadsafe(0, ev_Load);
}

View File

@ -0,0 +1,12 @@
#ifndef _STATE_H
#define _STATE_H
// None of these happen instantly - they get scheduled as an event.
void State_Init();
void State_Shutdown();
void State_Save();
void State_Load();
#endif