slot-1 savestates

This commit is contained in:
zeromus 2013-08-31 18:30:09 +00:00
parent 7555d69e9e
commit dd56e6c231
13 changed files with 178 additions and 120 deletions

View File

@ -83,120 +83,16 @@ public:
{
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(); }
// ///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 ---------------------------------

View File

@ -78,6 +78,18 @@ public:
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:
u32 slot1client_read_GCDATAIN(eSlot1Operation operation)

View File

@ -88,6 +88,18 @@ public:
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)
{
if (protocol.operation == eSlot1Operation_B7_Read)

View File

@ -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);
}
};

View File

@ -222,4 +222,31 @@ u32 Slot1Comp_Protocol::read_GCDATAIN(u8 PROCNUM)
}
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();
}

View File

@ -65,6 +65,9 @@ public:
class Slot1Comp_Protocol
{
public:
void savestate(EMUFILE* os);
void loadstate(EMUFILE* is);
//set some kind of protocol/hardware reset state
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
ISlot1Comp_Protocol_Client* client;
//--state--
//the major operational mode. the protocol shifts modes and interprets commands into operations differently depending on the mode
eCardMode mode;

View File

@ -103,3 +103,19 @@ u32 Slot1Comp_Rom::incAddress()
address = (address&~0xFFF) + ((address+4)&0xFFF);
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();
}

View File

@ -19,7 +19,7 @@
//this is largely done by accessing the rom provided in the core emulator
#include "slot1comp_protocol.h"
#include "emufile.h"
class Slot1Comp_Rom
{
@ -28,6 +28,10 @@ public:
u32 read();
u32 getAddress();
u32 incAddress();
void savestate(EMUFILE* os);
void loadstate(EMUFILE* is);
private:
u32 address;
eSlot1Operation operation;

View File

@ -258,3 +258,25 @@ size_t EMUFILE::readdouble(double* val)
*val = u64_to_double(temp);
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);
}
}

View File

@ -43,6 +43,8 @@ THE SOFTWARE.
#include <unistd.h>
#endif
class EMUFILE_MEMORY;
class EMUFILE {
protected:
bool failbit;
@ -120,6 +122,10 @@ public:
virtual void fflush() = 0;
virtual void truncate(s32 length) = 0;
void writeMemoryStream(EMUFILE_MEMORY* ms);
void readMemoryStream(EMUFILE_MEMORY* ms);
};
//todo - handle read-only specially?
@ -182,10 +188,10 @@ public:
va_start(argptr, format);
vsprintf(tempbuf,format,argptr);
fwrite(tempbuf,amt);
fwrite(tempbuf,amt);
delete[] tempbuf;
va_end(argptr);
va_end(argptr);
return amt;
};

View File

@ -43,6 +43,7 @@
#include "movie.h"
#include "mic.h"
#include "MMU_timing.h"
#include "slot1.h"
#include "path.h"
@ -364,6 +365,39 @@ SFORMAT reserveChunks[] = {
{ 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)
{
u32 version = 8;
@ -952,8 +986,8 @@ static void writechunks(EMUFILE* os) {
savestate_WriteChunk(os,110,SF_WIFI);
savestate_WriteChunk(os,120,SF_RTC);
savestate_WriteChunk(os,130,SF_NDS_HEADER);
savestate_WriteChunk(os,140,s_slot1_savestate);
// reserved for future versions
savestate_WriteChunk(os,140,reserveChunks);
savestate_WriteChunk(os,150,reserveChunks);
savestate_WriteChunk(os,160,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 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 140: if(!s_slot1_loadstate(is, size)) ret=false; break;
// reserved for future versions
case 140:
case 150:
case 160:
case 170:

View File

@ -166,6 +166,14 @@ NDS_SLOT1_TYPE slot1_GetCurrentType()
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 -------------------------------------
// ///writetoGCControl:

View File

@ -80,6 +80,10 @@ public:
//called when the auxspi burst is ended (SPI chipselect in is going low)
virtual void auxspi_reset(int PROCNUM) {}
virtual void savestate(EMUFILE* os) {}
virtual void loadstate(EMUFILE* is) {}
};
typedef ISlot1Interface* TISlot1InterfaceConstructor();
@ -102,6 +106,8 @@ void slot1_Init();
bool slot1_Connect();
void slot1_Disconnect();
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
void slot1_Reset();