- add mmu to savestate.

- totally change how the savestates work in order to fix a bug in the gfx3d savestate. your old savestates are definitely invalidated.
- rename adress to address everywhere.
This commit is contained in:
zeromus 2008-09-27 06:52:33 +00:00
parent a45b610c70
commit 6a696d6bb8
8 changed files with 360 additions and 304 deletions

View File

@ -2011,6 +2011,7 @@ void GPU_ligne(NDS_Screen * screen, u16 l)
/* initialize the scanline black */
/* not doing this causes invalid colors when all active BGs are prevented to draw at some place */
//ZERO TODO - shouldnt this be BG palette color 0?
memset(dst,0,256*2) ;
// This could almost be changed to use function pointers

View File

@ -647,7 +647,7 @@ u16 FASTCALL _MMU_read16(u32 adr)
if(adr&0x04000000)
{
/* Adress is an IO register */
/* Address is an IO register */
switch(adr)
{
case 0x04000604:
@ -721,7 +721,7 @@ u32 FASTCALL _MMU_read32(u32 adr)
if((adr >> 24) == 4)
{
/* Adress is an IO register */
/* Address is an IO register */
switch(adr)
{
// This is hacked due to the only current 3D core
@ -826,10 +826,10 @@ u32 FASTCALL _MMU_read32(u32 adr)
{
u32 val=0;
if(MMU.dscard[proc].adress)
val = T1ReadLong(MMU.CART_ROM, MMU.dscard[proc].adress);
if(MMU.dscard[proc].address)
val = T1ReadLong(MMU.CART_ROM, MMU.dscard[proc].address);
MMU.dscard[proc].adress += 4; /* increment adress */
MMU.dscard[proc].address += 4; /* increment address */
MMU.dscard[proc].transfer_count--; /* update transfer counter */
if(MMU.dscard[proc].transfer_count) /* if transfer is not ended */
@ -1306,7 +1306,7 @@ void FASTCALL _MMU_write16(u32 adr, u16 val)
((u16 *)(MMU.MMU_MEM[proc][0x40]))[(adr-0x04000000)>>1] = val;
gfx3d_UpdateToonTable(&((MMU.MMU_MEM[proc][0x40]))[(0x380)]);
}
/* Adress is an IO register */
/* Address is an IO register */
else switch(adr)
{
case 0x0400035C:
@ -2843,7 +2843,7 @@ void FASTCALL _MMU_write32(u32 adr, u32 val)
if(MEM_8(MMU.MMU_MEM[proc], REG_GCCMDOUT) == 0xB7)
{
MMU.dscard[proc].adress = (MEM_8(MMU.MMU_MEM[proc], REG_GCCMDOUT+1) << 24) | (MEM_8(MMU.MMU_MEM[proc], REG_GCCMDOUT+2) << 16) | (MEM_8(MMU.MMU_MEM[proc], REG_GCCMDOUT+3) << 8) | (MEM_8(MMU.MMU_MEM[proc], REG_GCCMDOUT+4));
MMU.dscard[proc].address = (MEM_8(MMU.MMU_MEM[proc], REG_GCCMDOUT+1) << 24) | (MEM_8(MMU.MMU_MEM[proc], REG_GCCMDOUT+2) << 16) | (MEM_8(MMU.MMU_MEM[proc], REG_GCCMDOUT+3) << 8) | (MEM_8(MMU.MMU_MEM[proc], REG_GCCMDOUT+4));
MMU.dscard[proc].transfer_count = 0x80;// * ((val>>24)&7));
}
else if (MEM_8(MMU.MMU_MEM[proc], REG_GCCMDOUT) == 0xB8)
@ -2851,7 +2851,7 @@ void FASTCALL _MMU_write32(u32 adr, u32 val)
// Get ROM chip ID
val |= 0x800000; // Data-Word Status
T1WriteLong(MMU.MMU_MEM[proc][(REG_GCROMCTRL >> 20) & 0xff], REG_GCROMCTRL & 0xfff, val);
MMU.dscard[proc].adress = 0;
MMU.dscard[proc].address = 0;
}
else
{
@ -2861,7 +2861,7 @@ void FASTCALL _MMU_write32(u32 adr, u32 val)
//CARDLOG("%08X : %08X %08X\r\n", adr, val, adresse[proc]);
val |= 0x00800000;
if(MMU.dscard[proc].adress == 0)
if(MMU.dscard[proc].address == 0)
{
val &= ~0x80000000;
T1WriteLong(MMU.MMU_MEM[proc][(REG_GCROMCTRL >> 20) & 0xff], REG_GCROMCTRL & 0xfff, val);

View File

@ -33,7 +33,7 @@
extern char szRomPath[512];
extern char szRomBaseName[512];
/* theses macros are designed for reading/writing in memory (m is a pointer to memory, like MMU.MMU_MEM[proc], and a is an adress, like 0x04000000 */
/* theses macros are designed for reading/writing in memory (m is a pointer to memory, like MMU.MMU_MEM[proc], and a is an address, like 0x04000000 */
#define MEM_8(m, a) (((u8*)(m[((a)>>20)&0xff]))[((a)&0xfff)])
/* theses ones for reading in rom data */
@ -43,60 +43,59 @@ extern char szRomBaseName[512];
//#define MAIN_MEMORY_DISP_FIFO 2
typedef struct {
//ARM7 mem
u8 ARM7_BIOS[0x4000];
u8 ARM7_ERAM[0x10000];
u8 ARM7_REG[0x10000];
u8 ARM7_WIRAM[0x10000];
//ARM7 mem
u8 ARM7_BIOS[0x4000];
u8 ARM7_ERAM[0x10000];
u8 ARM7_REG[0x10000];
u8 ARM7_WIRAM[0x10000];
u8 vram_mode[9];
u8 vScreen;
//Shared ram
u8 SWIRAM[0x8000];
//Card rom & ram
u8 * CART_ROM;
u8 CART_RAM[0x10000];
//Shared ram
u8 SWIRAM[0x8000];
//Card rom & ram
u8 * CART_ROM;
u8 CART_RAM[0x10000];
//Unused ram
u8 UNUSED_RAM[4];
u8 * * MMU_MEM[2];
u32 * MMU_MASK[2];
u8 ARM9_RW_MODE;
u8 * * MMU_MEM[2];
u32 * MMU_MASK[2];
u8 ARM9_RW_MODE;
FIFO fifos[2]; // 0 - ARM9 FIFO
// 1 - ARM7 FIFO
FIFO fifos[2]; // 0 - ARM9 FIFO
// 1 - ARM7 FIFO
u32 * MMU_WAIT16[2];
u32 * MMU_WAIT32[2];
u32 * MMU_WAIT16[2];
u32 * MMU_WAIT32[2];
u32 DTCMRegion;
u32 ITCMRegion;
u16 timer[2][4];
s32 timerMODE[2][4];
u32 timerON[2][4];
u32 timerRUN[2][4];
u16 timerReload[2][4];
u32 reg_IME[2];
u32 reg_IE[2];
u32 reg_IF[2];
u32 DMAStartTime[2][4];
s32 DMACycle[2][4];
u32 DMACrt[2][4];
BOOL DMAing[2][4];
memory_chip_t fw;
memory_chip_t bupmem;
nds_dscard dscard[2];
u32 CheckTimers;
u32 CheckDMAs;
u32 DTCMRegion;
u32 ITCMRegion;
u16 timer[2][4];
s32 timerMODE[2][4];
u32 timerON[2][4];
u32 timerRUN[2][4];
u16 timerReload[2][4];
u32 reg_IME[2];
u32 reg_IE[2];
u32 reg_IF[2];
u32 DMAStartTime[2][4];
s32 DMACycle[2][4];
u32 DMACrt[2][4];
BOOL DMAing[2][4];
memory_chip_t fw;
memory_chip_t bupmem;
nds_dscard dscard[2];
u32 CheckTimers;
u32 CheckDMAs;
} MMU_struct;

View File

@ -1502,7 +1502,7 @@ bool spu_loadstate(std::istream* is)
//copy the core spu (the more accurate) to the user spu
if(SPU_user) {
memcpy(SPU_core->channels,SPU_user->channels,sizeof(SPU_core->channels));
memcpy(SPU_user->channels,SPU_core->channels,sizeof(SPU_core->channels));
}
return true;

View File

@ -23,7 +23,7 @@
typedef struct
{
u32 adress;
u32 address;
u32 transfer_count;
} nds_dscard;

View File

@ -1472,71 +1472,71 @@ void gfx3d_glGetLightColor(unsigned int index, unsigned int* dest)
SFORMAT SF_GFX3D[]={
{ &control, 4|SS_RLSB, "GCTL" },
{ &polyAttr, 4|SS_RLSB, "GPAT" },
{ &textureFormat, 4|SS_RLSB, "GTFM" },
{ &texturePalette, 4|SS_RLSB, "GTPA" },
{ &mode, 4|SS_RLSB, "GMOD" },
{ mtxTemporal, 4|SS_MULT(16), "GMTM" },
{ mtxCurrent, 4|SS_MULT(64), "GMCU" },
{ &mtxStack[0].position, 4|SS_RLSB, "GM0P" },
{ mtxStack[0].matrix, 4|SS_MULT(16), "GM1M" },
{ &mtxStack[1].position, 4|SS_RLSB, "GM1P" },
{ mtxStack[1].matrix, 4|SS_MULT(16*31), "GM1M" },
{ &mtxStack[2].position, 4|SS_RLSB, "GM2P" },
{ mtxStack[2].matrix, 4|SS_MULT(16*31), "GM2M" },
{ &mtxStack[3].position, 4|SS_RLSB, "GM3P" },
{ mtxStack[3].matrix, 4|SS_MULT(16), "GM3M" },
{ &ML4x4ind, 1, "ML4I" },
{ &ML4x3_c, 1, "ML3C" },
{ &ML4x3_l, 1, "ML3L" },
{ &MM4x4ind, 1, "MM4I" },
{ &MM4x3_c, 1, "MM3C" },
{ &MM4x3_l, 1, "MM3L" },
{ &MM3x3_c, 1, "MMxC" },
{ &MM3x3_l, 1, "MMxL" },
{ coord, 4|SS_MULT(4), "GCOR" },
{ &coordind, 1, "GCOI" },
{ &vtxFormat, 4|SS_RLSB, "GCOI" },
{ trans, 4|SS_MULT(4), "GTRN" },
{ &transind, 1, "GTRI" },
{ scale, 4|SS_MULT(4), "GSCA" },
{ &scaleind, 1, "GSCI" },
{ &_t, 4|SS_RLSB, "G_T_" },
{ &_s, 4|SS_RLSB, "G_S_" },
{ &last_t, 4|SS_RLSB, "GL_T" },
{ &last_s, 4|SS_RLSB, "GL_S" },
{ &clCmd, 4|SS_RLSB, "GLCM" },
{ &clInd, 4|SS_RLSB, "GLIN" },
{ &clInd2, 4|SS_RLSB, "GLI2" },
{ colorRGB, 4, "GCOL" },
{ lightColor, 4|SS_MULT(4), "GLCO" },
{ lightDirection, 4|SS_MULT(4), "GLDI" },
{ &dsDiffuse, 2|SS_RLSB, "GMDI" },
{ &dsAmbient, 2|SS_RLSB, "GMAM" },
{ &dsSpecular, 2|SS_RLSB, "GMSP" },
{ &dsEmission, 2|SS_RLSB, "GMEM" },
{ &triStripToggle, 4|SS_RLSB, "GTST" },
{ &listTwiddle, 4|SS_RLSB, "GLTW" },
{ &flushPending, 4|SS_RLSB, "GFLP" },
{ &gfx3d.enableTexturing, 4|SS_RLSB, "GSET" },
{ &gfx3d.enableAlphaTest, 4|SS_RLSB, "GSEA" },
{ &gfx3d.enableAlphaBlending, 4|SS_RLSB, "GSEB" },
{ &gfx3d.enableAntialiasing, 4|SS_RLSB, "GSEX" },
{ &gfx3d.enableEdgeMarking, 4|SS_RLSB, "GSEE" },
{ &gfx3d.shading, 4|SS_RLSB, "GSSH" },
{ &gfx3d.wbuffer, 4|SS_RLSB, "GSWB" },
{ &gfx3d.sortmode, 4|SS_RLSB, "GSSM" },
{ &gfx3d.alphaTestRef, 4|SS_RLSB, "GSAR" },
{ &gfx3d.viewport.x, 4|SS_RLSB, "GSVX" },
{ &gfx3d.viewport.y, 4|SS_RLSB, "GSVY" },
{ &gfx3d.viewport.width, 4|SS_RLSB, "GSVW" },
{ &gfx3d.viewport.height, 4|SS_RLSB, "GSVH" },
{ gfx3d.clearColor, 4|SS_MULT(4), "GSCC" },
{ &gfx3d.clearDepth , 4|SS_RLSB, "GSCD" },
{ gfx3d.fogColor, 4|SS_MULT(4), "GSFC" },
{ &gfx3d.fogOffset, 4|SS_RLSB, "GSFO" },
{ gfx3d.rgbToonTable, 4|SS_MULT(32), "GSTT" },
{ "GCTL", 4, 1, &control},
{ "GPAT", 4, 1, &polyAttr},
{ "GTFM", 4, 1, &textureFormat},
{ "GTPA", 4, 1, &texturePalette},
{ "GMOD", 4, 1, &mode},
{ "GMTM", 4,16, mtxTemporal},
{ "GMCU", 4,64, mtxCurrent},
{ "GM0P", 4, 1, &mtxStack[0].position},
{ "GM1M", 4,16, mtxStack[0].matrix},
{ "GM1P", 4, 1, &mtxStack[1].position},
{ "GM1M", 4,496,mtxStack[1].matrix},
{ "GM2P", 4, 1, &mtxStack[2].position},
{ "GM2M", 4,496,mtxStack[2].matrix},
{ "GM3P", 4, 1, &mtxStack[3].position},
{ "GM3M", 4,16, mtxStack[3].matrix},
{ "ML4I", 1, 1, &ML4x4ind},
{ "ML3C", 1, 1, &ML4x3_c},
{ "ML3L", 1, 1, &ML4x3_l},
{ "MM4I", 1, 1, &MM4x4ind},
{ "MM3C", 1, 1, &MM4x3_c},
{ "MM3L", 1, 1, &MM4x3_l},
{ "MMxC", 1, 1, &MM3x3_c},
{ "MMxL", 1, 1, &MM3x3_l},
{ "GCOR", 4, 1, coord},
{ "GCOI", 1, 1, &coordind},
{ "GVFM", 4, 1, &vtxFormat},
{ "GTRN", 4, 4, trans},
{ "GTRI", 1, 1, &transind},
{ "GSCA", 4, 4, scale},
{ "GSCI", 1, 1, &scaleind},
{ "G_T_", 4, 1, &_t},
{ "G_S_", 4, 1, &_s},
{ "GL_T", 4, 1, &last_t},
{ "GL_S", 4, 1, &last_s},
{ "GLCM", 4, 1, &clCmd},
{ "GLIN", 4, 1, &clInd},
{ "GLI2", 4, 1, &clInd2},
{ "GCOL", 1, 4, colorRGB},
{ "GLCO", 4, 4, lightColor},
{ "GLDI", 4, 4, lightDirection},
{ "GMDI", 2, 1, &dsDiffuse},
{ "GMAM", 2, 1, &dsAmbient},
{ "GMSP", 2, 1, &dsSpecular},
{ "GMEM", 2, 1, &dsEmission},
{ "GTST", 4, 1, &triStripToggle},
{ "GLTW", 4, 1, &listTwiddle},
{ "GFLP", 4, 1, &flushPending},
{ "GSET", 4, 1, &gfx3d.enableTexturing},
{ "GSEA", 4, 1, &gfx3d.enableAlphaTest},
{ "GSEB", 4, 1, &gfx3d.enableAlphaBlending},
{ "GSEX", 4, 1, &gfx3d.enableAntialiasing},
{ "GSEE", 4, 1, &gfx3d.enableEdgeMarking},
{ "GSSH", 4, 1, &gfx3d.shading},
{ "GSWB", 4, 1, &gfx3d.wbuffer},
{ "GSSM", 4, 1, &gfx3d.sortmode},
{ "GSAR", 4, 1, &gfx3d.alphaTestRef},
{ "GSVX", 4, 1, &gfx3d.viewport.x},
{ "GSVY", 4, 1, &gfx3d.viewport.y},
{ "GSVW", 4, 1, &gfx3d.viewport.width},
{ "GSVH", 4, 1, &gfx3d.viewport.height},
{ "GSCC", 4, 4, gfx3d.clearColor},
{ "GSCD", 4, 1, &gfx3d.clearDepth},
{ "GSFC", 4, 4, gfx3d.fogColor},
{ "GSFO", 4, 1, &gfx3d.fogOffset},
{ "GSTT", 4, 32, gfx3d.rgbToonTable},
{ 0 }
};

View File

@ -51,120 +51,188 @@ static const char* magic = "DeSmuME SState\0";
SFORMAT SF_ARM7[]={
{ &NDS_ARM7.instruction, 4|SS_RLSB, "7INS" },
{ &NDS_ARM7.instruct_adr, 4|SS_RLSB, "7INA" },
{ &NDS_ARM7.next_instruction, 4|SS_RLSB, "7INN" },
{ NDS_ARM7.R, 4|SS_MULT(16), "7REG" },
{ &NDS_ARM7.CPSR, 4|SS_RLSB, "7CPS" },
{ &NDS_ARM7.SPSR, 4|SS_RLSB, "7SPS" },
{ &NDS_ARM7.R13_usr, 4|SS_RLSB, "7DUS" },
{ &NDS_ARM7.R14_usr, 4|SS_RLSB, "7EUS" },
{ &NDS_ARM7.R13_svc, 4|SS_RLSB, "7DSV" },
{ &NDS_ARM7.R14_svc, 4|SS_RLSB, "7ESV" },
{ &NDS_ARM7.R13_abt, 4|SS_RLSB, "7DAB" },
{ &NDS_ARM7.R14_abt, 4|SS_RLSB, "7EAB" },
{ &NDS_ARM7.R13_und, 4|SS_RLSB, "7DUN" },
{ &NDS_ARM7.R14_und, 4|SS_RLSB, "7EUN" },
{ &NDS_ARM7.R13_irq, 4|SS_RLSB, "7DIR" },
{ &NDS_ARM7.R14_irq, 4|SS_RLSB, "7EIR" },
{ &NDS_ARM7.R8_fiq, 4|SS_RLSB, "78FI" },
{ &NDS_ARM7.R9_fiq, 4|SS_RLSB, "79FI" },
{ &NDS_ARM7.R10_fiq, 4|SS_RLSB, "7AFI" },
{ &NDS_ARM7.R11_fiq, 4|SS_RLSB, "7BFI" },
{ &NDS_ARM7.R12_fiq, 4|SS_RLSB, "7CFI" },
{ &NDS_ARM7.R13_fiq, 4|SS_RLSB, "7DFI" },
{ &NDS_ARM7.R14_fiq, 4|SS_RLSB, "7EFI" },
{ &NDS_ARM7.SPSR_svc, 4|SS_RLSB, "7SVC" },
{ &NDS_ARM7.SPSR_abt, 4|SS_RLSB, "7ABT" },
{ &NDS_ARM7.SPSR_und, 4|SS_RLSB, "7UND" },
{ &NDS_ARM7.SPSR_irq, 4|SS_RLSB, "7IRQ" },
{ &NDS_ARM7.SPSR_fiq, 4|SS_RLSB, "7FIQ" },
{ &NDS_ARM7.intVector, 4|SS_RLSB, "7int" },
{ &NDS_ARM7.LDTBit, 1, "7LDT" },
{ &NDS_ARM7.waitIRQ, 4|SS_RLSB, "7Wai" },
{ &NDS_ARM7.wIRQ, 4|SS_RLSB, "7wIR" },
{ &NDS_ARM7.wirq, 4|SS_RLSB, "7wir" },
{ "7INS", 4, 1, &NDS_ARM7.instruction },
{ "7INA", 4, 1, &NDS_ARM7.instruct_adr },
{ "7INN", 4, 1, &NDS_ARM7.next_instruction },
{ "7REG", 4,16, NDS_ARM7.R },
{ "7CPS", 4, 1, &NDS_ARM7.CPSR },
{ "7SPS", 4, 1, &NDS_ARM7.SPSR },
{ "7DUS", 4, 1, &NDS_ARM7.R13_usr },
{ "7EUS", 4, 1, &NDS_ARM7.R14_usr },
{ "7DSV", 4, 1, &NDS_ARM7.R13_svc },
{ "7ESV", 4, 1, &NDS_ARM7.R14_svc },
{ "7DAB", 4, 1, &NDS_ARM7.R13_abt },
{ "7EAB", 4, 1, &NDS_ARM7.R14_abt },
{ "7DUN", 4, 1, &NDS_ARM7.R13_und },
{ "7EUN", 4, 1, &NDS_ARM7.R14_und },
{ "7DIR", 4, 1, &NDS_ARM7.R13_irq },
{ "7EIR", 4, 1, &NDS_ARM7.R14_irq },
{ "78FI", 4, 1, &NDS_ARM7.R8_fiq },
{ "79FI", 4, 1, &NDS_ARM7.R9_fiq },
{ "7AFI", 4, 1, &NDS_ARM7.R10_fiq },
{ "7BFI", 4, 1, &NDS_ARM7.R11_fiq },
{ "7CFI", 4, 1, &NDS_ARM7.R12_fiq },
{ "7DFI", 4, 1, &NDS_ARM7.R13_fiq },
{ "7EFI", 4, 1, &NDS_ARM7.R14_fiq },
{ "7SVC", 4, 1, &NDS_ARM7.SPSR_svc },
{ "7ABT", 4, 1, &NDS_ARM7.SPSR_abt },
{ "7UND", 4, 1, &NDS_ARM7.SPSR_und },
{ "7IRQ", 4, 1, &NDS_ARM7.SPSR_irq },
{ "7FIQ", 4, 1, &NDS_ARM7.SPSR_fiq },
{ "7int", 4, 1, &NDS_ARM7.intVector },
{ "7LDT", 1, 1, &NDS_ARM7.LDTBit },
{ "7Wai", 4, 1, &NDS_ARM7.waitIRQ },
{ "7wIR", 4, 1, &NDS_ARM7.wIRQ, },
{ "7wir", 4, 1, &NDS_ARM7.wirq, },
{ 0 }
};
SFORMAT SF_ARM9[]={
{ &NDS_ARM9.instruction, 4|SS_RLSB, "9INS" },
{ &NDS_ARM9.instruct_adr, 4|SS_RLSB, "9INA" },
{ &NDS_ARM9.next_instruction, 4|SS_RLSB, "9INN" },
{ NDS_ARM9.R, 4|SS_MULT(16), "9REG" },
{ &NDS_ARM9.CPSR, 4|SS_RLSB, "9CPS" },
{ &NDS_ARM9.SPSR, 4|SS_RLSB, "9SPS" },
{ &NDS_ARM9.R13_usr, 4|SS_RLSB, "9DUS" },
{ &NDS_ARM9.R14_usr, 4|SS_RLSB, "9EUS" },
{ &NDS_ARM9.R13_svc, 4|SS_RLSB, "9DSV" },
{ &NDS_ARM9.R14_svc, 4|SS_RLSB, "9ESV" },
{ &NDS_ARM9.R13_abt, 4|SS_RLSB, "9DAB" },
{ &NDS_ARM9.R14_abt, 4|SS_RLSB, "9EAB" },
{ &NDS_ARM9.R13_und, 4|SS_RLSB, "9DUN" },
{ &NDS_ARM9.R14_und, 4|SS_RLSB, "9EUN" },
{ &NDS_ARM9.R13_irq, 4|SS_RLSB, "9DIR" },
{ &NDS_ARM9.R14_irq, 4|SS_RLSB, "9EIR" },
{ &NDS_ARM9.R8_fiq, 4|SS_RLSB, "98FI" },
{ &NDS_ARM9.R9_fiq, 4|SS_RLSB, "99FI" },
{ &NDS_ARM9.R10_fiq, 4|SS_RLSB, "9AFI" },
{ &NDS_ARM9.R11_fiq, 4|SS_RLSB, "9BFI" },
{ &NDS_ARM9.R12_fiq, 4|SS_RLSB, "9CFI" },
{ &NDS_ARM9.R13_fiq, 4|SS_RLSB, "9DFI" },
{ &NDS_ARM9.R14_fiq, 4|SS_RLSB, "9EFI" },
{ &NDS_ARM9.SPSR_svc, 4|SS_RLSB, "9SVC" },
{ &NDS_ARM9.SPSR_abt, 4|SS_RLSB, "9ABT" },
{ &NDS_ARM9.SPSR_und, 4|SS_RLSB, "9UND" },
{ &NDS_ARM9.SPSR_irq, 4|SS_RLSB, "9IRQ" },
{ &NDS_ARM9.SPSR_fiq, 4|SS_RLSB, "9FIQ" },
{ &NDS_ARM9.intVector, 4|SS_RLSB, "9int" },
{ &NDS_ARM9.LDTBit, 1, "9LDT" },
{ &NDS_ARM9.waitIRQ, 4|SS_RLSB, "9Wai" },
{ &NDS_ARM9.wIRQ, 4|SS_RLSB, "9wIR" },
{ &NDS_ARM9.wirq, 4|SS_RLSB, "9wir" },
{ "9INS", 4, 1, &NDS_ARM9.instruction},
{ "9INA", 4, 1, &NDS_ARM9.instruct_adr},
{ "9INN", 4, 1, &NDS_ARM9.next_instruction},
{ "9REG", 4,16, NDS_ARM9.R},
{ "9CPS", 4, 1, &NDS_ARM9.CPSR},
{ "9SPS", 4, 1, &NDS_ARM9.SPSR},
{ "9DUS", 4, 1, &NDS_ARM9.R13_usr},
{ "9EUS", 4, 1, &NDS_ARM9.R14_usr},
{ "9DSV", 4, 1, &NDS_ARM9.R13_svc},
{ "9ESV", 4, 1, &NDS_ARM9.R14_svc},
{ "9DAB", 4, 1, &NDS_ARM9.R13_abt},
{ "9EAB", 4, 1, &NDS_ARM9.R14_abt},
{ "9DUN", 4, 1, &NDS_ARM9.R13_und},
{ "9EUN", 4, 1, &NDS_ARM9.R14_und},
{ "9DIR", 4, 1, &NDS_ARM9.R13_irq},
{ "9EIR", 4, 1, &NDS_ARM9.R14_irq},
{ "98FI", 4, 1, &NDS_ARM9.R8_fiq},
{ "99FI", 4, 1, &NDS_ARM9.R9_fiq},
{ "9AFI", 4, 1, &NDS_ARM9.R10_fiq},
{ "9BFI", 4, 1, &NDS_ARM9.R11_fiq},
{ "9CFI", 4, 1, &NDS_ARM9.R12_fiq},
{ "9DFI", 4, 1, &NDS_ARM9.R13_fiq},
{ "9EFI", 4, 1, &NDS_ARM9.R14_fiq},
{ "9SVC", 4, 1, &NDS_ARM9.SPSR_svc},
{ "9ABT", 4, 1, &NDS_ARM9.SPSR_abt},
{ "9UND", 4, 1, &NDS_ARM9.SPSR_und},
{ "9IRQ", 4, 1, &NDS_ARM9.SPSR_irq},
{ "9FIQ", 4, 1, &NDS_ARM9.SPSR_fiq},
{ "9int", 4, 1, &NDS_ARM9.intVector},
{ "9LDT", 1, 1, &NDS_ARM9.LDTBit},
{ "9Wai", 4, 1, &NDS_ARM9.waitIRQ},
{ "9wIR", 4, 1, &NDS_ARM9.wIRQ},
{ "9wir", 4, 1, &NDS_ARM9.wirq},
{ 0 }
};
SFORMAT SF_MEM[]={
{ ARM9Mem.ARM9_ITCM, 0x8000, "ITCM" },
{ ARM9Mem.ARM9_DTCM, 0x4000, "DTCM" },
{ ARM9Mem.MAIN_MEM, 0x400000, "WRAM" },
{ "ITCM", 1, 0x8000, ARM9Mem.ARM9_ITCM},
{ "DTCM", 1, 0x4000, ARM9Mem.ARM9_DTCM},
{ "WRAM", 1, 0x400000, ARM9Mem.MAIN_MEM},
//NOTE - this is not as large as the allocated memory.
//the memory is overlarge due to the way our memory map system is setup
//but there are actually no more registers than this
{ ARM9Mem.ARM9_REG, 0x2000, "9REG" },
{ "9REG", 1, 0x2000, ARM9Mem.ARM9_REG},
{ ARM9Mem.ARM9_VMEM, 0x800, "VMEM" },
{ ARM9Mem.ARM9_OAM, 0x800, "OAMS" },
{ ARM9Mem.ARM9_ABG, 0x80000, "ABGM" },
{ ARM9Mem.ARM9_BBG, 0x20000, "BBGM" },
{ ARM9Mem.ARM9_AOBJ, 0x40000, "AOBJ" },
{ ARM9Mem.ARM9_BOBJ, 0x20000, "BOBJ" },
{ ARM9Mem.ARM9_LCD, 0xA4000, "LCDM" },
{ MMU.ARM7_ERAM, 0x10000, "ERAM" },
{ MMU.ARM7_REG, 0x10000, "7REG" },
{ MMU.ARM7_WIRAM, 0x10000, "WIRA" },
{ MMU.SWIRAM, 0x8000, "SWIR" },
{ MMU.CART_RAM, SRAM_SIZE, "SRAM" },
{ "VMEM", 1, 0x800, ARM9Mem.ARM9_VMEM},
{ "OAMS", 1, 0x800, ARM9Mem.ARM9_OAM},
{ "ABGM", 1, 0x80000, ARM9Mem.ARM9_ABG},
{ "BBGM", 1, 0x20000, ARM9Mem.ARM9_BBG},
{ "AOBJ", 1, 0x40000, ARM9Mem.ARM9_AOBJ},
{ "BOBJ", 1, 0x20000, ARM9Mem.ARM9_BOBJ},
{ "LCDM", 1, 0xA4000, ARM9Mem.ARM9_LCD},
{ 0 }
};
SFORMAT SF_NDS[]={
{ &nds.ARM9Cycle, 4|SS_RLSB, "_9CY" },
{ &nds.ARM7Cycle, 4|SS_RLSB, "_7CY" },
{ &nds.cycles, 4|SS_RLSB, "_CYC" },
{ nds.timerCycle, 4|SS_MULT(8), "_TCY" },
{ nds.timerOver, 4|SS_MULT(8), "_TOV" },
{ &nds.nextHBlank, 4|SS_RLSB, "_NHB" },
{ &nds.VCount, 4|SS_RLSB, "_VCT" },
{ &nds.old, 4|SS_RLSB, "_OLD" },
{ &nds.diff, 4|SS_RLSB, "_DIF" },
{ &nds.lignerendu, 4|SS_RLSB, "_LIG" },
{ &nds.touchX, 2|SS_RLSB, "_TPX" },
{ &nds.touchY, 2|SS_RLSB, "_TPY" },
{ "_9CY", 4, 1, &nds.ARM9Cycle},
{ "_7CY", 4, 1, &nds.ARM7Cycle},
{ "_CYC", 4, 1, &nds.cycles},
{ "_TCY", 4, 8, nds.timerCycle},
{ "_TOV", 4, 8, nds.timerOver},
{ "_NHB", 4, 1, &nds.nextHBlank},
{ "_VCT", 4, 1, &nds.VCount},
{ "_OLD", 4, 1, &nds.old},
{ "_DIF", 4, 1, &nds.diff},
{ "_LIG", 4, 1, &nds.lignerendu},
{ "_TPX", 2, 1, &nds.touchX},
{ "_TPY", 2, 1, &nds.touchY},
{ 0 }
};
SFORMAT SF_MMU[]={
{ "M7BI", 1, 0x4000, MMU.ARM7_BIOS},
{ "M7ER", 1, 0x10000, MMU.ARM7_ERAM},
{ "M7RG", 1, 0x10000, MMU.ARM7_REG},
{ "M7WI", 1, 0x10000, MMU.ARM7_WIRAM},
{ "MVRM", 1, 9, MMU.vram_mode},
{ "MSWI", 1, 0x8000, MMU.SWIRAM},
{ "MCRA", 1, 0x10000, MMU.CART_RAM},
{ "M9RW", 1, 1, &MMU.ARM9_RW_MODE},
{ "MDTC", 4, 1, &MMU.DTCMRegion},
{ "MITC", 4, 1, &MMU.ITCMRegion},
{ "MTIM", 2, 8, MMU.timer},
{ "MTMO", 4, 8, MMU.timerMODE},
{ "MTON", 4, 8, MMU.timerON},
{ "MTRN", 4, 8, MMU.timerRUN},
{ "MTRL", 2, 8, MMU.timerReload},
{ "MIME", 4, 2, MMU.reg_IME},
{ "MIE_", 4, 2, MMU.reg_IE},
{ "MIF_", 4, 2, MMU.reg_IF},
{ "MDST", 4, 8, MMU.DMAStartTime},
{ "MDCY", 4, 8, MMU.DMACycle},
{ "MDCR", 4, 8, MMU.DMACrt},
{ "MDMA", 4, 8, MMU.DMAing},
//begin memory chips
//we are skipping the firmware, because we really don't want to save the firmware to the savestate
//but, we will need to think about the philosophy of this.
//should we perhaps hash the current firmware and save it, so that we can match it against the loader's firmware?
{ "BUCO", 1, 1, &MMU.bupmem.com},
{ "BUAD", 4, 1, &MMU.bupmem.addr},
{ "BUAS", 1, 1, &MMU.bupmem.addr_shift},
{ "BUAZ", 1, 1, &MMU.bupmem.addr_size},
{ "BUWE", 4, 1, &MMU.bupmem.write_enable},
//writeable_buffer ???
//end memory chips
{ "MC0A", 4, 1, &MMU.dscard[0].address},
{ "MC0T", 4, 1, &MMU.dscard[0].transfer_count},
{ "MC1A", 4, 1, &MMU.dscard[1].address},
{ "MC1T", 4, 1, &MMU.dscard[1].transfer_count},
{ "MCHT", 4, 1, &MMU.CheckTimers},
{ "MCHD", 4, 1, &MMU.CheckDMAs},
{ 0 }
};
void mmu_savestate(std::ostream* os)
{
//version
write32le(0,os);
write32le(MMU.bupmem.size,os);
os->write((char*)MMU.bupmem.data,MMU.bupmem.size);
}
bool mmu_loadstate(std::istream* is)
{
//read version
int version;
if(read32le(&version,is) != 1) return false;
if(version != 0) return false;
u32 bupmem_size;
if(read32le(&bupmem_size,is) != 1) return false;
if(bupmem_size != MMU.bupmem.size) return false; //mismatch between current initialized and saved size
is->read((char*)MMU.bupmem.data,bupmem_size);
if(is->fail()) return false;
return true;
}
/* Format time and convert to string */
char * format_time(time_t cal_time)
{
@ -281,27 +349,28 @@ int sram_save (const char *file_name) {
}
static SFORMAT *CheckS(SFORMAT *sf, u32 tsize, char *desc)
static SFORMAT *CheckS(SFORMAT *sf, u32 size, u32 count, char *desc)
{
while(sf->v)
{
if(sf->s==~0) // Link to another SFORMAT structure.
{
SFORMAT *tmp;
if((tmp= CheckS((SFORMAT *)sf->v, tsize, desc) ))
return(tmp);
sf++;
continue;
}
//NOT SUPPORTED RIGHT NOW
//if(sf->size==~0) // Link to another SFORMAT structure.
//{
// SFORMAT *tmp;
// if((tmp= CheckS((SFORMAT *)sf->v, tsize, desc) ))
// return(tmp);
// sf++;
// continue;
//}
if(!memcmp(desc,sf->desc,4))
{
if(tsize!=(sf->s))
return(0);
return(sf);
if(sf->size != size || sf->count != count)
return 0;
return sf;
}
sf++;
}
return(0);
return 0;
}
@ -312,34 +381,31 @@ static bool ReadStateChunk(std::istream* is, SFORMAT *sf, int size)
while(is->tellg()<temp+size)
{
u32 tsize;
u32 size, count;
char toa[4];
is->read(toa,4);
if(is->fail())
return false;
read32le(&tsize,is);
int count = SS_UNMULT(tsize);
int size = tsize & ~SS_FLAGS;
bool rlsb = (count!=0);
if(!read32le(&size,is)) return false;
if(!read32le(&count,is)) return false;
if((tmp=CheckS(sf,tsize,toa)))
if((tmp=CheckS(sf,size,count,toa)))
{
if(count == 0) count=1;
for(int i=0;i<count;i++) {
if(tmp->s&SS_INDIRECT)
is->read(*(char **)tmp->v,size);
else
if(size == 1) {
//special case: read a huge byte array
is->read((char *)tmp->v,count);
} else {
for(int i=0;i<count;i++)
{
is->read((char *)tmp->v + i*size,size);
#ifndef LOCAL_LE
if(rlsb)
FlipByteOrder((u8*)tmp->v + i*size,size);
#endif
#ifndef LOCAL_LE
if(rlsb)
FlipByteOrder((u8*)tmp->v + i*size,size);
#endif
}
}
}
else
@ -356,50 +422,49 @@ static int SubWrite(std::ostream* os, SFORMAT *sf)
while(sf->v)
{
if(sf->s==~0) //Link to another struct
{
uint32 tmp;
//not supported right now
//if(sf->size==~0) //Link to another struct
//{
// uint32 tmp;
if(!(tmp=SubWrite(os,(SFORMAT *)sf->v)))
return(0);
acc+=tmp;
sf++;
continue;
}
// if(!(tmp=SubWrite(os,(SFORMAT *)sf->v)))
// return(0);
// acc+=tmp;
// sf++;
// continue;
//}
int count = SS_UNMULT(sf->s);
int size = sf->s & ~SS_FLAGS;
bool rlsb = (count!=0);
int count = sf->count;
int size = sf->size;
acc+=8; //Description + size
if(count==0) count=1;
acc+=12; //Description + size + count
acc += count * size;
if(os) //Are we writing or calculating the size of this block?
{
os->write(sf->desc,4);
write32le(sf->s,os);
write32le(sf->size,os);
write32le(sf->count,os);
for(int i=0;i<count;i++) {
if(size == 1) {
//special case: write a huge byte array
os->write((char *)sf->v,count);
} else {
for(int i=0;i<count;i++) {
#ifndef LOCAL_LE
if(rlsb)
#ifndef LOCAL_LE
FlipByteOrder((u8*)sf->v,sf->s&(~SS_FLAGS));
#endif
#endif
if(sf->s&SS_INDIRECT)
os->write(*(char **)sf->v,size);
else
os->write((char*)sf->v + i*size,size);
//Now restore the original byte order.
#ifndef LOCAL_LE
if(rlsb)
FlipByteOrder((u8*)sf->v,sf->s&(~SS_FLAGS));
#endif
//Now restore the original byte order.
#ifndef LOCAL_LE
if(rlsb)
FlipByteOrder((u8*)sf->v,sf->s&(~SS_FLAGS));
#endif
}
}
}
sf++;
@ -508,10 +573,12 @@ static void writechunks(std::ostream* os) {
savestate_WriteChunk(os,2,SF_ARM7);
savestate_WriteChunk(os,3,SF_MEM);
savestate_WriteChunk(os,4,SF_NDS);
savestate_WriteChunk(os,5,gpu_savestate);
savestate_WriteChunk(os,50,SF_MMU);
savestate_WriteChunk(os,51,mmu_savestate);
savestate_WriteChunk(os,6,gpu_savestate);
savestate_WriteChunk(os,7,spu_savestate);
savestate_WriteChunk(os,60,SF_GFX3D);
savestate_WriteChunk(os,61,gfx3d_savestate);
savestate_WriteChunk(os,80,SF_GFX3D);
savestate_WriteChunk(os,81,gfx3d_savestate);
savestate_WriteChunk(os,0xFFFFFFFF,(SFORMAT*)0);
}
@ -531,10 +598,12 @@ static bool ReadStateChunks(std::istream* is, s32 totalsize)
case 2: if(!ReadStateChunk(is,SF_ARM7,size)) ret=false; break;
case 3: if(!ReadStateChunk(is,SF_MEM,size)) ret=false; break;
case 4: if(!ReadStateChunk(is,SF_NDS,size)) ret=false; break;
case 5: if(!gpu_loadstate(is)) ret=false; break;
case 50: if(!ReadStateChunk(is,SF_MMU,size)) ret=false; break;
case 51: if(!mmu_loadstate(is)) ret=false; break;
case 6: if(!gpu_loadstate(is)) ret=false; break;
case 7: if(!spu_loadstate(is)) ret=false; break;
case 60: if(!ReadStateChunk(is,SF_GFX3D,size)) ret=false; break;
case 61: if(!gfx3d_loadstate(is)) ret=false; break;
case 80: if(!ReadStateChunk(is,SF_GFX3D,size)) ret=false; break;
case 81: if(!gfx3d_loadstate(is)) ret=false; break;
default:
ret=false;
break;

View File

@ -36,32 +36,19 @@ typedef struct
struct SFORMAT
{
//a void* to the data or a void** to the data
void *v;
//size, plus flags
uint32 s;
//a string description of the element
char *desc;
//the size of each element
u32 size;
//the number of each element
u32 count;
//a void* to the data or a void** to the data
void *v;
};
//X multiple multibyte elements
#define SS_MULT(X) (X<<24)
//indicates that the value is a multibyte integer that needs to be put in the correct byte order
//this is the same as SS_MULT(1)
#define SS_RLSB SS_MULT(1)
//all flags together so that we can mask them out and get the size
#define SS_FLAGS (SS_INDIRECT|SS_MULT(127))
//extract the multiplier
#define SS_UNMULT(X) ((X>>24)&0x7F)
extern savestates_t savestates[NB_STATES];
void clear_savestates();