slot-1 savestates
This commit is contained in:
parent
7555d69e9e
commit
dd56e6c231
|
@ -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 ---------------------------------
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue