mirror of
https://github.com/izzy2lost/dolphin.git
synced 2026-06-19 01:16:48 -07:00
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:
@@ -455,6 +455,14 @@
|
||||
RelativePath=".\Src\ABI.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\ChunkFile.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\ChunkFile.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
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",
|
||||
"Common.cpp",
|
||||
"ChunkFile.cpp",
|
||||
"CPUDetect.cpp",
|
||||
"DynamicLibrary.cpp",
|
||||
"Hash.cpp",
|
||||
|
||||
@@ -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"
|
||||
>
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -289,7 +289,7 @@ void CEXIMemoryCard::TransferByte(u8 &byte)
|
||||
break;
|
||||
|
||||
case cmdSetInterrupt:
|
||||
if (m_uPosition==1)
|
||||
if (m_uPosition == 1)
|
||||
{
|
||||
interruptSwitch = byte;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user