slot-1 savestates
This commit is contained in:
parent
7555d69e9e
commit
dd56e6c231
|
@ -83,120 +83,16 @@ public:
|
||||||
{
|
{
|
||||||
mSelectedImplementation->auxspi_reset(PROCNUM);
|
mSelectedImplementation->auxspi_reset(PROCNUM);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void savestate(EMUFILE* os)
|
||||||
|
{
|
||||||
|
mSelectedImplementation->savestate(os);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void loadstate(EMUFILE* is)
|
||||||
|
{
|
||||||
|
mSelectedImplementation->loadstate(is);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ISlot1Interface* construct_Slot1_Retail_Auto() { return new Slot1_Retail_Auto(); }
|
ISlot1Interface* construct_Slot1_Retail_Auto() { return new Slot1_Retail_Auto(); }
|
||||||
|
|
||||||
// ///writetoGCControl:
|
|
||||||
//// --- Ninja SD commands -------------------------------------
|
|
||||||
|
|
||||||
// // NJSD init/reset
|
|
||||||
// case 0x20:
|
|
||||||
// {
|
|
||||||
// card.address = 0;
|
|
||||||
// card.transfer_count = 0;
|
|
||||||
// }
|
|
||||||
// break;
|
|
||||||
|
|
||||||
// // NJSD_sendCLK()
|
|
||||||
// case 0xE0:
|
|
||||||
// {
|
|
||||||
// card.address = 0;
|
|
||||||
// card.transfer_count = 0;
|
|
||||||
// NDS_makeInt(PROCNUM, 20);
|
|
||||||
// }
|
|
||||||
// break;
|
|
||||||
|
|
||||||
// // NJSD_sendCMDN() / NJSD_sendCMDR()
|
|
||||||
// case 0xF0:
|
|
||||||
// case 0xF1:
|
|
||||||
// switch (card.command[2])
|
|
||||||
// {
|
|
||||||
// // GO_IDLE_STATE
|
|
||||||
// case 0x40:
|
|
||||||
// card.address = 0;
|
|
||||||
// card.transfer_count = 0;
|
|
||||||
// NDS_makeInt(PROCNUM, 20);
|
|
||||||
// break;
|
|
||||||
|
|
||||||
// case 0x42: // ALL_SEND_CID
|
|
||||||
// case 0x43: // SEND_RELATIVE_ADDR
|
|
||||||
// case 0x47: // SELECT_CARD
|
|
||||||
// case 0x49: // SEND_CSD
|
|
||||||
// case 0x4D:
|
|
||||||
// case 0x77: // APP_CMD
|
|
||||||
// case 0x69: // SD_APP_OP_COND
|
|
||||||
// card.address = 0;
|
|
||||||
// card.transfer_count = 6;
|
|
||||||
// NDS_makeInt(PROCNUM, 20);
|
|
||||||
// break;
|
|
||||||
|
|
||||||
// // SET_BLOCKLEN
|
|
||||||
// case 0x50:
|
|
||||||
// card.address = 0;
|
|
||||||
// card.transfer_count = 6;
|
|
||||||
// card.blocklen = card.command[6] | (card.command[5] << 8) | (card.command[4] << 16) | (card.command[3] << 24);
|
|
||||||
// NDS_makeInt(PROCNUM, 20);
|
|
||||||
// break;
|
|
||||||
|
|
||||||
// // READ_SINGLE_BLOCK
|
|
||||||
// case 0x51:
|
|
||||||
// card.address = card.command[6] | (card.command[5] << 8) | (card.command[4] << 16) | (card.command[3] << 24);
|
|
||||||
// card.transfer_count = (card.blocklen + 3) >> 2;
|
|
||||||
// NDS_makeInt(PROCNUM, 20);
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// break;
|
|
||||||
|
|
||||||
// // --- Ninja SD commands end ---------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// //GCDATAIN:
|
|
||||||
// // --- Ninja SD commands -------------------------------------
|
|
||||||
|
|
||||||
// // NJSD_sendCMDN() / NJSD_sendCMDR()
|
|
||||||
// case 0xF0:
|
|
||||||
// case 0xF1:
|
|
||||||
// switch (card.command[2])
|
|
||||||
// {
|
|
||||||
// // ALL_SEND_CID
|
|
||||||
// case 0x42:
|
|
||||||
// if (card.transfer_count == 2) val = 0x44534A4E;
|
|
||||||
// else val = 0x00000000;
|
|
||||||
|
|
||||||
// // SEND_RELATIVE_ADDR
|
|
||||||
// case 0x43:
|
|
||||||
// case 0x47:
|
|
||||||
// case 0x49:
|
|
||||||
// case 0x50:
|
|
||||||
// val = 0x00000000;
|
|
||||||
// break;
|
|
||||||
|
|
||||||
// case 0x4D:
|
|
||||||
// if (card.transfer_count == 2) val = 0x09000000;
|
|
||||||
// else val = 0x00000000;
|
|
||||||
// break;
|
|
||||||
|
|
||||||
// // APP_CMD
|
|
||||||
// case 0x77:
|
|
||||||
// if (card.transfer_count == 2) val = 0x00000037;
|
|
||||||
// else val = 0x00000000;
|
|
||||||
// break;
|
|
||||||
|
|
||||||
// // SD_APP_OP_COND
|
|
||||||
// case 0x69:
|
|
||||||
// if (card.transfer_count == 2) val = 0x00008000;
|
|
||||||
// else val = 0x00000000;
|
|
||||||
// break;
|
|
||||||
|
|
||||||
// // READ_SINGLE_BLOCK
|
|
||||||
// case 0x51:
|
|
||||||
// val = 0x00000000;
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// break;
|
|
||||||
|
|
||||||
// // --- Ninja SD commands end ---------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -78,6 +78,18 @@ public:
|
||||||
rom.start(operation,protocol.address);
|
rom.start(operation,protocol.address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void savestate(EMUFILE* os)
|
||||||
|
{
|
||||||
|
protocol.savestate(os);
|
||||||
|
rom.savestate(os);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void loadstate(EMUFILE* is)
|
||||||
|
{
|
||||||
|
protocol.loadstate(is);
|
||||||
|
rom.loadstate(is);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
u32 slot1client_read_GCDATAIN(eSlot1Operation operation)
|
u32 slot1client_read_GCDATAIN(eSlot1Operation operation)
|
||||||
|
|
|
@ -88,6 +88,18 @@ public:
|
||||||
return protocol.read_GCDATAIN(PROCNUM);
|
return protocol.read_GCDATAIN(PROCNUM);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void savestate(EMUFILE* os)
|
||||||
|
{
|
||||||
|
protocol.savestate(os);
|
||||||
|
rom.savestate(os);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void loadstate(EMUFILE* is)
|
||||||
|
{
|
||||||
|
protocol.loadstate(is);
|
||||||
|
rom.loadstate(is);
|
||||||
|
}
|
||||||
|
|
||||||
virtual void slot1client_startOperation(eSlot1Operation operation)
|
virtual void slot1client_startOperation(eSlot1Operation operation)
|
||||||
{
|
{
|
||||||
if (protocol.operation == eSlot1Operation_B7_Read)
|
if (protocol.operation == eSlot1Operation_B7_Read)
|
||||||
|
|
|
@ -155,7 +155,17 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void savestate(EMUFILE* os)
|
||||||
|
{
|
||||||
|
protocol.savestate(os);
|
||||||
|
rom.savestate(os);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void loadstate(EMUFILE* is)
|
||||||
|
{
|
||||||
|
protocol.loadstate(is);
|
||||||
|
rom.loadstate(is);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -223,3 +223,30 @@ u32 Slot1Comp_Protocol::read_GCDATAIN(u8 PROCNUM)
|
||||||
|
|
||||||
return 0xFFFFFFFF;
|
return 0xFFFFFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Slot1Comp_Protocol::savestate(EMUFILE* os)
|
||||||
|
{
|
||||||
|
s32 version = 0;
|
||||||
|
os->write32le(version);
|
||||||
|
os->write32le((s32)mode);
|
||||||
|
os->write32le((s32)operation);
|
||||||
|
os->fwrite(command.bytes,8);
|
||||||
|
os->write32le(address);
|
||||||
|
os->write32le(length);
|
||||||
|
os->write32le(delay);
|
||||||
|
os->write32le(chipId);
|
||||||
|
os->write32le(gameCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Slot1Comp_Protocol::loadstate(EMUFILE* is)
|
||||||
|
{
|
||||||
|
s32 version = is->read32le();
|
||||||
|
mode = (eCardMode)is->read32le();
|
||||||
|
operation = (eSlot1Operation)is->read32le();
|
||||||
|
is->fread(command.bytes,8);
|
||||||
|
address = is->read32le();
|
||||||
|
length = is->read32le();
|
||||||
|
delay = is->read32le();
|
||||||
|
chipId = is->read32le();
|
||||||
|
gameCode = is->read32le();
|
||||||
|
}
|
|
@ -66,6 +66,9 @@ class Slot1Comp_Protocol
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
void savestate(EMUFILE* os);
|
||||||
|
void loadstate(EMUFILE* is);
|
||||||
|
|
||||||
//set some kind of protocol/hardware reset state
|
//set some kind of protocol/hardware reset state
|
||||||
void reset(ISlot1Comp_Protocol_Client* client);
|
void reset(ISlot1Comp_Protocol_Client* client);
|
||||||
|
|
||||||
|
@ -82,6 +85,8 @@ public:
|
||||||
//operations not related to obscurities of the protocol or otherwise unknown are passed through to the client here
|
//operations not related to obscurities of the protocol or otherwise unknown are passed through to the client here
|
||||||
ISlot1Comp_Protocol_Client* client;
|
ISlot1Comp_Protocol_Client* client;
|
||||||
|
|
||||||
|
//--state--
|
||||||
|
|
||||||
//the major operational mode. the protocol shifts modes and interprets commands into operations differently depending on the mode
|
//the major operational mode. the protocol shifts modes and interprets commands into operations differently depending on the mode
|
||||||
eCardMode mode;
|
eCardMode mode;
|
||||||
|
|
||||||
|
|
|
@ -103,3 +103,19 @@ u32 Slot1Comp_Rom::incAddress()
|
||||||
address = (address&~0xFFF) + ((address+4)&0xFFF);
|
address = (address&~0xFFF) + ((address+4)&0xFFF);
|
||||||
return address;
|
return address;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Slot1Comp_Rom::savestate(EMUFILE* os)
|
||||||
|
{
|
||||||
|
s32 version = 0;
|
||||||
|
os->write32le(version);
|
||||||
|
os->write32le((s32)operation);
|
||||||
|
os->write32le(address);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Slot1Comp_Rom::loadstate(EMUFILE* is)
|
||||||
|
{
|
||||||
|
s32 version = is->read32le();
|
||||||
|
operation = (eSlot1Operation)is->read32le();
|
||||||
|
address = is->read32le();
|
||||||
|
}
|
|
@ -19,7 +19,7 @@
|
||||||
//this is largely done by accessing the rom provided in the core emulator
|
//this is largely done by accessing the rom provided in the core emulator
|
||||||
|
|
||||||
#include "slot1comp_protocol.h"
|
#include "slot1comp_protocol.h"
|
||||||
|
#include "emufile.h"
|
||||||
|
|
||||||
class Slot1Comp_Rom
|
class Slot1Comp_Rom
|
||||||
{
|
{
|
||||||
|
@ -28,6 +28,10 @@ public:
|
||||||
u32 read();
|
u32 read();
|
||||||
u32 getAddress();
|
u32 getAddress();
|
||||||
u32 incAddress();
|
u32 incAddress();
|
||||||
|
|
||||||
|
void savestate(EMUFILE* os);
|
||||||
|
void loadstate(EMUFILE* is);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
u32 address;
|
u32 address;
|
||||||
eSlot1Operation operation;
|
eSlot1Operation operation;
|
||||||
|
|
|
@ -258,3 +258,25 @@ size_t EMUFILE::readdouble(double* val)
|
||||||
*val = u64_to_double(temp);
|
*val = u64_to_double(temp);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EMUFILE::writeMemoryStream(EMUFILE_MEMORY* ms)
|
||||||
|
{
|
||||||
|
s32 size = (s32)ms->size();
|
||||||
|
write32le(size);
|
||||||
|
if(size>0)
|
||||||
|
{
|
||||||
|
std::vector<u8>* vec = ms->get_vec();
|
||||||
|
fwrite(&vec->at(0),size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EMUFILE::readMemoryStream(EMUFILE_MEMORY* ms)
|
||||||
|
{
|
||||||
|
s32 size = read32le();
|
||||||
|
if(size != 0)
|
||||||
|
{
|
||||||
|
std::vector<u8> temp(size);
|
||||||
|
fread(&temp[0],size);
|
||||||
|
ms->fwrite(&temp[0],size);
|
||||||
|
}
|
||||||
|
}
|
|
@ -43,6 +43,8 @@ THE SOFTWARE.
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
class EMUFILE_MEMORY;
|
||||||
|
|
||||||
class EMUFILE {
|
class EMUFILE {
|
||||||
protected:
|
protected:
|
||||||
bool failbit;
|
bool failbit;
|
||||||
|
@ -120,6 +122,10 @@ public:
|
||||||
virtual void fflush() = 0;
|
virtual void fflush() = 0;
|
||||||
|
|
||||||
virtual void truncate(s32 length) = 0;
|
virtual void truncate(s32 length) = 0;
|
||||||
|
|
||||||
|
void writeMemoryStream(EMUFILE_MEMORY* ms);
|
||||||
|
void readMemoryStream(EMUFILE_MEMORY* ms);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//todo - handle read-only specially?
|
//todo - handle read-only specially?
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
#include "movie.h"
|
#include "movie.h"
|
||||||
#include "mic.h"
|
#include "mic.h"
|
||||||
#include "MMU_timing.h"
|
#include "MMU_timing.h"
|
||||||
|
#include "slot1.h"
|
||||||
|
|
||||||
#include "path.h"
|
#include "path.h"
|
||||||
|
|
||||||
|
@ -364,6 +365,39 @@ SFORMAT reserveChunks[] = {
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static bool s_slot1_loadstate(EMUFILE* is, int size)
|
||||||
|
{
|
||||||
|
u32 version = is->read32le();
|
||||||
|
|
||||||
|
//version 0:
|
||||||
|
if(version >= 0)
|
||||||
|
{
|
||||||
|
int slotType = is->read32le();
|
||||||
|
slot1_Change((NDS_SLOT1_TYPE)slotType);
|
||||||
|
|
||||||
|
EMUFILE_MEMORY temp;
|
||||||
|
is->readMemoryStream(&temp);
|
||||||
|
temp.fseek(0,SEEK_SET);
|
||||||
|
slot1_Loadstate(&temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void s_slot1_savestate(EMUFILE* os)
|
||||||
|
{
|
||||||
|
u32 version = 0;
|
||||||
|
os->write32le(version);
|
||||||
|
|
||||||
|
//version 0:
|
||||||
|
int slotType = (int)slot1_GetCurrentType();
|
||||||
|
os->write32le(slotType);
|
||||||
|
|
||||||
|
EMUFILE_MEMORY temp;
|
||||||
|
slot1_Savestate(&temp);
|
||||||
|
os->writeMemoryStream(&temp);
|
||||||
|
}
|
||||||
|
|
||||||
static void mmu_savestate(EMUFILE* os)
|
static void mmu_savestate(EMUFILE* os)
|
||||||
{
|
{
|
||||||
u32 version = 8;
|
u32 version = 8;
|
||||||
|
@ -952,8 +986,8 @@ static void writechunks(EMUFILE* os) {
|
||||||
savestate_WriteChunk(os,110,SF_WIFI);
|
savestate_WriteChunk(os,110,SF_WIFI);
|
||||||
savestate_WriteChunk(os,120,SF_RTC);
|
savestate_WriteChunk(os,120,SF_RTC);
|
||||||
savestate_WriteChunk(os,130,SF_NDS_HEADER);
|
savestate_WriteChunk(os,130,SF_NDS_HEADER);
|
||||||
|
savestate_WriteChunk(os,140,s_slot1_savestate);
|
||||||
// reserved for future versions
|
// reserved for future versions
|
||||||
savestate_WriteChunk(os,140,reserveChunks);
|
|
||||||
savestate_WriteChunk(os,150,reserveChunks);
|
savestate_WriteChunk(os,150,reserveChunks);
|
||||||
savestate_WriteChunk(os,160,reserveChunks);
|
savestate_WriteChunk(os,160,reserveChunks);
|
||||||
savestate_WriteChunk(os,170,reserveChunks);
|
savestate_WriteChunk(os,170,reserveChunks);
|
||||||
|
@ -1003,8 +1037,8 @@ static bool ReadStateChunks(EMUFILE* is, s32 totalsize)
|
||||||
case 110: if(!ReadStateChunk(is,SF_WIFI,size)) ret=false; break;
|
case 110: if(!ReadStateChunk(is,SF_WIFI,size)) ret=false; break;
|
||||||
case 120: if(!ReadStateChunk(is,SF_RTC,size)) ret=false; break;
|
case 120: if(!ReadStateChunk(is,SF_RTC,size)) ret=false; break;
|
||||||
case 130: if(!ReadStateChunk(is,SF_HEADER,size)) ret=false; else haveInfo=true; break;
|
case 130: if(!ReadStateChunk(is,SF_HEADER,size)) ret=false; else haveInfo=true; break;
|
||||||
|
case 140: if(!s_slot1_loadstate(is, size)) ret=false; break;
|
||||||
// reserved for future versions
|
// reserved for future versions
|
||||||
case 140:
|
|
||||||
case 150:
|
case 150:
|
||||||
case 160:
|
case 160:
|
||||||
case 170:
|
case 170:
|
||||||
|
|
|
@ -166,6 +166,14 @@ NDS_SLOT1_TYPE slot1_GetCurrentType()
|
||||||
return slot1_device_type;
|
return slot1_device_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void slot1_Savestate(EMUFILE* os)
|
||||||
|
{
|
||||||
|
slot1_device->savestate(os);
|
||||||
|
}
|
||||||
|
void slot1_Loadstate(EMUFILE* is)
|
||||||
|
{
|
||||||
|
slot1_device->loadstate(is);
|
||||||
|
}
|
||||||
|
|
||||||
//// --- Ninja SD commands notes -------------------------------------
|
//// --- Ninja SD commands notes -------------------------------------
|
||||||
// ///writetoGCControl:
|
// ///writetoGCControl:
|
||||||
|
|
|
@ -80,6 +80,10 @@ public:
|
||||||
|
|
||||||
//called when the auxspi burst is ended (SPI chipselect in is going low)
|
//called when the auxspi burst is ended (SPI chipselect in is going low)
|
||||||
virtual void auxspi_reset(int PROCNUM) {}
|
virtual void auxspi_reset(int PROCNUM) {}
|
||||||
|
|
||||||
|
virtual void savestate(EMUFILE* os) {}
|
||||||
|
|
||||||
|
virtual void loadstate(EMUFILE* is) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef ISlot1Interface* TISlot1InterfaceConstructor();
|
typedef ISlot1Interface* TISlot1InterfaceConstructor();
|
||||||
|
@ -102,6 +106,8 @@ void slot1_Init();
|
||||||
bool slot1_Connect();
|
bool slot1_Connect();
|
||||||
void slot1_Disconnect();
|
void slot1_Disconnect();
|
||||||
void slot1_Shutdown();
|
void slot1_Shutdown();
|
||||||
|
void slot1_Savestate(EMUFILE* os);
|
||||||
|
void slot1_Loadstate(EMUFILE* is);
|
||||||
|
|
||||||
//just disconnects and reconnects the device. ideally, the disconnection and connection would be called with sensible timing
|
//just disconnects and reconnects the device. ideally, the disconnection and connection would be called with sensible timing
|
||||||
void slot1_Reset();
|
void slot1_Reset();
|
||||||
|
|
Loading…
Reference in New Issue