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:
parent
28edd4d31b
commit
465ee5fd86
|
@ -455,6 +455,14 @@
|
||||||
RelativePath=".\Src\ABI.h"
|
RelativePath=".\Src\ABI.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\Src\ChunkFile.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\Src\ChunkFile.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\Src\Common.cpp"
|
RelativePath=".\Src\Common.cpp"
|
||||||
>
|
>
|
||||||
|
|
|
@ -0,0 +1,175 @@
|
||||||
|
// Copyright (C) 2003-2008 Dolphin Project.
|
||||||
|
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
|
// Official SVN repository and contact information can be found at
|
||||||
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
#include "ChunkFile.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
// Not using file mapping, just bog standard fopen and friends. We trust them to be fast
|
||||||
|
// enough to not be the bottleneck.
|
||||||
|
|
||||||
|
ChunkFile::ChunkFile(const char *filename, ChunkFileMode _mode)
|
||||||
|
{
|
||||||
|
mode = _mode;
|
||||||
|
data = 0;
|
||||||
|
|
||||||
|
didFail = false;
|
||||||
|
f = fopen(filename, mode == MODE_WRITE ? "wb" : "rb");
|
||||||
|
if (!f) {
|
||||||
|
didFail = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fseek(f, 0, SEEK_END);
|
||||||
|
size = ftell(f);
|
||||||
|
eof = size;
|
||||||
|
|
||||||
|
stack_ptr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ChunkFile::~ChunkFile()
|
||||||
|
{
|
||||||
|
if (f)
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ChunkFile::ReadInt()
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
fread(&x, 4, 1, f);
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChunkFile::WriteInt(int x)
|
||||||
|
{
|
||||||
|
fwrite(&x, 4, 1, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ChunkFile::Do(void *ptr, int size)
|
||||||
|
{
|
||||||
|
int sz;
|
||||||
|
switch (mode) {
|
||||||
|
case MODE_READ:
|
||||||
|
sz = ReadInt();
|
||||||
|
if (sz != size)
|
||||||
|
return false;
|
||||||
|
fread(ptr, size, 1, f);
|
||||||
|
fseek(f, ((size + 3) & ~3) - size, SEEK_CUR);
|
||||||
|
break;
|
||||||
|
case MODE_WRITE:
|
||||||
|
WriteInt(size);
|
||||||
|
fwrite(ptr, size, 1, f);
|
||||||
|
fseek(f, ((size + 3) & ~3) - size, SEEK_CUR);
|
||||||
|
break;
|
||||||
|
case MODE_VERIFY:
|
||||||
|
sz = ReadInt();
|
||||||
|
if (sz != size)
|
||||||
|
return false;
|
||||||
|
fseek(f, (size + 3) & ~3, SEEK_CUR);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//let's get into the business
|
||||||
|
bool ChunkFile::Descend(const char *cid)
|
||||||
|
{
|
||||||
|
int id = *((int*)cid);
|
||||||
|
if (mode == MODE_READ)
|
||||||
|
{
|
||||||
|
bool found = false;
|
||||||
|
int startPos = ftell(f);
|
||||||
|
ChunkInfo temp = stack[stack_ptr];
|
||||||
|
|
||||||
|
//save information to restore after the next Ascend
|
||||||
|
stack[stack_ptr].parentStartLocation = startPos;
|
||||||
|
stack[stack_ptr].parentEOF = eof;
|
||||||
|
|
||||||
|
int firstID = 0;
|
||||||
|
//let's search through children..
|
||||||
|
while (ftell(f) < eof)
|
||||||
|
{
|
||||||
|
stack[stack_ptr].ID = ReadInt();
|
||||||
|
if (firstID == 0)
|
||||||
|
firstID = stack[stack_ptr].ID|1;
|
||||||
|
stack[stack_ptr].length = ReadInt();
|
||||||
|
stack[stack_ptr].startLocation = ftell(f);
|
||||||
|
if (stack[stack_ptr].ID == id)
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fseek(f, stack[stack_ptr].length, SEEK_CUR); //try next block
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//if we found nothing, return false so the caller can skip this
|
||||||
|
if (!found)
|
||||||
|
{
|
||||||
|
stack[stack_ptr] = temp;
|
||||||
|
fseek(f, stack[stack_ptr].parentStartLocation, SEEK_SET);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//descend into it
|
||||||
|
//pos was set inside the loop above
|
||||||
|
eof = stack[stack_ptr].startLocation + stack[stack_ptr].length;
|
||||||
|
stack_ptr++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//write a chunk id, and prepare for filling in length later
|
||||||
|
WriteInt(id);
|
||||||
|
WriteInt(0); //will be filled in by Ascend
|
||||||
|
stack[stack_ptr].startLocation = ftell(f);
|
||||||
|
stack_ptr++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//let's ascend out
|
||||||
|
void ChunkFile::Ascend()
|
||||||
|
{
|
||||||
|
if (mode == MODE_READ)
|
||||||
|
{
|
||||||
|
//ascend, and restore information
|
||||||
|
stack_ptr--;
|
||||||
|
fseek(f, stack[stack_ptr].parentStartLocation, SEEK_SET);
|
||||||
|
eof = stack[stack_ptr].parentEOF;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stack_ptr--;
|
||||||
|
//now fill in the written length automatically
|
||||||
|
int posNow = ftell(f);
|
||||||
|
fseek(f, stack[stack_ptr].startLocation - 4, SEEK_SET);
|
||||||
|
WriteInt(posNow - stack[stack_ptr].startLocation);
|
||||||
|
fseek(f, posNow, SEEK_SET);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int ChunkFile::GetCurrentChunkSize()
|
||||||
|
{
|
||||||
|
if (stack_ptr)
|
||||||
|
return stack[stack_ptr - 1].length;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,109 @@
|
||||||
|
// Copyright (C) 2003-2008 Dolphin Project.
|
||||||
|
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, version 2.0.
|
||||||
|
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License 2.0 for more details.
|
||||||
|
|
||||||
|
// A copy of the GPL 2.0 should have been included with the program.
|
||||||
|
// If not, see http://www.gnu.org/licenses/
|
||||||
|
|
||||||
|
// Official SVN repository and contact information can be found at
|
||||||
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
|
#ifndef _CHUNKFILE_H
|
||||||
|
#define _CHUNKFILE_H
|
||||||
|
|
||||||
|
// Class to read/write/verify hierarchical binary file formats.
|
||||||
|
// Grabbed from one of my older projects and modified heavily.
|
||||||
|
// Works more like a RIFF file than a Google Protocol Buffer, for example.
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
//TO REMEMBER WHEN USING:
|
||||||
|
|
||||||
|
//EITHER a chunk contains ONLY data
|
||||||
|
//OR it contains ONLY other chunks
|
||||||
|
//otherwise the scheme breaks...
|
||||||
|
|
||||||
|
class ChunkFile
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum ChunkFileMode
|
||||||
|
{
|
||||||
|
MODE_READ,
|
||||||
|
MODE_WRITE,
|
||||||
|
MODE_VERIFY,
|
||||||
|
};
|
||||||
|
private:
|
||||||
|
struct ChunkInfo
|
||||||
|
{
|
||||||
|
int startLocation;
|
||||||
|
int parentStartLocation;
|
||||||
|
int parentEOF;
|
||||||
|
unsigned int ID;
|
||||||
|
int length;
|
||||||
|
};
|
||||||
|
|
||||||
|
ChunkInfo stack[8];
|
||||||
|
int stack_ptr;
|
||||||
|
|
||||||
|
char *data;
|
||||||
|
int size;
|
||||||
|
int eof;
|
||||||
|
|
||||||
|
ChunkFileMode mode;
|
||||||
|
FILE *f;
|
||||||
|
bool didFail;
|
||||||
|
|
||||||
|
// Used for internal bookkeeping only.
|
||||||
|
int ReadInt();
|
||||||
|
void WriteInt(int x);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
ChunkFile(const char *filename, ChunkFileMode mode);
|
||||||
|
~ChunkFile();
|
||||||
|
|
||||||
|
// Only pass 4-character IDs.
|
||||||
|
bool Descend(const char *id);
|
||||||
|
void Ascend();
|
||||||
|
|
||||||
|
//void Do(int &i);
|
||||||
|
//bool Do(std::string &s);
|
||||||
|
bool Do(void *ptr, int size);
|
||||||
|
|
||||||
|
// Future
|
||||||
|
// bool DoCompressed(void *ptr, int size)
|
||||||
|
|
||||||
|
// Store maps to file. Very useful.
|
||||||
|
template<class T>
|
||||||
|
void Do(std::map<u32, T> &x) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store vectors.
|
||||||
|
template<class T>
|
||||||
|
void Do(std::vector<T> &x) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle everything else
|
||||||
|
template<class T>
|
||||||
|
void Do(T &x) {
|
||||||
|
Do((void *)&x, sizeof(x));
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetCurrentChunkSize();
|
||||||
|
bool failed() {return didFail;}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -2,6 +2,7 @@ Import('env')
|
||||||
|
|
||||||
files = ["ABI.cpp",
|
files = ["ABI.cpp",
|
||||||
"Common.cpp",
|
"Common.cpp",
|
||||||
|
"ChunkFile.cpp",
|
||||||
"CPUDetect.cpp",
|
"CPUDetect.cpp",
|
||||||
"DynamicLibrary.cpp",
|
"DynamicLibrary.cpp",
|
||||||
"Hash.cpp",
|
"Hash.cpp",
|
||||||
|
|
|
@ -1174,6 +1174,14 @@
|
||||||
RelativePath=".\Src\SConscript"
|
RelativePath=".\Src\SConscript"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\Src\State.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\Src\State.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\Src\stdafx.cpp"
|
RelativePath=".\Src\stdafx.cpp"
|
||||||
>
|
>
|
||||||
|
|
|
@ -61,7 +61,7 @@ int RegisterEvent(const char *name, TimedCallback callback)
|
||||||
type.name = name;
|
type.name = name;
|
||||||
type.callback = callback;
|
type.callback = callback;
|
||||||
event_types.push_back(type);
|
event_types.push_back(type);
|
||||||
return event_types.size() - 1;
|
return (int)event_types.size() - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnregisterAllEvents()
|
void UnregisterAllEvents()
|
||||||
|
@ -71,6 +71,18 @@ void UnregisterAllEvents()
|
||||||
event_types.clear();
|
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()
|
u64 GetTicks()
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
// callback. You then schedule events using the type id you get back.
|
// callback. You then schedule events using the type id you get back.
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
#include "ChunkFile.h"
|
||||||
|
|
||||||
namespace CoreTiming
|
namespace CoreTiming
|
||||||
{
|
{
|
||||||
|
@ -34,6 +35,7 @@ typedef void (*TimedCallback)(u64 userdata, int cyclesLate);
|
||||||
u64 GetTicks();
|
u64 GetTicks();
|
||||||
u64 GetIdleTicks();
|
u64 GetIdleTicks();
|
||||||
|
|
||||||
|
void DoState(ChunkFile &f);
|
||||||
// The int that the callbacks get is how many cycles late it was.
|
// The int that the callbacks get is how many cycles late it was.
|
||||||
// So to schedule a new event on a regular basis:
|
// So to schedule a new event on a regular basis:
|
||||||
// inside callback:
|
// inside callback:
|
||||||
|
|
|
@ -87,18 +87,29 @@ struct SAudioRegister
|
||||||
u32 m_InterruptTiming;
|
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 GenerateAudioInterrupt();
|
||||||
void UpdateInterrupts();
|
void UpdateInterrupts();
|
||||||
void IncreaseSampleCount(const u32 _uAmount);
|
void IncreaseSampleCount(const u32 _uAmount);
|
||||||
void ReadStreamBlock(short* _pPCM);
|
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()
|
void Init()
|
||||||
{
|
{
|
||||||
g_AudioRegister.m_SampleCounter = 0;
|
g_AudioRegister.m_SampleCounter = 0;
|
||||||
|
|
|
@ -20,32 +20,28 @@
|
||||||
#ifndef _AUDIOINTERFACE_H
|
#ifndef _AUDIOINTERFACE_H
|
||||||
#define _AUDIOINTERFACE_H
|
#define _AUDIOINTERFACE_H
|
||||||
|
|
||||||
|
class ChunkFile;
|
||||||
|
|
||||||
namespace AudioInterface
|
namespace AudioInterface
|
||||||
{
|
{
|
||||||
|
|
||||||
// Init
|
|
||||||
void Init();
|
void Init();
|
||||||
|
|
||||||
// Shutdown
|
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
|
void DoState(ChunkFile &f);
|
||||||
|
|
||||||
// Update
|
|
||||||
void Update();
|
void Update();
|
||||||
|
|
||||||
// Calls by DSP plugin
|
// Calls by DSP plugin
|
||||||
unsigned __int32 Callback_GetStreaming(short* _pDestBuffer, unsigned __int32 _numSamples);
|
unsigned __int32 Callback_GetStreaming(short* _pDestBuffer, unsigned __int32 _numSamples);
|
||||||
|
|
||||||
// Read32
|
|
||||||
void HWCALL Read32(u32& _uReturnValue, const u32 _iAddress);
|
void HWCALL Read32(u32& _uReturnValue, const u32 _iAddress);
|
||||||
|
|
||||||
// Write32
|
|
||||||
void HWCALL Write32(const u32 _iValue, const u32 _iAddress);
|
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 GetAISampleRate();
|
||||||
u32 GetDSPSampleRate();
|
u32 GetDSPSampleRate();
|
||||||
|
|
||||||
} // end of namespace AudioInterface
|
} // namespace
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -105,6 +105,20 @@ u16 m_tokenReg;
|
||||||
|
|
||||||
CPFifo fifo; //This one is shared between gfx thread and emulator thread
|
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
|
// function
|
||||||
void UpdateFifoRegister();
|
void UpdateFifoRegister();
|
||||||
|
|
|
@ -18,6 +18,9 @@
|
||||||
#ifndef _COMMANDPROCESSOR_H
|
#ifndef _COMMANDPROCESSOR_H
|
||||||
#define _COMMANDPROCESSOR_H
|
#define _COMMANDPROCESSOR_H
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
class ChunkFile;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -79,6 +82,7 @@ extern CPFifo fifo;
|
||||||
// Init
|
// Init
|
||||||
void Init();
|
void Init();
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
|
void DoState(ChunkFile &f);
|
||||||
|
|
||||||
// Read
|
// Read
|
||||||
void HWCALL Read16(u16& _rReturnValue, const u32 _Address);
|
void HWCALL Read16(u16& _rReturnValue, const u32 _Address);
|
||||||
|
|
|
@ -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)
|
// 0x43 -> written by OSAudioInit at the UCode upload (upload UCode)
|
||||||
// 0x63 -> ARCheckSize Mode (access AR-registers ??) or no exception ??
|
// 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 UpdateInterrupts();
|
||||||
void Update_ARAM_DMA();
|
void Update_ARAM_DMA();
|
||||||
void WriteARAM(u8 _iValue, u32 _iAddress);
|
void WriteARAM(u8 _iValue, u32 _iAddress);
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#define _DSPINTERFACE_H
|
#define _DSPINTERFACE_H
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
class ChunkFile;
|
||||||
|
|
||||||
namespace DSP
|
namespace DSP
|
||||||
{
|
{
|
||||||
|
@ -32,6 +33,8 @@ enum DSPInterruptType
|
||||||
|
|
||||||
void Init();
|
void Init();
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
|
void DoState(ChunkFile &f);
|
||||||
|
|
||||||
void GenerateDSPInterrupt(DSPInterruptType _DSPInterruptType, bool _bSet = true);
|
void GenerateDSPInterrupt(DSPInterruptType _DSPInterruptType, bool _bSet = true);
|
||||||
void GenerateDSPInterruptFromPlugin(DSPInterruptType _DSPInterruptType, bool _bSet = true);
|
void GenerateDSPInterruptFromPlugin(DSPInterruptType _DSPInterruptType, bool _bSet = true);
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,9 @@
|
||||||
// Official SVN repository and contact information can be found at
|
// Official SVN repository and contact information can be found at
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
#include "ChunkFile.h"
|
||||||
|
|
||||||
#include "StreamADPCM.H"
|
#include "StreamADPCM.H"
|
||||||
#include "DVDInterface.h"
|
#include "DVDInterface.h"
|
||||||
|
|
||||||
|
@ -44,7 +47,7 @@ namespace DVDInterface
|
||||||
20993: 00000000 DVD (zzz_80146e44 ??, 0x80146fcc) : DVD(r): 0xcc006018
|
20993: 00000000 DVD (zzz_80146e44 ??, 0x80146fcc) : DVD(r): 0xcc006018
|
||||||
|
|
||||||
After this, Cubivore infinitely calls DVDGetDriveStatus, which does not even
|
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
|
// internal hardware addresses
|
||||||
|
@ -69,7 +72,7 @@ enum DVDInterruptType
|
||||||
INT_DEINT = 0,
|
INT_DEINT = 0,
|
||||||
INT_TCINT = 1,
|
INT_TCINT = 1,
|
||||||
INT_BRKINT = 2,
|
INT_BRKINT = 2,
|
||||||
INT_CVRINT
|
INT_CVRINT = 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
// DI Status Register
|
// DI Status Register
|
||||||
|
@ -78,14 +81,14 @@ union UDISR
|
||||||
u32 Hex;
|
u32 Hex;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
unsigned BREAK : 1; // Stop the Device + Interrupt
|
unsigned BREAK : 1; // Stop the Device + Interrupt
|
||||||
unsigned DEINITMASK : 1; // Access Device Error Int Mask
|
unsigned DEINITMASK : 1; // Access Device Error Int Mask
|
||||||
unsigned DEINT : 1; // Access Device Error Int
|
unsigned DEINT : 1; // Access Device Error Int
|
||||||
unsigned TCINTMASK : 1; // Transfer Complete Int Mask
|
unsigned TCINTMASK : 1; // Transfer Complete Int Mask
|
||||||
unsigned TCINT : 1; // Transfer Complete Int
|
unsigned TCINT : 1; // Transfer Complete Int
|
||||||
unsigned BRKINTMASK : 1;
|
unsigned BRKINTMASK : 1;
|
||||||
unsigned BRKINT : 1; // w 1: clear brkint
|
unsigned BRKINT : 1; // w 1: clear brkint
|
||||||
unsigned : 25;
|
unsigned : 25;
|
||||||
};
|
};
|
||||||
UDISR() {Hex = 0;}
|
UDISR() {Hex = 0;}
|
||||||
UDISR(u32 _hex) {Hex = _hex;}
|
UDISR(u32 _hex) {Hex = _hex;}
|
||||||
|
@ -97,10 +100,10 @@ union UDICVR
|
||||||
u32 Hex;
|
u32 Hex;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
unsigned CVR : 1; // 0: Cover closed 1: Cover open
|
unsigned CVR : 1; // 0: Cover closed 1: Cover open
|
||||||
unsigned CVRINTMASK : 1; // 1: Interrupt enabled;
|
unsigned CVRINTMASK : 1; // 1: Interrupt enabled;
|
||||||
unsigned CVRINT : 1; // 1: Interrupt clear
|
unsigned CVRINT : 1; // 1: Interrupt clear
|
||||||
unsigned : 29;
|
unsigned : 29;
|
||||||
};
|
};
|
||||||
UDICVR() {Hex = 0;}
|
UDICVR() {Hex = 0;}
|
||||||
UDICVR(u32 _hex) {Hex = _hex;}
|
UDICVR(u32 _hex) {Hex = _hex;}
|
||||||
|
@ -170,11 +173,19 @@ struct DVDMemStruct
|
||||||
u32 AudioLength;
|
u32 AudioLength;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// STATE_TO_SAVE
|
||||||
DVDMemStruct dvdMem;
|
DVDMemStruct dvdMem;
|
||||||
|
u32 g_ErrorCode = 0x00;
|
||||||
|
bool g_bDiscInside = true;
|
||||||
|
|
||||||
// helper
|
void DoState(ChunkFile &f)
|
||||||
u32 g_ErrorCode = 0x00;
|
{
|
||||||
bool g_bDiscInside = true;
|
f.Descend("DI ");
|
||||||
|
f.Do(dvdMem);
|
||||||
|
f.Do(g_ErrorCode);
|
||||||
|
f.Do(g_bDiscInside);
|
||||||
|
f.Ascend();
|
||||||
|
}
|
||||||
|
|
||||||
void UpdateInterrupts();
|
void UpdateInterrupts();
|
||||||
void GenerateDVDInterrupt(DVDInterruptType _DVDInterrupt);
|
void GenerateDVDInterrupt(DVDInterruptType _DVDInterrupt);
|
||||||
|
|
|
@ -19,13 +19,14 @@
|
||||||
#define _DVDINTERFACE_H
|
#define _DVDINTERFACE_H
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
class ChunkFile;
|
||||||
|
|
||||||
namespace DVDInterface
|
namespace DVDInterface
|
||||||
{
|
{
|
||||||
|
|
||||||
// Init
|
|
||||||
void Init();
|
void Init();
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
|
void DoState(ChunkFile &f);
|
||||||
|
|
||||||
void SetDiscInside(bool _DiscInside);
|
void SetDiscInside(bool _DiscInside);
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,9 @@
|
||||||
// Official SVN repository and contact information can be found at
|
// Official SVN repository and contact information can be found at
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
#include "ChunkFile.h"
|
||||||
|
|
||||||
#include "PeripheralInterface.h"
|
#include "PeripheralInterface.h"
|
||||||
#include "../PowerPC/PowerPC.h"
|
#include "../PowerPC/PowerPC.h"
|
||||||
|
|
||||||
|
@ -50,6 +53,13 @@ void Shutdown()
|
||||||
g_Channels = 0;
|
g_Channels = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DoState(ChunkFile &f)
|
||||||
|
{
|
||||||
|
f.Descend("EXI ");
|
||||||
|
// TODO: descend all the devices recursively.
|
||||||
|
f.Ascend();
|
||||||
|
}
|
||||||
|
|
||||||
void Update()
|
void Update()
|
||||||
{
|
{
|
||||||
g_Channels[0].Update();
|
g_Channels[0].Update();
|
||||||
|
|
|
@ -18,12 +18,15 @@
|
||||||
#define _EXIINTERFACE_H
|
#define _EXIINTERFACE_H
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
class ChunkFile;
|
||||||
|
|
||||||
namespace ExpansionInterface
|
namespace ExpansionInterface
|
||||||
{
|
{
|
||||||
|
|
||||||
void Init();
|
void Init();
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
|
void DoState(ChunkFile &f);
|
||||||
|
|
||||||
void Update();
|
void Update();
|
||||||
void UpdateInterrupts();
|
void UpdateInterrupts();
|
||||||
|
|
||||||
|
|
|
@ -289,7 +289,7 @@ void CEXIMemoryCard::TransferByte(u8 &byte)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cmdSetInterrupt:
|
case cmdSetInterrupt:
|
||||||
if (m_uPosition==1)
|
if (m_uPosition == 1)
|
||||||
{
|
{
|
||||||
interruptSwitch = byte;
|
interruptSwitch = byte;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,13 +15,15 @@
|
||||||
// Official SVN repository and contact information can be found at
|
// Official SVN repository and contact information can be found at
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
#include "GPFifo.h"
|
#include "Common.h"
|
||||||
|
#include "ChunkFile.h"
|
||||||
#include "PeripheralInterface.h"
|
#include "PeripheralInterface.h"
|
||||||
#include "CommandProcessor.h"
|
#include "CommandProcessor.h"
|
||||||
#include "Memmap.h"
|
#include "Memmap.h"
|
||||||
#include "../PowerPC/PowerPC.h"
|
#include "../PowerPC/PowerPC.h"
|
||||||
|
|
||||||
|
#include "GPFifo.h"
|
||||||
|
|
||||||
namespace GPFifo
|
namespace GPFifo
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -42,6 +44,14 @@ u8 GC_ALIGNED32(m_gatherPipe[GATHER_PIPE_SIZE*16]); //more room, for the fastmod
|
||||||
// pipe counter
|
// pipe counter
|
||||||
u32 m_gatherPipeCount = 0;
|
u32 m_gatherPipeCount = 0;
|
||||||
|
|
||||||
|
void DoState(ChunkFile &f)
|
||||||
|
{
|
||||||
|
f.Descend("FIFO");
|
||||||
|
f.Do(m_gatherPipe);
|
||||||
|
f.Do(m_gatherPipeCount);
|
||||||
|
f.Ascend();
|
||||||
|
}
|
||||||
|
|
||||||
void Init()
|
void Init()
|
||||||
{
|
{
|
||||||
ResetGatherPipe();
|
ResetGatherPipe();
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#define _GPFIFO_H
|
#define _GPFIFO_H
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
class ChunkFile;
|
||||||
|
|
||||||
namespace GPFifo
|
namespace GPFifo
|
||||||
{
|
{
|
||||||
|
@ -35,6 +36,7 @@ extern u32 m_gatherPipeCount;
|
||||||
|
|
||||||
// Init
|
// Init
|
||||||
void Init();
|
void Init();
|
||||||
|
void DoState(ChunkFile &f);
|
||||||
|
|
||||||
// ResetGatherPipe
|
// ResetGatherPipe
|
||||||
void ResetGatherPipe();
|
void ResetGatherPipe();
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include "../CoreTiming.h"
|
#include "../CoreTiming.h"
|
||||||
#include "SystemTimers.h"
|
#include "SystemTimers.h"
|
||||||
#include "../IPC_HLE/WII_IPC_HLE.h"
|
#include "../IPC_HLE/WII_IPC_HLE.h"
|
||||||
|
#include "../State.h"
|
||||||
|
|
||||||
#define CURVERSION 0x0001
|
#define CURVERSION 0x0001
|
||||||
|
|
||||||
|
@ -45,7 +46,10 @@ namespace HW
|
||||||
void Init()
|
void Init()
|
||||||
{
|
{
|
||||||
Thunk_Init(); // not really hw, but this way we know it's inited first :P
|
Thunk_Init(); // not really hw, but this way we know it's inited first :P
|
||||||
|
State_Init();
|
||||||
|
|
||||||
// Init the whole Hardware
|
// Init the whole Hardware
|
||||||
|
AudioInterface::Init();
|
||||||
PixelEngine::Init();
|
PixelEngine::Init();
|
||||||
CommandProcessor::Init();
|
CommandProcessor::Init();
|
||||||
VideoInterface::Init();
|
VideoInterface::Init();
|
||||||
|
@ -72,11 +76,32 @@ namespace HW
|
||||||
DSP::Shutdown();
|
DSP::Shutdown();
|
||||||
Memory::Shutdown();
|
Memory::Shutdown();
|
||||||
SerialInterface::Shutdown();
|
SerialInterface::Shutdown();
|
||||||
|
AudioInterface::Shutdown();
|
||||||
|
|
||||||
WII_IPC_HLE_Interface::Shutdown();
|
WII_IPC_HLE_Interface::Shutdown();
|
||||||
WII_IPCInterface::Shutdown();
|
WII_IPCInterface::Shutdown();
|
||||||
|
|
||||||
|
State_Shutdown();
|
||||||
Thunk_Shutdown();
|
Thunk_Shutdown();
|
||||||
|
|
||||||
CoreTiming::UnregisterAllEvents();
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,15 +19,13 @@
|
||||||
#define _HW_H
|
#define _HW_H
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
#include "ChunkFile.h"
|
||||||
|
|
||||||
namespace HW
|
namespace HW
|
||||||
{
|
{
|
||||||
void Init();
|
void Init();
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
/*
|
void DoState(ChunkFile &f);
|
||||||
void LoadState(const char* _szFilename);
|
|
||||||
void SaveState(const char* _szFilename);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
|
||||||
|
class ChunkFile;
|
||||||
|
|
||||||
typedef void (HWCALL *writeFn8 )(const u8, const u32);
|
typedef void (HWCALL *writeFn8 )(const u8, const u32);
|
||||||
typedef void (HWCALL *writeFn16)(const u16,const u32);
|
typedef void (HWCALL *writeFn16)(const u16,const u32);
|
||||||
typedef void (HWCALL *writeFn32)(const u32,const u32);
|
typedef void (HWCALL *writeFn32)(const u32,const u32);
|
||||||
|
@ -63,6 +65,8 @@ namespace Memory
|
||||||
bool IsInitialized();
|
bool IsInitialized();
|
||||||
bool Init();
|
bool Init();
|
||||||
bool Shutdown();
|
bool Shutdown();
|
||||||
|
void DoState(ChunkFile &f);
|
||||||
|
|
||||||
void Clear();
|
void Clear();
|
||||||
bool AreMemoryBreakpointsActivated();
|
bool AreMemoryBreakpointsActivated();
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,9 @@
|
||||||
// Official SVN repository and contact information can be found at
|
// Official SVN repository and contact information can be found at
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
#include "ChunkFile.h"
|
||||||
|
|
||||||
#include "../PowerPC/PowerPC.h"
|
#include "../PowerPC/PowerPC.h"
|
||||||
#include "MemoryInterface.h"
|
#include "MemoryInterface.h"
|
||||||
|
|
||||||
|
@ -47,6 +50,13 @@ struct MIMemStruct
|
||||||
// STATE_TO_SAVE
|
// STATE_TO_SAVE
|
||||||
static MIMemStruct miMem;
|
static MIMemStruct miMem;
|
||||||
|
|
||||||
|
void DoState(ChunkFile &f)
|
||||||
|
{
|
||||||
|
f.Descend("MI ");
|
||||||
|
f.Do(miMem);
|
||||||
|
f.Ascend();
|
||||||
|
}
|
||||||
|
|
||||||
void Read16(u16& _uReturnValue, const u32 _iAddress)
|
void Read16(u16& _uReturnValue, const u32 _iAddress)
|
||||||
{
|
{
|
||||||
//0x30 -> 0x5a : gp memory metrics
|
//0x30 -> 0x5a : gp memory metrics
|
||||||
|
|
|
@ -17,8 +17,13 @@
|
||||||
#ifndef _MEMORYINTERFACE_H
|
#ifndef _MEMORYINTERFACE_H
|
||||||
#define _MEMORYINTERFACE_H
|
#define _MEMORYINTERFACE_H
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
class ChunkFile;
|
||||||
|
|
||||||
namespace MemoryInterface
|
namespace MemoryInterface
|
||||||
{
|
{
|
||||||
|
void DoState(ChunkFile &f);
|
||||||
|
|
||||||
void HWCALL Read16(u16& _uReturnValue, const u32 _iAddress);
|
void HWCALL Read16(u16& _uReturnValue, const u32 _iAddress);
|
||||||
void HWCALL Read32(u32& _uReturnValue, const u32 _iAddress);
|
void HWCALL Read32(u32& _uReturnValue, const u32 _iAddress);
|
||||||
void HWCALL Write32(const u32 _iValue, const u32 _iAddress);
|
void HWCALL Write32(const u32 _iValue, const u32 _iAddress);
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
#include "ChunkFile.h"
|
||||||
#include "../PowerPC/PowerPC.h"
|
#include "../PowerPC/PowerPC.h"
|
||||||
|
|
||||||
#include "../HW/CPU.h"
|
#include "../HW/CPU.h"
|
||||||
|
@ -31,6 +33,17 @@ u32 CPeripheralInterface::Fifo_CPUBase;
|
||||||
u32 CPeripheralInterface::Fifo_CPUEnd;
|
u32 CPeripheralInterface::Fifo_CPUEnd;
|
||||||
u32 CPeripheralInterface::Fifo_CPUWritePointer;
|
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()
|
void CPeripheralInterface::Init()
|
||||||
{
|
{
|
||||||
m_InterruptMask = 0;
|
m_InterruptMask = 0;
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
#define _PERIPHERALINTERFACE_H
|
#define _PERIPHERALINTERFACE_H
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
class ChunkFile;
|
||||||
|
|
||||||
//
|
//
|
||||||
// PERIPHERALINTERFACE
|
// PERIPHERALINTERFACE
|
||||||
// Handles communication with cpu services like the write gatherer used for fifos, and interrupts
|
// Handles communication with cpu services like the write gatherer used for fifos, and interrupts
|
||||||
|
@ -96,6 +98,7 @@ public:
|
||||||
static u32 Fifo_CPUWritePointer;
|
static u32 Fifo_CPUWritePointer;
|
||||||
|
|
||||||
static void Init();
|
static void Init();
|
||||||
|
static void DoState(ChunkFile &f);
|
||||||
|
|
||||||
static void SetInterrupt(InterruptCause _causemask, bool _bSet=true);
|
static void SetInterrupt(InterruptCause _causemask, bool _bSet=true);
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,9 @@
|
||||||
// Official SVN repository and contact information can be found at
|
// Official SVN repository and contact information can be found at
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
#include "ChunkFile.h"
|
||||||
|
|
||||||
#include "PixelEngine.h"
|
#include "PixelEngine.h"
|
||||||
|
|
||||||
#include "../CoreTiming.h"
|
#include "../CoreTiming.h"
|
||||||
|
@ -60,6 +63,16 @@ static bool g_bSignalFinishInterrupt;
|
||||||
int et_SetTokenOnMainThread;
|
int et_SetTokenOnMainThread;
|
||||||
int et_SetFinishOnMainThread;
|
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 UpdateInterrupts();
|
||||||
|
|
||||||
void SetToken_OnMainThread(u64 userdata, int cyclesLate);
|
void SetToken_OnMainThread(u64 userdata, int cyclesLate);
|
||||||
|
|
|
@ -18,10 +18,12 @@
|
||||||
#define _PIXELENGINE_H
|
#define _PIXELENGINE_H
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
class ChunkFile;
|
||||||
|
|
||||||
namespace PixelEngine
|
namespace PixelEngine
|
||||||
{
|
{
|
||||||
void Init();
|
void Init();
|
||||||
|
void DoState(ChunkFile &f);
|
||||||
|
|
||||||
// Read
|
// Read
|
||||||
void HWCALL Read16(u16& _uReturnValue, const u32 _iAddress);
|
void HWCALL Read16(u16& _uReturnValue, const u32 _iAddress);
|
||||||
|
|
|
@ -17,6 +17,9 @@
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
#include "ChunkFile.h"
|
||||||
|
|
||||||
#include "SerialInterface.h"
|
#include "SerialInterface.h"
|
||||||
#include "SerialInterface_Devices.h"
|
#include "SerialInterface_Devices.h"
|
||||||
|
|
||||||
|
@ -215,6 +218,18 @@ static USIStatusReg g_StatusReg;
|
||||||
static USIEXIClockCount g_EXIClockCount;
|
static USIEXIClockCount g_EXIClockCount;
|
||||||
static u8 g_SIBuffer[128];
|
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);
|
static void GenerateSIInterrupt(SIInterruptType _SIInterrupt);
|
||||||
void RunSIBuffer();
|
void RunSIBuffer();
|
||||||
void UpdateInterrupts();
|
void UpdateInterrupts();
|
||||||
|
@ -228,10 +243,10 @@ void Init()
|
||||||
g_Channel[i].m_InLo.Hex = 0;
|
g_Channel[i].m_InLo.Hex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int AttachedPasMask = PluginPAD::PAD_GetAttachedPads();
|
unsigned int AttachedPadMask = PluginPAD::PAD_GetAttachedPads();
|
||||||
for (int i=0; i<4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
if (AttachedPasMask & (1 << i))
|
if (AttachedPadMask & (1 << i))
|
||||||
g_Channel[i].m_pDevice = new CSIDevice_GCController(i);
|
g_Channel[i].m_pDevice = new CSIDevice_GCController(i);
|
||||||
else
|
else
|
||||||
g_Channel[i].m_pDevice = new CSIDevice_Dummy(i);
|
g_Channel[i].m_pDevice = new CSIDevice_Dummy(i);
|
||||||
|
@ -246,7 +261,7 @@ void Init()
|
||||||
|
|
||||||
void Shutdown()
|
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;
|
delete g_Channel[i].m_pDevice;
|
||||||
g_Channel[i].m_pDevice = NULL;
|
g_Channel[i].m_pDevice = NULL;
|
||||||
|
|
|
@ -19,22 +19,18 @@
|
||||||
#define _SERIALINTERFACE_H
|
#define _SERIALINTERFACE_H
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
class ChunkFile;
|
||||||
|
|
||||||
namespace SerialInterface
|
namespace SerialInterface
|
||||||
{
|
{
|
||||||
|
|
||||||
// Init
|
|
||||||
void Init();
|
void Init();
|
||||||
|
|
||||||
// Shutdown
|
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
|
void DoState(ChunkFile &f);
|
||||||
|
|
||||||
void UpdateDevices();
|
void UpdateDevices();
|
||||||
|
|
||||||
// Read32
|
|
||||||
void HWCALL Read32(u32& _uReturnValue, const u32 _iAddress);
|
void HWCALL Read32(u32& _uReturnValue, const u32 _iAddress);
|
||||||
|
|
||||||
// Write32
|
|
||||||
void HWCALL Write32(const u32 _iValue, const u32 _iAddress);
|
void HWCALL Write32(const u32 _iValue, const u32 _iAddress);
|
||||||
|
|
||||||
}; // end of namespace SerialInterface
|
}; // end of namespace SerialInterface
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#define _SERIALINTERFACE_DEVICES_H
|
#define _SERIALINTERFACE_DEVICES_H
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
class ChunkFile;
|
||||||
|
|
||||||
class ISIDevice
|
class ISIDevice
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#define _STREAMADPCM_H
|
#define _STREAMADPCM_H
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
class ChunkFile;
|
||||||
|
|
||||||
#define ONE_BLOCK_SIZE 32
|
#define ONE_BLOCK_SIZE 32
|
||||||
#define SAMPLES_PER_BLOCK 28
|
#define SAMPLES_PER_BLOCK 28
|
||||||
|
|
|
@ -7,7 +7,9 @@
|
||||||
|
|
||||||
#include "StreamADPCM.H"
|
#include "StreamADPCM.H"
|
||||||
|
|
||||||
float NGCADPCM::iir1[STEREO], NGCADPCM::iir2[STEREO];
|
// STATE_TO_SAVE
|
||||||
|
float NGCADPCM::iir1[STEREO],
|
||||||
|
NGCADPCM::iir2[STEREO];
|
||||||
|
|
||||||
void NGCADPCM::InitFilter()
|
void NGCADPCM::InitFilter()
|
||||||
{
|
{
|
||||||
|
|
|
@ -15,6 +15,9 @@
|
||||||
// Official SVN repository and contact information can be found at
|
// Official SVN repository and contact information can be found at
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
#include "ChunkFile.h"
|
||||||
|
|
||||||
#include "../PowerPC/PowerPC.h"
|
#include "../PowerPC/PowerPC.h"
|
||||||
|
|
||||||
#include "PeripheralInterface.h"
|
#include "PeripheralInterface.h"
|
||||||
|
@ -83,30 +86,44 @@ union UVIInterruptRegister
|
||||||
};
|
};
|
||||||
|
|
||||||
// STATE_TO_SAVE
|
// STATE_TO_SAVE
|
||||||
UVIDisplayControlRegister m_VIDisplayControlRegister;
|
static UVIDisplayControlRegister m_VIDisplayControlRegister;
|
||||||
|
|
||||||
// Framebuffers
|
// Framebuffers
|
||||||
u32 m_FrameBuffer1; // normal framebuffer address
|
static u32 m_FrameBuffer1; // normal framebuffer address
|
||||||
u32 m_FrameBuffer2; // framebuffer for 3d buffer address
|
static u32 m_FrameBuffer2; // framebuffer for 3d buffer address
|
||||||
|
|
||||||
// VI Interrupt Registers
|
// VI Interrupt Registers
|
||||||
UVIInterruptRegister m_VIInterruptRegister[4];
|
static UVIInterruptRegister m_VIInterruptRegister[4];
|
||||||
|
|
||||||
u8 m_UVIUnknownRegs[0x1000];
|
u8 m_UVIUnknownRegs[0x1000];
|
||||||
|
|
||||||
u16 HorizontalBeamPos = 0;
|
static u16 HorizontalBeamPos = 0;
|
||||||
u16 VerticalBeamPos = 0;
|
static u16 VerticalBeamPos = 0;
|
||||||
|
|
||||||
u32 TicksPerFrame = 0;
|
static u32 TicksPerFrame = 0;
|
||||||
u32 LineCount = 0;
|
static u32 LineCount = 0;
|
||||||
u64 LastTime = 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()
|
void Init()
|
||||||
{
|
{
|
||||||
for (int i=0; i<4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
{
|
|
||||||
m_VIInterruptRegister[i].Hex = 0x00;
|
m_VIInterruptRegister[i].Hex = 0x00;
|
||||||
}
|
|
||||||
|
|
||||||
m_VIDisplayControlRegister.Hex = 0x0000;
|
m_VIDisplayControlRegister.Hex = 0x0000;
|
||||||
m_VIDisplayControlRegister.ENB = 0;
|
m_VIDisplayControlRegister.ENB = 0;
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#define _VIDEOINTERFACE_H
|
#define _VIDEOINTERFACE_H
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
class ChunkFile;
|
||||||
|
|
||||||
namespace VideoInterface
|
namespace VideoInterface
|
||||||
{
|
{
|
||||||
|
@ -29,20 +30,18 @@ namespace VideoInterface
|
||||||
INT_REG_3,
|
INT_REG_3,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Init
|
|
||||||
void Init();
|
void Init();
|
||||||
|
void DoState(ChunkFile &f);
|
||||||
|
|
||||||
// Read
|
|
||||||
void HWCALL Read16(u16& _uReturnValue, const u32 _uAddress);
|
void HWCALL Read16(u16& _uReturnValue, const u32 _uAddress);
|
||||||
void HWCALL Read32(u32& _uReturnValue, const u32 _uAddress);
|
void HWCALL Read32(u32& _uReturnValue, const u32 _uAddress);
|
||||||
|
|
||||||
// Write
|
|
||||||
void HWCALL Write16(const u16 _uValue, const u32 _uAddress);
|
void HWCALL Write16(const u16 _uValue, const u32 _uAddress);
|
||||||
void HWCALL Write32(const u32 _uValue, const u32 _uAddress);
|
void HWCALL Write32(const u32 _uValue, const u32 _uAddress);
|
||||||
|
|
||||||
void GenerateVIInterrupt(VIInterruptType _VIInterrupt);
|
void GenerateVIInterrupt(VIInterruptType _VIInterrupt);
|
||||||
|
|
||||||
// returns a pointer to the framebuffer
|
// returns a pointer to the current visible framebuffer
|
||||||
u8* GetFrameBufferPointer();
|
u8* GetFrameBufferPointer();
|
||||||
|
|
||||||
// pre init
|
// pre init
|
||||||
|
@ -51,7 +50,6 @@ namespace VideoInterface
|
||||||
// VI Unknown Regs
|
// VI Unknown Regs
|
||||||
extern u8 m_UVIUnknownRegs[0x1000];
|
extern u8 m_UVIUnknownRegs[0x1000];
|
||||||
|
|
||||||
|
|
||||||
// ??????
|
// ??????
|
||||||
void Update();
|
void Update();
|
||||||
|
|
||||||
|
@ -59,7 +57,6 @@ namespace VideoInterface
|
||||||
// UpdateInterrupts: check if we have to generate a new VI Interrupt
|
// UpdateInterrupts: check if we have to generate a new VI Interrupt
|
||||||
void UpdateInterrupts();
|
void UpdateInterrupts();
|
||||||
|
|
||||||
|
|
||||||
// ??????
|
// ??????
|
||||||
void UpdateTiming();
|
void UpdateTiming();
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
#include "ChunkFile.h"
|
||||||
#include "WII_IOB.h"
|
#include "WII_IOB.h"
|
||||||
|
|
||||||
namespace WII_IOBridge
|
namespace WII_IOBridge
|
||||||
|
|
|
@ -17,16 +17,16 @@
|
||||||
#ifndef _WII_IOBRIDGE_H_
|
#ifndef _WII_IOBRIDGE_H_
|
||||||
#define _WII_IOBRIDGE_H_
|
#define _WII_IOBRIDGE_H_
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
class ChunkFile;
|
||||||
|
|
||||||
namespace WII_IOBridge
|
namespace WII_IOBridge
|
||||||
{
|
{
|
||||||
|
|
||||||
// Init
|
|
||||||
void Init();
|
void Init();
|
||||||
|
|
||||||
// Shutdown
|
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
|
void DoState(ChunkFile &f);
|
||||||
|
|
||||||
// Update
|
|
||||||
void Update();
|
void Update();
|
||||||
|
|
||||||
void HWCALL Read8(u8& _rReturnValue, const u32 _Address);
|
void HWCALL Read8(u8& _rReturnValue, const u32 _Address);
|
||||||
|
|
|
@ -18,13 +18,14 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "WII_IPC.h"
|
#include "ChunkFile.h"
|
||||||
|
|
||||||
#include "CPU.h"
|
#include "CPU.h"
|
||||||
#include "Memmap.h"
|
#include "Memmap.h"
|
||||||
#include "PeripheralInterface.h"
|
#include "PeripheralInterface.h"
|
||||||
|
|
||||||
#include "../IPC_HLE/WII_IPC_HLE.h"
|
#include "../IPC_HLE/WII_IPC_HLE.h"
|
||||||
|
#include "WII_IPC.h"
|
||||||
|
|
||||||
namespace WII_IPCInterface
|
namespace WII_IPCInterface
|
||||||
{
|
{
|
||||||
|
@ -92,6 +93,17 @@ u32 g_Address = 0;
|
||||||
u32 g_Reply = 0;
|
u32 g_Reply = 0;
|
||||||
u32 g_SensorBarPower = 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();
|
void UpdateInterrupts();
|
||||||
|
|
||||||
|
|
|
@ -17,18 +17,17 @@
|
||||||
#ifndef _WII_IPC_H_
|
#ifndef _WII_IPC_H_
|
||||||
#define _WII_IPC_H_
|
#define _WII_IPC_H_
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
class ChunkFile;
|
||||||
|
|
||||||
namespace WII_IPCInterface
|
namespace WII_IPCInterface
|
||||||
{
|
{
|
||||||
|
|
||||||
// Init
|
|
||||||
void Init();
|
void Init();
|
||||||
|
|
||||||
// Shutdown
|
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
|
void DoState(ChunkFile &f);
|
||||||
|
|
||||||
// Update
|
|
||||||
void Update();
|
void Update();
|
||||||
|
|
||||||
bool IsReady();
|
bool IsReady();
|
||||||
void GenerateReply(u32 _AnswerAddress);
|
void GenerateReply(u32 _AnswerAddress);
|
||||||
void GenerateAck(u32 _AnswerAddress);
|
void GenerateAck(u32 _AnswerAddress);
|
||||||
|
|
|
@ -15,6 +15,9 @@
|
||||||
// Official SVN repository and contact information can be found at
|
// Official SVN repository and contact information can be found at
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
#include "ChunkFile.h"
|
||||||
|
|
||||||
#include "../HW/Memmap.h"
|
#include "../HW/Memmap.h"
|
||||||
#include "../HW/CPU.h"
|
#include "../HW/CPU.h"
|
||||||
#include "../Core.h"
|
#include "../Core.h"
|
||||||
|
@ -29,10 +32,19 @@
|
||||||
|
|
||||||
namespace PowerPC
|
namespace PowerPC
|
||||||
{
|
{
|
||||||
|
// STATE_TO_SAVE
|
||||||
PowerPCState GC_ALIGNED16(ppcState);
|
PowerPCState GC_ALIGNED16(ppcState);
|
||||||
|
volatile CPUState state = CPU_STEPPING;
|
||||||
|
|
||||||
ICPUCore* m_pCore = NULL;
|
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()
|
void ResetRegisters()
|
||||||
{
|
{
|
||||||
|
|
|
@ -29,6 +29,8 @@
|
||||||
#include "Gekko.h"
|
#include "Gekko.h"
|
||||||
#include "ICPUCore.h"
|
#include "ICPUCore.h"
|
||||||
|
|
||||||
|
class ChunkFile;
|
||||||
|
|
||||||
namespace PowerPC
|
namespace PowerPC
|
||||||
{
|
{
|
||||||
enum ECoreType
|
enum ECoreType
|
||||||
|
@ -85,6 +87,8 @@ namespace PowerPC
|
||||||
|
|
||||||
void Init();
|
void Init();
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
|
void DoState(ChunkFile &f);
|
||||||
|
|
||||||
void SetCore(ECoreType _coreType);
|
void SetCore(ECoreType _coreType);
|
||||||
|
|
||||||
ICPUCore& GetCore();
|
ICPUCore& GetCore();
|
||||||
|
|
|
@ -4,11 +4,12 @@ files = ["Console.cpp",
|
||||||
"Core.cpp",
|
"Core.cpp",
|
||||||
"CoreTiming.cpp",
|
"CoreTiming.cpp",
|
||||||
"CoreParameter.cpp",
|
"CoreParameter.cpp",
|
||||||
"LogManager.cpp",
|
|
||||||
"PatchEngine.cpp",
|
|
||||||
"MemTools.cpp",
|
|
||||||
"Tracer.cpp",
|
|
||||||
"Host.cpp",
|
"Host.cpp",
|
||||||
|
"LogManager.cpp",
|
||||||
|
"MemTools.cpp",
|
||||||
|
"PatchEngine.cpp",
|
||||||
|
"State.cpp",
|
||||||
|
"Tracer.cpp",
|
||||||
"VolumeHandler.cpp",
|
"VolumeHandler.cpp",
|
||||||
"Boot/Boot.cpp",
|
"Boot/Boot.cpp",
|
||||||
"Boot/Boot_DOL.cpp",
|
"Boot/Boot_DOL.cpp",
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
|
@ -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
|
Loading…
Reference in New Issue