From b4a3551b1ca8021623cb9108c3fe81b76c06c537 Mon Sep 17 00:00:00 2001 From: zeromus Date: Mon, 29 Dec 2008 01:32:58 +0000 Subject: [PATCH] switch back to using templates for mmu 7/9 splitting. to make it worth the trouble, i also split the embedded bios functions in the same way --- desmume/src/MMU.cpp | 121 +- desmume/src/MMU.h | 43 +- desmume/src/NDSSystem.cpp | 112 +- desmume/src/arm_instructions.cpp | 2 +- desmume/src/armcpu.h | 2 +- desmume/src/bios.cpp | 323 +++--- desmume/src/bios.h | 4 +- desmume/src/saves.cpp | 1682 ++++++++++++++-------------- desmume/src/thumb_instructions.cpp | 12 +- 9 files changed, 1179 insertions(+), 1122 deletions(-) diff --git a/desmume/src/MMU.cpp b/desmume/src/MMU.cpp index 84d40b9cf..b36bcdc55 100644 --- a/desmume/src/MMU.cpp +++ b/desmume/src/MMU.cpp @@ -56,13 +56,56 @@ static u8 FASTCALL _MMU_ARM7_read08(u32 adr); static u16 FASTCALL _MMU_ARM7_read16(u32 adr); static u32 FASTCALL _MMU_ARM7_read32(u32 adr); -u8 (* FASTCALL _MMU_read08[2])(u32 addr) = {_MMU_ARM9_read08, _MMU_ARM7_read08}; -u16 (* FASTCALL _MMU_read16[2])(u32 addr) = {_MMU_ARM9_read16, _MMU_ARM7_read16}; -u32 (* FASTCALL _MMU_read32[2])(u32 addr) = {_MMU_ARM9_read32, _MMU_ARM7_read32}; -void (* FASTCALL _MMU_write08[2])(u32 addr, u8 val) = {_MMU_ARM9_write08, _MMU_ARM7_write08}; -void (* FASTCALL _MMU_write16[2])(u32 addr, u16 val) = {_MMU_ARM9_write16, _MMU_ARM7_write16}; -void (* FASTCALL _MMU_write32[2])(u32 addr, u32 val) = {_MMU_ARM9_write32, _MMU_ARM7_write32}; +u8 _MMU_read08(int PROCNUM, u32 addr) { + if(PROCNUM==ARMCPU_ARM9) return _MMU_ARM9_read08(addr); + else return _MMU_ARM7_read08(addr); +} + +u16 _MMU_read16(int PROCNUM, u32 addr) { + if(PROCNUM==ARMCPU_ARM9) return _MMU_ARM9_read16(addr); + else return _MMU_ARM7_read16(addr); +} + +u32 _MMU_read32(int PROCNUM, u32 addr) { + if(PROCNUM==ARMCPU_ARM9) return _MMU_ARM9_read32(addr); + else return _MMU_ARM7_read32(addr); +} + +void _MMU_write08(int PROCNUM, u32 addr, u8 val) { + if(PROCNUM==ARMCPU_ARM9) _MMU_ARM9_write08(addr,val); + else _MMU_ARM7_write08(addr,val); +} + +void _MMU_write16(int PROCNUM, u32 addr, u16 val) { + if(PROCNUM==ARMCPU_ARM9) _MMU_ARM9_write16(addr,val); + else _MMU_ARM7_write16(addr,val); +} + +void _MMU_write32(int PROCNUM, u32 addr, u32 val) { + if(PROCNUM==ARMCPU_ARM9) _MMU_ARM9_write32(addr,val); + else _MMU_ARM7_write32(addr,val); +} + + + +template +u8 _MMU_read08(u32 addr) { return _MMU_read08(PROCNUM, addr); } + +template +u16 _MMU_read16(u32 addr) { return _MMU_read16(PROCNUM, addr); } + +template +u32 _MMU_read32(u32 addr) { return _MMU_read32(PROCNUM, addr); } + +template +void _MMU_write08(u32 addr, u8 val) { _MMU_write08(PROCNUM, addr, val); } + +template +void _MMU_write16(u32 addr, u16 val) { _MMU_write16(PROCNUM, addr, val); } + +template +void _MMU_write32(u32 addr, u32 val) { _MMU_write32(PROCNUM, addr, val); } //http://home.utah.edu/~nahaj/factoring/isqrt.c.html static u64 isqrt (u64 x) { @@ -880,20 +923,26 @@ void FASTCALL MMU_doDMA(u32 proc, u32 num) default: return; } - if ((MMU.DMACrt[proc][num]>>26)&1) - for(; i < taille; ++i) - { - _MMU_write32[proc](dst, _MMU_read32[proc](src)); - dst += dstinc; - src += srcinc; - } - else - for(; i < taille; ++i) - { - _MMU_write16[proc](dst, _MMU_read16[proc](src)); - dst += dstinc; - src += srcinc; - } + + #define DMA_LOOP(PROC) \ + if ((MMU.DMACrt[proc][num]>>26)&1) \ + for(; i < taille; ++i) \ + { \ + _MMU_write32(dst, _MMU_read32(src)); \ + dst += dstinc; \ + src += srcinc; \ + } \ + else \ + for(; i < taille; ++i) \ + { \ + _MMU_write16(dst, _MMU_read16(src)); \ + dst += dstinc; \ + src += srcinc; \ + } \ + + if(proc == ARMCPU_ARM9) { DMA_LOOP(ARMCPU_ARM9); } + else { DMA_LOOP(ARMCPU_ARM7); } + //write back the addresses DMASrc[proc][num] = src; @@ -1119,7 +1168,7 @@ arm9_prefetch16( void *data, u32 adr) { } #endif - return _MMU_read16[ARMCPU_ARM9](adr); + return _MMU_read16(adr); } static u32 FASTCALL arm9_prefetch32( void *data, u32 adr) { @@ -1140,7 +1189,7 @@ arm9_prefetch32( void *data, u32 adr) { } #endif - return _MMU_read32[ARMCPU_ARM9](adr); + return _MMU_read32(adr); } static u8 FASTCALL @@ -1161,7 +1210,7 @@ arm9_read8( void *data, u32 adr) { } #endif - return _MMU_read08[ARMCPU_ARM9](adr); + return _MMU_read08(adr); } static u16 FASTCALL arm9_read16( void *data, u32 adr) { @@ -1183,7 +1232,7 @@ arm9_read16( void *data, u32 adr) { } #endif - return _MMU_read16[ARMCPU_ARM9](adr); + return _MMU_read16(adr); } static u32 FASTCALL arm9_read32( void *data, u32 adr) { @@ -1204,7 +1253,7 @@ arm9_read32( void *data, u32 adr) { } #endif - return _MMU_read32[ARMCPU_ARM9](adr); + return _MMU_read32(adr); } @@ -1229,7 +1278,7 @@ arm9_write8(void *data, u32 adr, u8 val) { } #endif - _MMU_write08[ARMCPU_ARM9](adr, val); + _MMU_write08(adr, val); } static void FASTCALL arm9_write16(void *data, u32 adr, u16 val) { @@ -1252,7 +1301,7 @@ arm9_write16(void *data, u32 adr, u16 val) { } #endif - _MMU_write16[ARMCPU_ARM9](adr, val); + _MMU_write16(adr, val); } static void FASTCALL arm9_write32(void *data, u32 adr, u32 val) { @@ -1275,7 +1324,7 @@ arm9_write32(void *data, u32 adr, u32 val) { } #endif - _MMU_write32[ARMCPU_ARM9](adr, val); + _MMU_write32(adr, val); } @@ -1295,7 +1344,7 @@ arm7_prefetch16( void *data, u32 adr) { } #endif - return _MMU_read16[ARMCPU_ARM7](adr); + return _MMU_read16(adr); } static u32 FASTCALL arm7_prefetch32( void *data, u32 adr) { @@ -1311,7 +1360,7 @@ arm7_prefetch32( void *data, u32 adr) { } #endif - return _MMU_read32[ARMCPU_ARM7](adr); + return _MMU_read32(adr); } static u8 FASTCALL @@ -1320,7 +1369,7 @@ arm7_read8( void *data, u32 adr) { profile_memory_access( 0, adr, PROFILE_READ); #endif - return _MMU_read08[ARMCPU_ARM7](adr); + return _MMU_read08(adr); } static u16 FASTCALL arm7_read16( void *data, u32 adr) { @@ -1328,7 +1377,7 @@ arm7_read16( void *data, u32 adr) { profile_memory_access( 0, adr, PROFILE_READ); #endif - return _MMU_read16[ARMCPU_ARM7](adr); + return _MMU_read16(adr); } static u32 FASTCALL arm7_read32( void *data, u32 adr) { @@ -1336,7 +1385,7 @@ arm7_read32( void *data, u32 adr) { profile_memory_access( 0, adr, PROFILE_READ); #endif - return _MMU_read32[ARMCPU_ARM7](adr); + return _MMU_read32(adr); } static void FASTCALL @@ -1345,7 +1394,7 @@ arm7_write8(void *data, u32 adr, u8 val) { profile_memory_access( 0, adr, PROFILE_WRITE); #endif - _MMU_write08[ARMCPU_ARM7](adr, val); + _MMU_write08(adr, val); } static void FASTCALL arm7_write16(void *data, u32 adr, u16 val) { @@ -1353,7 +1402,7 @@ arm7_write16(void *data, u32 adr, u16 val) { profile_memory_access( 0, adr, PROFILE_WRITE); #endif - _MMU_write16[ARMCPU_ARM7](adr, val); + _MMU_write16(adr, val); } static void FASTCALL arm7_write32(void *data, u32 adr, u32 val) { @@ -1361,7 +1410,7 @@ arm7_write32(void *data, u32 adr, u32 val) { profile_memory_access( 0, adr, PROFILE_WRITE); #endif - _MMU_write32[ARMCPU_ARM7](adr, val); + _MMU_write32(adr, val); } diff --git a/desmume/src/MMU.h b/desmume/src/MMU.h index d189d1994..31c124f78 100644 --- a/desmume/src/MMU.h +++ b/desmume/src/MMU.h @@ -177,14 +177,19 @@ extern struct armcpu_memory_iface arm9_direct_memory_iface; extern u8 *MMU_RenderMapToLCD(u32 vram_addr); -extern u8 (* FASTCALL _MMU_read08[2])(u32 addr); -extern u16 (* FASTCALL _MMU_read16[2])(u32 addr); -extern u32 (* FASTCALL _MMU_read32[2])(u32 addr); - -extern void (* FASTCALL _MMU_write08[2])(u32 addr, u8 val); -extern void (* FASTCALL _MMU_write16[2])(u32 addr, u16 val); -extern void (* FASTCALL _MMU_write32[2])(u32 addr, u32 val); +template u8 _MMU_read08(u32 addr); +template u16 _MMU_read16(u32 addr); +template u32 _MMU_read32(u32 addr); +template void _MMU_write08(u32 addr, u8 val); +template void _MMU_write16(u32 addr, u16 val); +template void _MMU_write32(u32 addr, u32 val); +u8 _MMU_read08(int PROCNUM, u32 addr); +u16 _MMU_read16(int PROCNUM, u32 addr); +u32 _MMU_read32(int PROCNUM, u32 addr); +void _MMU_write08(int PROCNUM, u32 addr, u8 val); +void _MMU_write16(int PROCNUM, u32 addr, u16 val); +void _MMU_write32(int PROCNUM, u32 addr, u32 val); #ifdef MMU_ENABLE_ACL void FASTCALL MMU_write8_acl(u32 proc, u32 adr, u8 val); @@ -194,12 +199,12 @@ extern void (* FASTCALL _MMU_write32[2])(u32 addr, u32 val); u16 FASTCALL MMU_read16_acl(u32 proc, u32 adr, u32 access); u32 FASTCALL MMU_read32_acl(u32 proc, u32 adr, u32 access); #else - #define MMU_write8_acl(proc, adr, val) _MMU_write08[proc](adr, val) - #define MMU_write16_acl(proc, adr, val) _MMU_write16[proc](adr, val) - #define MMU_write32_acl(proc, adr, val) _MMU_write32[proc][proc](adr, val) - #define MMU_read8_acl(proc,adr,access) _MMU_read08[proc](adr) - #define MMU_read16_acl(proc,adr,access) _MMU_read16[proc](adr) - #define MMU_read32_acl(proc,adr,access) _MMU_read32[proc](adr) + #define MMU_write8_acl(proc, adr, val) _MMU_write08(adr, val) + #define MMU_write16_acl(proc, adr, val) _MMU_write16(adr, val) + #define MMU_write32_acl(proc, adr, val) _MMU_write32(adr, val) + #define MMU_read8_acl(proc,adr,access) _MMU_read08(adr) + #define MMU_read16_acl(proc,adr,access) _MMU_read16(adr) + #define MMU_read32_acl(proc,adr,access) _MMU_read32(adr) #endif // Use this macros for reading/writing, so the GDB stub isn't broken @@ -211,12 +216,12 @@ extern void (* FASTCALL _MMU_write32[2])(u32 addr, u32 val); #define READ8(a,b) cpu->mem_if->read8(a,b) #define WRITE8(a,b,c) cpu->mem_if->write8(a,b,c) #else - #define READ32(a,b) _MMU_read32[PROCNUM]((b) & 0xFFFFFFFC) - #define WRITE32(a,b,c) _MMU_write32[PROCNUM]((b) & 0xFFFFFFFC,c) - #define READ16(a,b) _MMU_read16[PROCNUM]((b) & 0xFFFFFFFE) - #define WRITE16(a,b,c) _MMU_write16[PROCNUM]((b) & 0xFFFFFFFE,c) - #define READ8(a,b) _MMU_read08[PROCNUM](b) - #define WRITE8(a,b,c) _MMU_write08[PROCNUM](b, c) + #define READ32(a,b) _MMU_read32((b) & 0xFFFFFFFC) + #define WRITE32(a,b,c) _MMU_write32((b) & 0xFFFFFFFC,c) + #define READ16(a,b) _MMU_read16((b) & 0xFFFFFFFE) + #define WRITE16(a,b,c) _MMU_write16((b) & 0xFFFFFFFE,c) + #define READ8(a,b) _MMU_read08(b) + #define WRITE8(a,b,c) _MMU_write08(b, c) #endif #endif diff --git a/desmume/src/NDSSystem.cpp b/desmume/src/NDSSystem.cpp index c559c98b8..914462488 100644 --- a/desmume/src/NDSSystem.cpp +++ b/desmume/src/NDSSystem.cpp @@ -487,7 +487,7 @@ void NDS_Reset( void) for(i = 0; i < (header->ARM9binSize>>2); ++i) { - _MMU_write32[ARMCPU_ARM9](dst, T1ReadLong(MMU.CART_ROM, src)); + _MMU_write32(dst, T1ReadLong(MMU.CART_ROM, src)); dst += 4; src += 4; } @@ -497,7 +497,7 @@ void NDS_Reset( void) for(i = 0; i < (header->ARM7binSize>>2); ++i) { - _MMU_write32[ARMCPU_ARM7](dst, T1ReadLong(MMU.CART_ROM, src)); + _MMU_write32(dst, T1ReadLong(MMU.CART_ROM, src)); dst += 4; src += 4; } @@ -517,9 +517,9 @@ void NDS_Reset( void) nds.touchX = nds.touchY = 0; nds.isTouch = 0; - _MMU_write16[ARMCPU_ARM9](0x04000130, 0x3FF); - _MMU_write16[ARMCPU_ARM7](0x04000130, 0x3FF); - _MMU_write08[ARMCPU_ARM7](0x04000136, 0x43); + _MMU_write16(0x04000130, 0x3FF); + _MMU_write16(0x04000130, 0x3FF); + _MMU_write08(0x04000136, 0x43); LidClosed = FALSE; LidKeyCount = 0; @@ -534,70 +534,70 @@ void NDS_Reset( void) if ( copy_firmware_user_data( temp_buffer, MMU.fw.data)) { for ( fw_index = 0; fw_index < NDS_FW_USER_SETTINGS_MEM_BYTE_COUNT; fw_index++) - _MMU_write08[ARMCPU_ARM9](0x027FFC80 + fw_index, temp_buffer[fw_index]); + _MMU_write08(0x027FFC80 + fw_index, temp_buffer[fw_index]); } } // Copy the whole header to Main RAM 0x27FFE00 on startup. // Reference: http://nocash.emubase.de/gbatek.htm#dscartridgeheader for (i = 0; i < ((0x170+0x90)/4); i++) { - _MMU_write32[ARMCPU_ARM9](0x027FFE00+i*4, LE_TO_LOCAL_32(((u32*)MMU.CART_ROM)[i])); + _MMU_write32(0x027FFE00+i*4, LE_TO_LOCAL_32(((u32*)MMU.CART_ROM)[i])); } MainScreen.offset = 0; SubScreen.offset = 192; //_MMU_write32[ARMCPU_ARM9](0x02007FFC, 0xE92D4030); - FILE* inf = 0; - - //ARM7 BIOS IRQ HANDLER - inf = fopen("BiosNds7.ROM","rb"); - if(inf) { - fread(MMU.ARM7_BIOS,1,16384,inf); - fclose(inf); - NDS_ARM7.swi_tab = 0; - } else { - NDS_ARM7.swi_tab = ARM7_swi_tab; - _MMU_write32[ARMCPU_ARM7](0x00, 0xE25EF002); - _MMU_write32[ARMCPU_ARM7](0x04, 0xEAFFFFFE); - _MMU_write32[ARMCPU_ARM7](0x18, 0xEA000000); - _MMU_write32[ARMCPU_ARM7](0x20, 0xE92D500F); - _MMU_write32[ARMCPU_ARM7](0x24, 0xE3A00301); - _MMU_write32[ARMCPU_ARM7](0x28, 0xE28FE000); - _MMU_write32[ARMCPU_ARM7](0x2C, 0xE510F004); - _MMU_write32[ARMCPU_ARM7](0x30, 0xE8BD500F); - _MMU_write32[ARMCPU_ARM7](0x34, 0xE25EF004); - } + FILE* inf = 0; + + //ARM7 BIOS IRQ HANDLER + inf = fopen("BiosNds7.ROM","rb"); + if(inf) { + fread(MMU.ARM7_BIOS,1,16384,inf); + fclose(inf); + NDS_ARM7.swi_tab = 0; + } else { + NDS_ARM7.swi_tab = ARM7_swi_tab; + _MMU_write32(0x00, 0xE25EF002); + _MMU_write32(0x04, 0xEAFFFFFE); + _MMU_write32(0x18, 0xEA000000); + _MMU_write32(0x20, 0xE92D500F); + _MMU_write32(0x24, 0xE3A00301); + _MMU_write32(0x28, 0xE28FE000); + _MMU_write32(0x2C, 0xE510F004); + _MMU_write32(0x30, 0xE8BD500F); + _MMU_write32(0x34, 0xE25EF004); + } //ARM9 BIOS IRQ HANDLER - inf = fopen("BiosNds9.ROM","rb"); - if(inf) { - fread(ARM9Mem.ARM9_BIOS,1,4096,inf); - fclose(inf); - NDS_ARM9.swi_tab = 0; - } else { - NDS_ARM9.swi_tab = ARM9_swi_tab; - _MMU_write32[ARMCPU_ARM9](0xFFFF0018, 0xEA000000); - _MMU_write32[ARMCPU_ARM9](0xFFFF0020, 0xE92D500F); - _MMU_write32[ARMCPU_ARM9](0xFFFF0024, 0xEE190F11); - _MMU_write32[ARMCPU_ARM9](0xFFFF0028, 0xE1A00620); - _MMU_write32[ARMCPU_ARM9](0xFFFF002C, 0xE1A00600); - _MMU_write32[ARMCPU_ARM9](0xFFFF0030, 0xE2800C40); - _MMU_write32[ARMCPU_ARM9](0xFFFF0034, 0xE28FE000); - _MMU_write32[ARMCPU_ARM9](0xFFFF0038, 0xE510F004); - _MMU_write32[ARMCPU_ARM9](0xFFFF003C, 0xE8BD500F); - _MMU_write32[ARMCPU_ARM9](0xFFFF0040, 0xE25EF004); - } - - + inf = fopen("BiosNds9.ROM","rb"); + if(inf) { + fread(ARM9Mem.ARM9_BIOS,1,4096,inf); + fclose(inf); + NDS_ARM9.swi_tab = 0; + } else { + NDS_ARM9.swi_tab = ARM9_swi_tab; + _MMU_write32(0xFFFF0018, 0xEA000000); + _MMU_write32(0xFFFF0020, 0xE92D500F); + _MMU_write32(0xFFFF0024, 0xEE190F11); + _MMU_write32(0xFFFF0028, 0xE1A00620); + _MMU_write32(0xFFFF002C, 0xE1A00600); + _MMU_write32(0xFFFF0030, 0xE2800C40); + _MMU_write32(0xFFFF0034, 0xE28FE000); + _MMU_write32(0xFFFF0038, 0xE510F004); + _MMU_write32(0xFFFF003C, 0xE8BD500F); + _MMU_write32(0xFFFF0040, 0xE25EF004); + } - _MMU_write32[ARMCPU_ARM9](0x0000004, 0xE3A0010E); - _MMU_write32[ARMCPU_ARM9](0x0000008, 0xE3A01020); - // _MMU_write32[ARMCPU_ARM9](0x000000C, 0xE1B02110); - _MMU_write32[ARMCPU_ARM9](0x000000C, 0xE1B02040); - _MMU_write32[ARMCPU_ARM9](0x0000010, 0xE3B02020); - // _MMU_write32[ARMCPU_ARM9](0x0000010, 0xE2100202); + + + _MMU_write32(0x0000004, 0xE3A0010E); + _MMU_write32(0x0000008, 0xE3A01020); + // _MMU_write32(0x000000C, 0xE1B02110); + _MMU_write32(0x000000C, 0xE1B02040); + _MMU_write32(0x0000010, 0xE3B02020); + // _MMU_write32(0x0000010, 0xE2100202); delete header; @@ -1826,9 +1826,9 @@ void NDS_setPad(bool R,bool L,bool D,bool U,bool T,bool S,bool B,bool A,bool Y,b // TODO: low power IRQ } - -void emu_halt() { - execute = false; + +void emu_halt() { + execute = false; } //these templates needed to be instantiated manually diff --git a/desmume/src/arm_instructions.cpp b/desmume/src/arm_instructions.cpp index 36e704ad6..d4b103bfe 100644 --- a/desmume/src/arm_instructions.cpp +++ b/desmume/src/arm_instructions.cpp @@ -7773,7 +7773,7 @@ TEMPLATE static u32 FASTCALL OP_SWI() { if(cpu->swi_tab) { u32 swinum = (cpu->instruction>>16)&0x1F; - return cpu->swi_tab[swinum](cpu) + 3; + return cpu->swi_tab[swinum]() + 3; } else { /* TODO (#1#): translocated SWI vectors */ /* we use an irq thats not in the irq tab, as diff --git a/desmume/src/armcpu.h b/desmume/src/armcpu.h index 7311cc224..d81279023 100644 --- a/desmume/src/armcpu.h +++ b/desmume/src/armcpu.h @@ -182,7 +182,7 @@ typedef struct armcpu_t BOOL wIRQ; BOOL wirq; - u32 (* *swi_tab)(struct armcpu_t * cpu); + u32 (* *swi_tab)(); #ifdef GDB_STUB /** there is a pending irq for the cpu */ diff --git a/desmume/src/bios.cpp b/desmume/src/bios.cpp index 19e95af52..b7d04712e 100644 --- a/desmume/src/bios.cpp +++ b/desmume/src/bios.cpp @@ -25,6 +25,9 @@ #include "SPU.h" #include "debug.h" +#define cpu (&ARMPROC) +#define TEMPLATE template + extern BOOL execute; static const u16 getsinetbl[] = { @@ -186,7 +189,7 @@ static const u8 getvoltbl[] = { 0x7C, 0x7D, 0x7E, 0x7F }; -static u32 bios_nop(armcpu_t * cpu) +TEMPLATE static u32 bios_nop() { if (cpu->proc_ID == ARMCPU_ARM9) { @@ -199,14 +202,14 @@ static u32 bios_nop(armcpu_t * cpu) return 3; } -static u32 delayLoop(armcpu_t * cpu) +TEMPLATE static u32 delayLoop() { return cpu->R[0] * 4; } //u32 oldmode[2]; -static u32 intrWaitARM(armcpu_t * cpu) +TEMPLATE u32 intrWaitARM() { u32 intrFlagAdr;// = (((armcp15_t *)(cpu->coproc[15]))->DTCMRegion&0xFFFFF000)+0x3FF8; u32 intr; @@ -219,7 +222,7 @@ static u32 intrWaitARM(armcpu_t * cpu) } else { intrFlagAdr = (((armcp15_t *)(cpu->coproc[15]))->DTCMRegion&0xFFFFF000)+0x3FF8; } - intr = _MMU_read32[cpu->proc_ID]( intrFlagAdr); + intr = _MMU_read32(cpu->proc_ID,intrFlagAdr); intrFlag = cpu->R[1] & intr; if(intrFlag) @@ -227,7 +230,7 @@ static u32 intrWaitARM(armcpu_t * cpu) // si une(ou plusieurs) des interruptions que l'on attend s'est(se sont) produite(s) // on efface son(les) occurence(s). intr ^= intrFlag; - _MMU_write32[cpu->proc_ID]( intrFlagAdr, intr); + _MMU_write32(cpu->proc_ID, intrFlagAdr, intr); //cpu->switchMode(oldmode[cpu->proc_ID]); return 1; } @@ -240,7 +243,7 @@ static u32 intrWaitARM(armcpu_t * cpu) return 1; } -static u32 waitVBlankARM(armcpu_t * cpu) +TEMPLATE static u32 waitVBlankARM() { u32 intrFlagAdr;// = (((armcp15_t *)(cpu->coproc[15]))->DTCMRegion&0xFFFFF000)+0x3FF8; u32 intr; @@ -253,7 +256,7 @@ static u32 waitVBlankARM(armcpu_t * cpu) } else { intrFlagAdr = (((armcp15_t *)(cpu->coproc[15]))->DTCMRegion&0xFFFFF000)+0x3FF8; } - intr = _MMU_read32[cpu->proc_ID]( intrFlagAdr); + intr = _MMU_read32(cpu->proc_ID,intrFlagAdr); intrFlag = 1 & intr; if(intrFlag) @@ -261,7 +264,7 @@ static u32 waitVBlankARM(armcpu_t * cpu) // si une(ou plusieurs) des interruptions que l'on attend s'est(se sont) produite(s) // on efface son(les) occurence(s). intr ^= intrFlag; - _MMU_write32[cpu->proc_ID]( intrFlagAdr, intr); + _MMU_write32(cpu->proc_ID,intrFlagAdr, intr); //cpu->switchMode(oldmode[cpu->proc_ID]); return 1; } @@ -274,7 +277,7 @@ static u32 waitVBlankARM(armcpu_t * cpu) return 1; } -static u32 wait4IRQ(armcpu_t* cpu) +TEMPLATE static u32 wait4IRQ() { //execute= FALSE; if(cpu->wirq) @@ -298,7 +301,7 @@ static u32 wait4IRQ(armcpu_t* cpu) return 1; } -static u32 divide(armcpu_t* cpu) +TEMPLATE static u32 divide() { s32 num = (s32)cpu->R[0]; s32 dnum = (s32)cpu->R[1]; @@ -312,7 +315,7 @@ static u32 divide(armcpu_t* cpu) return 6; } -static u32 copy(armcpu_t* cpu) +TEMPLATE static u32 copy() { u32 src = cpu->R[0]; u32 dst = cpu->R[1]; @@ -329,7 +332,7 @@ static u32 copy(armcpu_t* cpu) cnt &= 0x1FFFFF; while(cnt) { - _MMU_write16[cpu->proc_ID]( dst, _MMU_read16[cpu->proc_ID]( src)); + _MMU_write16(cpu->proc_ID,dst, _MMU_read16(cpu->proc_ID,src)); cnt--; dst+=2; src+=2; @@ -337,11 +340,11 @@ static u32 copy(armcpu_t* cpu) break; case 1: { - u32 val = _MMU_read16[cpu->proc_ID]( src); + u32 val = _MMU_read16(cpu->proc_ID, src); cnt &= 0x1FFFFF; while(cnt) { - _MMU_write16[cpu->proc_ID]( dst, val); + _MMU_write16(cpu->proc_ID, dst, val); cnt--; dst+=2; } @@ -358,7 +361,7 @@ static u32 copy(armcpu_t* cpu) cnt &= 0x1FFFFF; while(cnt) { - _MMU_write32[cpu->proc_ID]( dst, _MMU_read32[cpu->proc_ID]( src)); + _MMU_write32(cpu->proc_ID, dst, _MMU_read32(cpu->proc_ID, src)); cnt--; dst+=4; src+=4; @@ -366,11 +369,11 @@ static u32 copy(armcpu_t* cpu) break; case 1: { - u32 val = _MMU_read32[cpu->proc_ID]( src); + u32 val = _MMU_read32(cpu->proc_ID, src); cnt &= 0x1FFFFF; while(cnt) { - _MMU_write32[cpu->proc_ID]( dst, val); + _MMU_write32(cpu->proc_ID,dst, val); cnt--; dst+=4; } @@ -382,7 +385,7 @@ static u32 copy(armcpu_t* cpu) return 1; } -static u32 fastCopy(armcpu_t* cpu) +TEMPLATE static u32 fastCopy() { u32 src = cpu->R[0] & 0xFFFFFFFC; u32 dst = cpu->R[1] & 0xFFFFFFFC; @@ -394,7 +397,7 @@ static u32 fastCopy(armcpu_t* cpu) cnt &= 0x1FFFFF; while(cnt) { - _MMU_write32[cpu->proc_ID]( dst, _MMU_read32[cpu->proc_ID]( src)); + _MMU_write32(cpu->proc_ID,dst, _MMU_read32(cpu->proc_ID,src)); cnt--; dst+=4; src+=4; @@ -402,11 +405,11 @@ static u32 fastCopy(armcpu_t* cpu) break; case 1: { - u32 val = _MMU_read32[cpu->proc_ID]( src); + u32 val = _MMU_read32(cpu->proc_ID,src); cnt &= 0x1FFFFF; while(cnt) { - _MMU_write32[cpu->proc_ID]( dst, val); + _MMU_write32(cpu->proc_ID,dst, val); cnt--; dst+=4; } @@ -416,7 +419,7 @@ static u32 fastCopy(armcpu_t* cpu) return 1; } -static u32 LZ77UnCompVram(armcpu_t* cpu) +TEMPLATE static u32 LZ77UnCompVram() { int i1, i2; int byteCount; @@ -425,7 +428,7 @@ static u32 LZ77UnCompVram(armcpu_t* cpu) int len; u32 source = cpu->R[0]; u32 dest = cpu->R[1]; - u32 header = _MMU_read32[cpu->proc_ID]( source); + u32 header = _MMU_read32(cpu->proc_ID,source); source += 4; if(((source & 0xe000000) == 0) || @@ -439,7 +442,7 @@ static u32 LZ77UnCompVram(armcpu_t* cpu) len = header >> 8; while(len > 0) { - u8 d = _MMU_read08[cpu->proc_ID]( source++); + u8 d = _MMU_read08(cpu->proc_ID,source++); if(d) { for(i1 = 0; i1 < 8; i1++) { @@ -447,18 +450,18 @@ static u32 LZ77UnCompVram(armcpu_t* cpu) int length; int offset; u32 windowOffset; - u16 data = _MMU_read08[cpu->proc_ID]( source++) << 8; - data |= _MMU_read08[cpu->proc_ID]( source++); + u16 data = _MMU_read08(cpu->proc_ID,source++) << 8; + data |= _MMU_read08(cpu->proc_ID,source++); length = (data >> 12) + 3; offset = (data & 0x0FFF); windowOffset = dest + byteCount - offset - 1; for(i2 = 0; i2 < length; i2++) { - writeValue |= (_MMU_read08[cpu->proc_ID]( windowOffset++) << byteShift); + writeValue |= (_MMU_read08(cpu->proc_ID,windowOffset++) << byteShift); byteShift += 8; byteCount++; if(byteCount == 2) { - _MMU_write16[cpu->proc_ID]( dest, writeValue); + _MMU_write16(cpu->proc_ID,dest, writeValue); dest += 2; byteCount = 0; byteShift = 0; @@ -469,11 +472,11 @@ static u32 LZ77UnCompVram(armcpu_t* cpu) return 0; } } else { - writeValue |= (_MMU_read08[cpu->proc_ID]( source++) << byteShift); + writeValue |= (_MMU_read08(cpu->proc_ID,source++) << byteShift); byteShift += 8; byteCount++; if(byteCount == 2) { - _MMU_write16[cpu->proc_ID]( dest, writeValue); + _MMU_write16(cpu->proc_ID,dest, writeValue); dest += 2; byteCount = 0; byteShift = 0; @@ -487,11 +490,11 @@ static u32 LZ77UnCompVram(armcpu_t* cpu) } } else { for(i1 = 0; i1 < 8; i1++) { - writeValue |= (_MMU_read08[cpu->proc_ID]( source++) << byteShift); + writeValue |= (_MMU_read08(cpu->proc_ID, source++) << byteShift); byteShift += 8; byteCount++; if(byteCount == 2) { - _MMU_write16[cpu->proc_ID]( dest, writeValue); + _MMU_write16(cpu->proc_ID, dest, writeValue); dest += 2; byteShift = 0; byteCount = 0; @@ -506,14 +509,14 @@ static u32 LZ77UnCompVram(armcpu_t* cpu) return 1; } -static u32 LZ77UnCompWram(armcpu_t* cpu) +TEMPLATE static u32 LZ77UnCompWram() { int i1, i2; int len; u32 source = cpu->R[0]; u32 dest = cpu->R[1]; - u32 header = _MMU_read32[cpu->proc_ID]( source); + u32 header = _MMU_read32(cpu->proc_ID, source); source += 4; if(((source & 0xe000000) == 0) || @@ -523,7 +526,7 @@ static u32 LZ77UnCompWram(armcpu_t* cpu) len = header >> 8; while(len > 0) { - u8 d = _MMU_read08[cpu->proc_ID]( source++); + u8 d = _MMU_read08(cpu->proc_ID, source++); if(d) { for(i1 = 0; i1 < 8; i1++) { @@ -531,19 +534,19 @@ static u32 LZ77UnCompWram(armcpu_t* cpu) int length; int offset; u32 windowOffset; - u16 data = _MMU_read08[cpu->proc_ID]( source++) << 8; - data |= _MMU_read08[cpu->proc_ID]( source++); + u16 data = _MMU_read08(cpu->proc_ID, source++) << 8; + data |= _MMU_read08(cpu->proc_ID, source++); length = (data >> 12) + 3; offset = (data & 0x0FFF); windowOffset = dest - offset - 1; for(i2 = 0; i2 < length; i2++) { - _MMU_write08[cpu->proc_ID]( dest++, _MMU_read08[cpu->proc_ID]( windowOffset++)); + _MMU_write08(cpu->proc_ID, dest++, _MMU_read08(cpu->proc_ID, windowOffset++)); len--; if(len == 0) return 0; } } else { - _MMU_write08[cpu->proc_ID]( dest++, _MMU_read08[cpu->proc_ID]( source++)); + _MMU_write08(cpu->proc_ID, dest++, _MMU_read08(cpu->proc_ID,source++)); len--; if(len == 0) return 0; @@ -552,7 +555,7 @@ static u32 LZ77UnCompWram(armcpu_t* cpu) } } else { for(i1 = 0; i1 < 8; i1++) { - _MMU_write08[cpu->proc_ID]( dest++, _MMU_read08[cpu->proc_ID]( source++)); + _MMU_write08(cpu->proc_ID,dest++, _MMU_read08(cpu->proc_ID, source++)); len--; if(len == 0) return 0; @@ -562,7 +565,7 @@ static u32 LZ77UnCompWram(armcpu_t* cpu) return 1; } -static u32 RLUnCompVram(armcpu_t* cpu) +TEMPLATE static u32 RLUnCompVram() { int i; int len; @@ -572,7 +575,7 @@ static u32 RLUnCompVram(armcpu_t* cpu) u32 source = cpu->R[0]; u32 dest = cpu->R[1]; - u32 header = _MMU_read32[cpu->proc_ID]( source); + u32 header = _MMU_read32(cpu->proc_ID, source); source += 4; if(((source & 0xe000000) == 0) || @@ -585,10 +588,10 @@ static u32 RLUnCompVram(armcpu_t* cpu) writeValue = 0; while(len > 0) { - u8 d = _MMU_read08[cpu->proc_ID]( source++); + u8 d = _MMU_read08(cpu->proc_ID, source++); int l = d & 0x7F; if(d & 0x80) { - u8 data = _MMU_read08[cpu->proc_ID]( source++); + u8 data = _MMU_read08(cpu->proc_ID, source++); l += 3; for(i = 0;i < l; i++) { writeValue |= (data << byteShift); @@ -596,7 +599,7 @@ static u32 RLUnCompVram(armcpu_t* cpu) byteCount++; if(byteCount == 2) { - _MMU_write16[cpu->proc_ID]( dest, writeValue); + _MMU_write16(cpu->proc_ID, dest, writeValue); dest += 2; byteCount = 0; byteShift = 0; @@ -609,11 +612,11 @@ static u32 RLUnCompVram(armcpu_t* cpu) } else { l++; for(i = 0; i < l; i++) { - writeValue |= (_MMU_read08[cpu->proc_ID]( source++) << byteShift); + writeValue |= (_MMU_read08(cpu->proc_ID, source++) << byteShift); byteShift += 8; byteCount++; if(byteCount == 2) { - _MMU_write16[cpu->proc_ID]( dest, writeValue); + _MMU_write16(cpu->proc_ID, dest, writeValue); dest += 2; byteCount = 0; byteShift = 0; @@ -628,14 +631,14 @@ static u32 RLUnCompVram(armcpu_t* cpu) return 1; } -static u32 RLUnCompWram(armcpu_t* cpu) +TEMPLATE static u32 RLUnCompWram() { int i; int len; u32 source = cpu->R[0]; u32 dest = cpu->R[1]; - u32 header = _MMU_read32[cpu->proc_ID]( source); + u32 header = _MMU_read32(cpu->proc_ID, source); source += 4; if(((source & 0xe000000) == 0) || @@ -645,13 +648,13 @@ static u32 RLUnCompWram(armcpu_t* cpu) len = header >> 8; while(len > 0) { - u8 d = _MMU_read08[cpu->proc_ID]( source++); + u8 d = _MMU_read08(cpu->proc_ID, source++); int l = d & 0x7F; if(d & 0x80) { - u8 data = _MMU_read08[cpu->proc_ID]( source++); + u8 data = _MMU_read08(cpu->proc_ID, source++); l += 3; for(i = 0;i < l; i++) { - _MMU_write08[cpu->proc_ID]( dest++, data); + _MMU_write08(cpu->proc_ID,dest++, data); len--; if(len == 0) return 0; @@ -659,7 +662,7 @@ static u32 RLUnCompWram(armcpu_t* cpu) } else { l++; for(i = 0; i < l; i++) { - _MMU_write08[cpu->proc_ID]( dest++, _MMU_read08[cpu->proc_ID]( source++)); + _MMU_write08(cpu->proc_ID, dest++, _MMU_read08(cpu->proc_ID,source++)); len--; if(len == 0) return 0; @@ -669,7 +672,7 @@ static u32 RLUnCompWram(armcpu_t* cpu) return 1; } -static u32 UnCompHuffman(armcpu_t* cpu) +TEMPLATE static u32 UnCompHuffman() { u32 source, dest, writeValue, header, treeStart, mask; u32 data; @@ -680,14 +683,14 @@ static u32 UnCompHuffman(armcpu_t* cpu) source = cpu->R[0]; dest = cpu->R[1]; - header = _MMU_read08[cpu->proc_ID]( source); + header = _MMU_read08(cpu->proc_ID, source); source += 4; if(((source & 0xe000000) == 0) || ((source + ((header >> 8) & 0x1fffff)) & 0xe000000) == 0) return 0; - treeSize = _MMU_read08[cpu->proc_ID]( source++); + treeSize = _MMU_read08(cpu->proc_ID,source++); treeStart = source; @@ -696,11 +699,11 @@ static u32 UnCompHuffman(armcpu_t* cpu) len = header >> 8; mask = 0x80000000; - data = _MMU_read08[cpu->proc_ID]( source); + data = _MMU_read08(cpu->proc_ID,source); source += 4; pos = 0; - rootNode = _MMU_read08[cpu->proc_ID]( treeStart); + rootNode = _MMU_read08(cpu->proc_ID,treeStart); currentNode = rootNode; writeData = 0; byteShift = 0; @@ -719,12 +722,12 @@ static u32 UnCompHuffman(armcpu_t* cpu) // right if(currentNode & 0x40) writeData = 1; - currentNode = _MMU_read08[cpu->proc_ID]( treeStart+pos+1); + currentNode = _MMU_read08(cpu->proc_ID,treeStart+pos+1); } else { // left if(currentNode & 0x80) writeData = 1; - currentNode = _MMU_read08[cpu->proc_ID]( treeStart+pos); + currentNode = _MMU_read08(cpu->proc_ID,treeStart+pos); } if(writeData) { @@ -739,7 +742,7 @@ static u32 UnCompHuffman(armcpu_t* cpu) if(byteCount == 4) { byteCount = 0; byteShift = 0; - _MMU_write08[cpu->proc_ID]( dest, writeValue); + _MMU_write08(cpu->proc_ID, dest, writeValue); writeValue = 0; dest += 4; len -= 4; @@ -748,7 +751,7 @@ static u32 UnCompHuffman(armcpu_t* cpu) mask >>= 1; if(mask == 0) { mask = 0x80000000; - data = _MMU_read08[cpu->proc_ID]( source); + data = _MMU_read08(cpu->proc_ID,source); source += 4; } } @@ -766,12 +769,12 @@ static u32 UnCompHuffman(armcpu_t* cpu) // right if(currentNode & 0x40) writeData = 1; - currentNode = _MMU_read08[cpu->proc_ID]( treeStart+pos+1); + currentNode = _MMU_read08(cpu->proc_ID, treeStart+pos+1); } else { // left if(currentNode & 0x80) writeData = 1; - currentNode = _MMU_read08[cpu->proc_ID]( treeStart+pos); + currentNode = _MMU_read08(cpu->proc_ID, treeStart+pos); } if(writeData) { @@ -792,7 +795,7 @@ static u32 UnCompHuffman(armcpu_t* cpu) if(byteCount == 4) { byteCount = 0; byteShift = 0; - _MMU_write08[cpu->proc_ID]( dest, writeValue); + _MMU_write08(cpu->proc_ID,dest, writeValue); dest += 4; writeValue = 0; len -= 4; @@ -805,7 +808,7 @@ static u32 UnCompHuffman(armcpu_t* cpu) mask >>= 1; if(mask == 0) { mask = 0x80000000; - data = _MMU_read08[cpu->proc_ID]( source); + data = _MMU_read08(cpu->proc_ID, source); source += 4; } } @@ -813,7 +816,7 @@ static u32 UnCompHuffman(armcpu_t* cpu) return 1; } -static u32 BitUnPack(armcpu_t* cpu) +TEMPLATE static u32 BitUnPack() { u32 source,dest,header,base,d,temp; int len,bits,revbits,dataSize,data,bitwritecount,mask,bitcount,addBase; @@ -823,15 +826,15 @@ static u32 BitUnPack(armcpu_t* cpu) dest = cpu->R[1]; header = cpu->R[2]; - len = _MMU_read16[cpu->proc_ID]( header); + len = _MMU_read16(cpu->proc_ID, header); // check address - bits = _MMU_read08[cpu->proc_ID]( header+2); + bits = _MMU_read08(cpu->proc_ID, header+2); revbits = 8 - bits; // u32 value = 0; - base = _MMU_read08[cpu->proc_ID]( header+4); + base = _MMU_read08(cpu->proc_ID, header+4); addBase = (base & 0x80000000) ? 1 : 0; base &= 0x7fffffff; - dataSize = _MMU_read08[cpu->proc_ID]( header+3); + dataSize = _MMU_read08(cpu->proc_ID, header+3); data = 0; bitwritecount = 0; @@ -840,7 +843,7 @@ static u32 BitUnPack(armcpu_t* cpu) if(len < 0) break; mask = 0xff >> revbits; - b = _MMU_read08[cpu->proc_ID]( source); + b = _MMU_read08(cpu->proc_ID, source); source++; bitcount = 0; while(1) { @@ -854,7 +857,7 @@ static u32 BitUnPack(armcpu_t* cpu) data |= temp << bitwritecount; bitwritecount += dataSize; if(bitwritecount >= 32) { - _MMU_write08[cpu->proc_ID]( dest, data); + _MMU_write08(cpu->proc_ID,dest, data); dest += 4; data = 0; bitwritecount = 0; @@ -866,7 +869,7 @@ static u32 BitUnPack(armcpu_t* cpu) return 1; } -static u32 Diff8bitUnFilterWram(armcpu_t* cpu) +TEMPLATE static u32 Diff8bitUnFilterWram() { u32 source,dest,header; u8 data,diff; @@ -875,7 +878,7 @@ static u32 Diff8bitUnFilterWram(armcpu_t* cpu) source = cpu->R[0]; dest = cpu->R[1]; - header = _MMU_read08[cpu->proc_ID]( source); + header = _MMU_read08(cpu->proc_ID, source); source += 4; if(((source & 0xe000000) == 0) || @@ -884,20 +887,20 @@ static u32 Diff8bitUnFilterWram(armcpu_t* cpu) len = header >> 8; - data = _MMU_read08[cpu->proc_ID]( source++); - _MMU_write08[cpu->proc_ID]( dest++, data); + data = _MMU_read08(cpu->proc_ID, source++); + _MMU_write08(cpu->proc_ID, dest++, data); len--; while(len > 0) { - diff = _MMU_read08[cpu->proc_ID]( source++); + diff = _MMU_read08(cpu->proc_ID,source++); data += diff; - _MMU_write08[cpu->proc_ID]( dest++, data); + _MMU_write08(cpu->proc_ID, dest++, data); len--; } return 1; } -static u32 Diff16bitUnFilter(armcpu_t* cpu) +TEMPLATE static u32 Diff16bitUnFilter() { u32 source,dest,header; u16 data; @@ -906,7 +909,7 @@ static u32 Diff16bitUnFilter(armcpu_t* cpu) source = cpu->R[0]; dest = cpu->R[1]; - header = _MMU_read08[cpu->proc_ID]( source); + header = _MMU_read08(cpu->proc_ID, source); source += 4; if(((source & 0xe000000) == 0) || @@ -915,54 +918,54 @@ static u32 Diff16bitUnFilter(armcpu_t* cpu) len = header >> 8; - data = _MMU_read16[cpu->proc_ID]( source); + data = _MMU_read16(cpu->proc_ID,source); source += 2; - _MMU_write16[cpu->proc_ID]( dest, data); + _MMU_write16(cpu->proc_ID, dest, data); dest += 2; len -= 2; while(len >= 2) { - u16 diff = _MMU_read16[cpu->proc_ID]( source); + u16 diff = _MMU_read16(cpu->proc_ID, source); source += 2; data += diff; - _MMU_write16[cpu->proc_ID]( dest, data); + _MMU_write16(cpu->proc_ID,dest, data); dest += 2; len -= 2; } return 1; } -static u32 bios_sqrt(armcpu_t* cpu) +TEMPLATE static u32 bios_sqrt() { cpu->R[0] = (u32)sqrt((double)(cpu->R[0])); return 1; } -static u32 setHaltCR(armcpu_t* cpu) +TEMPLATE static u32 setHaltCR() { - _MMU_write08[cpu->proc_ID]( 0x4000300+cpu->proc_ID, cpu->R[0]); + _MMU_write08(cpu->proc_ID,0x4000300+cpu->proc_ID, cpu->R[0]); return 1; } -static u32 getSineTab(armcpu_t* cpu) +TEMPLATE static u32 getSineTab() { cpu->R[0] = getsinetbl[cpu->R[0]]; return 1; } -static u32 getPitchTab(armcpu_t* cpu) +TEMPLATE static u32 getPitchTab() { cpu->R[0] = getpitchtbl[cpu->R[0]]; return 1; } -static u32 getVolumeTab(armcpu_t* cpu) +TEMPLATE static u32 getVolumeTab() { cpu->R[0] = getvoltbl[cpu->R[0]]; return 1; } -static u32 getCRC16(armcpu_t* cpu) +TEMPLATE static u32 getCRC16() { unsigned int i,j; @@ -973,7 +976,7 @@ static u32 getCRC16(armcpu_t* cpu) static u16 val[] = { 0xC0C1,0xC181,0xC301,0xC601,0xCC01,0xD801,0xF001,0xA001 }; for(i = 0; i < size; i++) { - crc = crc ^ _MMU_read08[cpu->proc_ID]( datap + i); + crc = crc ^ _MMU_read08(cpu->proc_ID, datap + i); for(j = 0; j < 8; j++) { int do_bit = 0; @@ -992,7 +995,7 @@ static u32 getCRC16(armcpu_t* cpu) return 1; } -static u32 SoundBias(armcpu_t* cpu) +TEMPLATE static u32 SoundBias() { u32 current = SPU_ReadLong(0x4000504); if (cpu->R[0] > current) @@ -1002,72 +1005,72 @@ static u32 SoundBias(armcpu_t* cpu) return cpu->R[1]; } -u32 (* ARM9_swi_tab[32])(armcpu_t* cpu)={ - bios_nop, // 0x00 - bios_nop, // 0x01 - bios_nop, // 0x02 - delayLoop, // 0x03 - intrWaitARM, // 0x04 - waitVBlankARM, // 0x05 - wait4IRQ, // 0x06 - bios_nop, // 0x07 - bios_nop, // 0x08 - divide, // 0x09 - bios_nop, // 0x0A - copy, // 0x0B - fastCopy, // 0x0C - bios_sqrt, // 0x0D - getCRC16, // 0x0E - bios_nop, // 0x0F - BitUnPack, // 0x10 - LZ77UnCompWram, // 0x11 - LZ77UnCompVram, // 0x12 - UnCompHuffman, // 0x13 - RLUnCompWram, // 0x14 - RLUnCompVram, // 0x15 - Diff8bitUnFilterWram, // 0x16 - bios_nop, // 0x17 - Diff16bitUnFilter, // 0x18 - bios_nop, // 0x19 - bios_nop, // 0x1A - bios_nop, // 0x1B - bios_nop, // 0x1C - bios_nop, // 0x1D - bios_nop, // 0x1E - setHaltCR, // 0x1F +u32 (* ARM9_swi_tab[32])()={ + bios_nop, // 0x00 + bios_nop, // 0x01 + bios_nop, // 0x02 + delayLoop, // 0x03 + intrWaitARM, // 0x04 + waitVBlankARM, // 0x05 + wait4IRQ, // 0x06 + bios_nop, // 0x07 + bios_nop, // 0x08 + divide, // 0x09 + bios_nop, // 0x0A + copy, // 0x0B + fastCopy, // 0x0C + bios_sqrt, // 0x0D + getCRC16, // 0x0E + bios_nop, // 0x0F + BitUnPack, // 0x10 + LZ77UnCompWram, // 0x11 + LZ77UnCompVram, // 0x12 + UnCompHuffman, // 0x13 + RLUnCompWram, // 0x14 + RLUnCompVram, // 0x15 + Diff8bitUnFilterWram, // 0x16 + bios_nop, // 0x17 + Diff16bitUnFilter, // 0x18 + bios_nop, // 0x19 + bios_nop, // 0x1A + bios_nop, // 0x1B + bios_nop, // 0x1C + bios_nop, // 0x1D + bios_nop, // 0x1E + setHaltCR, // 0x1F }; -u32 (* ARM7_swi_tab[32])(armcpu_t* cpu)={ - bios_nop, // 0x00 - bios_nop, // 0x01 - bios_nop, // 0x02 - delayLoop, // 0x03 - intrWaitARM, // 0x04 - waitVBlankARM, // 0x05 - wait4IRQ, // 0x06 - wait4IRQ, // 0x07 - SoundBias, // 0x08 - divide, // 0x09 - bios_nop, // 0x0A - copy, // 0x0B - fastCopy, // 0x0C - bios_sqrt, // 0x0D - getCRC16, // 0x0E - bios_nop, // 0x0F - BitUnPack, // 0x10 - LZ77UnCompWram, // 0x11 - LZ77UnCompVram, // 0x12 - UnCompHuffman, // 0x13 - RLUnCompWram, // 0x14 - RLUnCompVram, // 0x15 - Diff8bitUnFilterWram, // 0x16 - bios_nop, // 0x17 - bios_nop, // 0x18 - bios_nop, // 0x19 - getSineTab, // 0x1A - getPitchTab, // 0x1B - getVolumeTab, // 0x1C - bios_nop, // 0x1D - bios_nop, // 0x1E - setHaltCR, // 0x1F +u32 (* ARM7_swi_tab[32])()={ + bios_nop, // 0x00 + bios_nop, // 0x01 + bios_nop, // 0x02 + delayLoop, // 0x03 + intrWaitARM, // 0x04 + waitVBlankARM, // 0x05 + wait4IRQ, // 0x06 + wait4IRQ, // 0x07 + SoundBias, // 0x08 + divide, // 0x09 + bios_nop, // 0x0A + copy, // 0x0B + fastCopy, // 0x0C + bios_sqrt, // 0x0D + getCRC16, // 0x0E + bios_nop, // 0x0F + BitUnPack, // 0x10 + LZ77UnCompWram, // 0x11 + LZ77UnCompVram, // 0x12 + UnCompHuffman, // 0x13 + RLUnCompWram, // 0x14 + RLUnCompVram, // 0x15 + Diff8bitUnFilterWram, // 0x16 + bios_nop, // 0x17 + bios_nop, // 0x18 + bios_nop, // 0x19 + getSineTab, // 0x1A + getPitchTab, // 0x1B + getVolumeTab, // 0x1C + bios_nop, // 0x1D + bios_nop, // 0x1E + setHaltCR, // 0x1F }; diff --git a/desmume/src/bios.h b/desmume/src/bios.h index 85e9ca62b..f7107fa2c 100644 --- a/desmume/src/bios.h +++ b/desmume/src/bios.h @@ -24,8 +24,8 @@ #include "armcpu.h" -extern u32 (* ARM9_swi_tab[32])(armcpu_t * cpu); -extern u32 (* ARM7_swi_tab[32])(armcpu_t * cpu); +extern u32 (* ARM9_swi_tab[32])(); +extern u32 (* ARM7_swi_tab[32])(); #endif diff --git a/desmume/src/saves.cpp b/desmume/src/saves.cpp index d05bb9183..7bf978a4c 100644 --- a/desmume/src/saves.cpp +++ b/desmume/src/saves.cpp @@ -1,842 +1,842 @@ -/* Copyright (C) 2006 Normmatt - Copyright (C) 2006 Theo Berkau - Copyright (C) 2007 Pascal Giard - - This file is part of DeSmuME - - DeSmuME 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; either version 2 of the License, or - (at your option) any later version. - - DeSmuME 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 for more details. - - You should have received a copy of the GNU General Public License - along with DeSmuME; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#ifdef HAVE_LIBZ -#include -#endif -#include -#include -#include -#include -#include -#include "saves.h" -#include "MMU.h" -#include "NDSSystem.h" -#include "render3D.h" -#include "cp15.h" - -#include "memorystream.h" -#include "readwrite.h" -#include "gfx3d.h" - - -//void*v is actually a void** which will be indirected before reading -//since this isnt supported right now, it is declared in here to make things compile -#define SS_INDIRECT 0x80000000 - -savestates_t savestates[NB_STATES]; - -#define SAVESTATE_VERSION 11 -static const char* magic = "DeSmuME SState\0"; - -#ifndef MAX_PATH -#define MAX_PATH 256 -#endif - - -SFORMAT SF_ARM7[]={ - { "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[]={ - { "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[]={ - { "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 - { "9REG", 1, 0x2000, ARM9Mem.ARM9_REG}, - - { "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[]={ - { "_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}, - { "_TPB", 4, 1, &nds.isTouch}, - { 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, 4, MMU.VRAM_MAP}, - { "MVRM", 4, 9, MMU.LCD_VRAM_ADDR}, - { "MVRM", 1, 9, MMU.LCDCenable}, - { "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}, - - { "MDV1", 4, 1, &MMU.divRunning}, - { "MDV2", 8, 1, &MMU.divResult}, - { "MDV3", 8, 1, &MMU.divMod}, - { "MDV4", 4, 1, &MMU.divCnt}, - { "MDV5", 4, 1, &MMU.divCycles}, - - { "MSQ1", 4, 1, &MMU.sqrtRunning}, - { "MSQ2", 4, 1, &MMU.sqrtResult}, - { "MSQ3", 4, 1, &MMU.sqrtCnt}, - { "MSQ4", 4, 1, &MMU.sqrtCycles}, +/* Copyright (C) 2006 Normmatt + Copyright (C) 2006 Theo Berkau + Copyright (C) 2007 Pascal Giard + + This file is part of DeSmuME + + DeSmuME 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; either version 2 of the License, or + (at your option) any later version. + + DeSmuME 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 for more details. + + You should have received a copy of the GNU General Public License + along with DeSmuME; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifdef HAVE_LIBZ +#include +#endif +#include +#include +#include +#include +#include +#include "saves.h" +#include "MMU.h" +#include "NDSSystem.h" +#include "render3D.h" +#include "cp15.h" + +#include "memorystream.h" +#include "readwrite.h" +#include "gfx3d.h" + + +//void*v is actually a void** which will be indirected before reading +//since this isnt supported right now, it is declared in here to make things compile +#define SS_INDIRECT 0x80000000 + +savestates_t savestates[NB_STATES]; + +#define SAVESTATE_VERSION 11 +static const char* magic = "DeSmuME SState\0"; + +#ifndef MAX_PATH +#define MAX_PATH 256 +#endif + + +SFORMAT SF_ARM7[]={ + { "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[]={ + { "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[]={ + { "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 + { "9REG", 1, 0x2000, ARM9Mem.ARM9_REG}, + + { "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[]={ + { "_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}, + { "_TPB", 4, 1, &nds.isTouch}, + { 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, 4, MMU.VRAM_MAP}, + { "MVRM", 4, 9, MMU.LCD_VRAM_ADDR}, + { "MVRM", 1, 9, MMU.LCDCenable}, + { "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}, + + { "MDV1", 4, 1, &MMU.divRunning}, + { "MDV2", 8, 1, &MMU.divResult}, + { "MDV3", 8, 1, &MMU.divMod}, + { "MDV4", 4, 1, &MMU.divCnt}, + { "MDV5", 4, 1, &MMU.divCycles}, + + { "MSQ1", 4, 1, &MMU.sqrtRunning}, + { "MSQ2", 4, 1, &MMU.sqrtResult}, + { "MSQ3", 4, 1, &MMU.sqrtCnt}, + { "MSQ4", 4, 1, &MMU.sqrtCycles}, - //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}, - - //fifos - { "F0ST", 1, 1, ipc_fifo.sendTail}, - { "F0RT", 1, 1, ipc_fifo.recvTail}, - { "FSB0", 4, 16, &ipc_fifo.sendBuf[0]}, - { "FRB0", 4, 16, &ipc_fifo.recvBuf[0]}, - { "FSB1", 4, 16, &ipc_fifo.sendBuf[1]}, - { "FRB1", 4, 16, &ipc_fifo.recvBuf[1]}, - { 0 } -}; - - -static void mmu_savestate(std::ostream* os) -{ - //version - write32le(0,os); - - write32le(MMU.bupmem.size,os); - os->write((char*)MMU.bupmem.data,MMU.bupmem.size); -} - -static 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; -} - -static void cp15_saveone(armcp15_t *cp15, std::ostream* os) -{ - write32le(cp15->IDCode,os); - write32le(cp15->cacheType,os); - write32le(cp15->TCMSize,os); - write32le(cp15->ctrl,os); - write32le(cp15->DCConfig,os); - write32le(cp15->ICConfig,os); - write32le(cp15->writeBuffCtrl,os); - write32le(cp15->und,os); - write32le(cp15->DaccessPerm,os); - write32le(cp15->IaccessPerm,os); - write32le(cp15->protectBaseSize0,os); - write32le(cp15->protectBaseSize1,os); - write32le(cp15->protectBaseSize2,os); - write32le(cp15->protectBaseSize3,os); - write32le(cp15->protectBaseSize4,os); - write32le(cp15->protectBaseSize5,os); - write32le(cp15->protectBaseSize6,os); - write32le(cp15->protectBaseSize7,os); - write32le(cp15->cacheOp,os); - write32le(cp15->DcacheLock,os); - write32le(cp15->IcacheLock,os); - write32le(cp15->ITCMRegion,os); - write32le(cp15->DTCMRegion,os); - write32le(cp15->processID,os); - write32le(cp15->RAM_TAG,os); - write32le(cp15->testState,os); - write32le(cp15->cacheDbg,os); - for(int i=0;i<8;i++) write32le(cp15->regionWriteMask_USR[i],os); - for(int i=0;i<8;i++) write32le(cp15->regionWriteMask_SYS[i],os); - for(int i=0;i<8;i++) write32le(cp15->regionReadMask_USR[i],os); - for(int i=0;i<8;i++) write32le(cp15->regionReadMask_SYS[i],os); - for(int i=0;i<8;i++) write32le(cp15->regionExecuteMask_USR[i],os); - for(int i=0;i<8;i++) write32le(cp15->regionExecuteMask_SYS[i],os); - for(int i=0;i<8;i++) write32le(cp15->regionWriteSet_USR[i],os); - for(int i=0;i<8;i++) write32le(cp15->regionWriteSet_SYS[i],os); - for(int i=0;i<8;i++) write32le(cp15->regionReadSet_USR[i],os); - for(int i=0;i<8;i++) write32le(cp15->regionReadSet_SYS[i],os); - for(int i=0;i<8;i++) write32le(cp15->regionExecuteSet_USR[i],os); - for(int i=0;i<8;i++) write32le(cp15->regionExecuteSet_SYS[i],os); -} - -static void cp15_savestate(std::ostream* os) -{ - //version - write32le(0,os); - - cp15_saveone((armcp15_t *)NDS_ARM9.coproc[15],os); - cp15_saveone((armcp15_t *)NDS_ARM7.coproc[15],os); -} - -static bool cp15_loadone(armcp15_t *cp15, std::istream* is) -{ - if(!read32le(&cp15->IDCode,is)) return false; - if(!read32le(&cp15->cacheType,is)) return false; - if(!read32le(&cp15->TCMSize,is)) return false; - if(!read32le(&cp15->ctrl,is)) return false; - if(!read32le(&cp15->DCConfig,is)) return false; - if(!read32le(&cp15->ICConfig,is)) return false; - if(!read32le(&cp15->writeBuffCtrl,is)) return false; - if(!read32le(&cp15->und,is)) return false; - if(!read32le(&cp15->DaccessPerm,is)) return false; - if(!read32le(&cp15->IaccessPerm,is)) return false; - if(!read32le(&cp15->protectBaseSize0,is)) return false; - if(!read32le(&cp15->protectBaseSize1,is)) return false; - if(!read32le(&cp15->protectBaseSize2,is)) return false; - if(!read32le(&cp15->protectBaseSize3,is)) return false; - if(!read32le(&cp15->protectBaseSize4,is)) return false; - if(!read32le(&cp15->protectBaseSize5,is)) return false; - if(!read32le(&cp15->protectBaseSize6,is)) return false; - if(!read32le(&cp15->protectBaseSize7,is)) return false; - if(!read32le(&cp15->cacheOp,is)) return false; - if(!read32le(&cp15->DcacheLock,is)) return false; - if(!read32le(&cp15->IcacheLock,is)) return false; - if(!read32le(&cp15->ITCMRegion,is)) return false; - if(!read32le(&cp15->DTCMRegion,is)) return false; - if(!read32le(&cp15->processID,is)) return false; - if(!read32le(&cp15->RAM_TAG,is)) return false; - if(!read32le(&cp15->testState,is)) return false; - if(!read32le(&cp15->cacheDbg,is)) return false; - for(int i=0;i<8;i++) if(!read32le(&cp15->regionWriteMask_USR[i],is)) return false; - for(int i=0;i<8;i++) if(!read32le(&cp15->regionWriteMask_SYS[i],is)) return false; - for(int i=0;i<8;i++) if(!read32le(&cp15->regionReadMask_USR[i],is)) return false; - for(int i=0;i<8;i++) if(!read32le(&cp15->regionReadMask_SYS[i],is)) return false; - for(int i=0;i<8;i++) if(!read32le(&cp15->regionExecuteMask_USR[i],is)) return false; - for(int i=0;i<8;i++) if(!read32le(&cp15->regionExecuteMask_SYS[i],is)) return false; - for(int i=0;i<8;i++) if(!read32le(&cp15->regionWriteSet_USR[i],is)) return false; - for(int i=0;i<8;i++) if(!read32le(&cp15->regionWriteSet_SYS[i],is)) return false; - for(int i=0;i<8;i++) if(!read32le(&cp15->regionReadSet_USR[i],is)) return false; - for(int i=0;i<8;i++) if(!read32le(&cp15->regionReadSet_SYS[i],is)) return false; - for(int i=0;i<8;i++) if(!read32le(&cp15->regionExecuteSet_USR[i],is)) return false; - for(int i=0;i<8;i++) if(!read32le(&cp15->regionExecuteSet_SYS[i],is)) return false; - - return true; -} - -static bool cp15_loadstate(std::istream* is) -{ - //read version - int version; - if(read32le(&version,is) != 1) return false; - if(version != 0) return false; - - if(!cp15_loadone((armcp15_t *)NDS_ARM9.coproc[15],is)) return false; - if(!cp15_loadone((armcp15_t *)NDS_ARM7.coproc[15],is)) return false; - - return true; -} - - - -/* Format time and convert to string */ -static char * format_time(time_t cal_time) -{ - struct tm *time_struct; - static char string[30]; - - time_struct=localtime(&cal_time); - strftime(string, sizeof string, "%Y-%m-%d %H:%M", time_struct); - - return(string); -} - -void clear_savestates() -{ - u8 i; - for( i = 0; i < NB_STATES; i++ ) - savestates[i].exists = FALSE; -} - -/* Scan for existing savestates and update struct */ -void scan_savestates() -{ - struct stat sbuf; - char filename[MAX_PATH]; - u8 i; - - clear_savestates(); - - for( i = 1; i <= NB_STATES; i++ ) - { - strncpy(filename, szRomBaseName,MAX_PATH); - if (strlen(filename) + strlen(".dst") + strlen("-2147483648") /* = biggest string for i */ >MAX_PATH) return ; - sprintf(filename+strlen(filename), "%d.dst", i); - if( stat(filename,&sbuf) == -1 ) continue; - savestates[i-1].exists = TRUE; - strncpy(savestates[i-1].date, format_time(sbuf.st_mtime),40-strlen(savestates[i-1].date)); - } - - return ; -} - -void savestate_slot(int num) -{ - struct stat sbuf; - char filename[MAX_PATH]; - - strncpy(filename, szRomBaseName,MAX_PATH); - if (strlen(filename) + strlen(".dst") + strlen("-2147483648") /* = biggest string for num */ >MAX_PATH) return ; - sprintf(filename+strlen(filename), "%d.dst", num); - savestate_save(filename); - - savestates[num-1].exists = TRUE; - if( stat(filename,&sbuf) == -1 ) return; - strncpy(savestates[num-1].date, format_time(sbuf.st_mtime),40-strlen(savestates[num-1].date)); -} - -void loadstate_slot(int num) -{ - char filename[MAX_PATH]; - strncpy(filename, szRomBaseName,MAX_PATH); - if (strlen(filename) + strlen(".dst") + strlen("-2147483648") /* = biggest string for num */ >MAX_PATH) return ; - sprintf(filename+strlen(filename), "%d.dst", num); - savestate_load(filename); -} - -u8 sram_read (u32 address) { - address = address - SRAM_ADDRESS; - - if ( address > SRAM_SIZE ) - return 0; - - return MMU.CART_RAM[address]; - -} - -void sram_write (u32 address, u8 value) { - - address = address - SRAM_ADDRESS; - - if ( address < SRAM_SIZE ) - MMU.CART_RAM[address] = value; - -} - -int sram_load (const char *file_name) { - - FILE *file; - size_t elems_read; - - file = fopen ( file_name, "rb" ); - if( file == NULL ) - return 0; - - elems_read = fread ( MMU.CART_RAM, SRAM_SIZE, 1, file ); - - fclose ( file ); - - return 1; - -} - -int sram_save (const char *file_name) { - - FILE *file; - size_t elems_written; - - file = fopen ( file_name, "wb" ); - if( file == NULL ) - return 0; - - elems_written = fwrite ( MMU.CART_RAM, SRAM_SIZE, 1, file ); - - fclose ( file ); - - return 1; - -} - -static SFORMAT *CheckS(SFORMAT *sf, u32 size, u32 count, char *desc) -{ - while(sf->v) - { - //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(sf->size != size || sf->count != count) - return 0; - return sf; - } - sf++; - } - return 0; -} - - -static bool ReadStateChunk(std::istream* is, SFORMAT *sf, int size) -{ - SFORMAT *tmp; - int temp = is->tellg(); - - while(is->tellg()read(toa,4); - if(is->fail()) - return false; - - if(!read32le(&sz,is)) return false; - if(!read32le(&count,is)) return false; - - if((tmp=CheckS(sf,sz,count,toa))) - { - if(sz == 1) { - //special case: read a huge byte array - is->read((char *)tmp->v,count); - } else { - for(unsigned int i=0;iread((char *)tmp->v + i*sz,sz); - - #ifndef LOCAL_LE - FlipByteOrder((u8*)tmp->v + i*sz,sz); - #endif - } - } - } - else - is->seekg(sz*count,std::ios::cur); - } // while(...) - return true; -} - - - -static int SubWrite(std::ostream* os, SFORMAT *sf) -{ - uint32 acc=0; - - while(sf->v) - { - //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; - //} - - int count = sf->count; - int size = sf->size; - - //add size of current node to the accumulator - acc += sizeof(sf->desc) + sizeof(sf->size) + sizeof(sf->count); - acc += count * size; - - if(os) //Are we writing or calculating the size of this block? - { - os->write(sf->desc,4); - write32le(sf->size,os); - write32le(sf->count,os); - - if(size == 1) { - //special case: write a huge byte array - os->write((char *)sf->v,count); - } else { - for(int i=0;iv + i*size, size); - #endif - - os->write((char*)sf->v + i*size,size); - - //Now restore the original byte order. - #ifndef LOCAL_LE - FlipByteOrder((u8*)sf->v + i*size, size); - #endif - } - } - } - sf++; - } - - return(acc); -} - -static int savestate_WriteChunk(std::ostream* os, int type, SFORMAT *sf) -{ - write32le(type,os); - if(!sf) return 4; - int bsize = SubWrite((std::ostream*)0,sf); - write32le(bsize,os); - - if(!SubWrite(os,sf)) - { - return 8; - } - return (bsize+8); -} - -static void savestate_WriteChunk(std::ostream* os, int type, void (*saveproc)(std::ostream* os)) -{ - //get the size - memorystream mstemp; - saveproc(&mstemp); - mstemp.flush(); - u32 size = mstemp.size(); - - //write the type, size, and data - write32le(type,os); - write32le(size,os); - os->write(mstemp.buf(),size); -} - -static void writechunks(std::ostream* os); - -static bool savestate_save(std::ostream* outstream, int compressionLevel) -{ - //generate the savestate in memory first - memorystream ms; - std::ostream* os = (std::ostream*)&ms; - writechunks(os); - ms.flush(); - - //save the length of the file - u32 len = ms.size(); - - u32 comprlen = 0xFFFFFFFF; - u8* cbuf = (u8*)ms.buf(); - -#ifdef HAVE_LIBZ - //compress the data - int error = Z_OK; - if(compressionLevel != Z_NO_COMPRESSION) - { - uLongf comprlen2; - //worst case compression. - //zlib says "0.1% larger than sourceLen plus 12 bytes" - comprlen = (len>>9)+12 + len; - cbuf = new u8[comprlen]; - /* Workaround to make it compile under linux 64bit */ - comprlen2 = comprlen; - error = compress2(cbuf,&comprlen2,(u8*)ms.buf(),len,compressionLevel); - comprlen = (u32)comprlen2; - } -#endif - - //dump the header - outstream->write(magic,16); - write32le(SAVESTATE_VERSION,outstream); - write32le(DESMUME_VERSION_NUMERIC,outstream); //desmume version - write32le(len,outstream); //uncompressed length - write32le(comprlen,outstream); //compressed length (-1 if it is not compressed) - - outstream->write((char*)cbuf,comprlen==(u32)-1?len:comprlen); - if(cbuf != (uint8*)ms.buf()) delete[] cbuf; -#ifdef HAVE_LIBZ - return error == Z_OK; -#else - return true; -#endif -} - -bool savestate_save (const char *file_name) -{ - memorystream ms; - size_t elems_written; -#ifdef HAVE_LIBZ - if(!savestate_save(&ms, Z_DEFAULT_COMPRESSION)) -#else - if(!savestate_save(&ms, 0)) -#endif - return false; - ms.flush(); - FILE* file = fopen(file_name,"wb"); - if(file) - { - elems_written = fwrite(ms.buf(),1,ms.size(),file); - fclose(file); - return (elems_written == ms.size()); - } else return false; -} - -//u8 GPU_screen[4*256*192]; - -static void writechunks(std::ostream* os) { - savestate_WriteChunk(os,1,SF_ARM9); - savestate_WriteChunk(os,2,SF_ARM7); - savestate_WriteChunk(os,3,cp15_savestate); - savestate_WriteChunk(os,4,SF_MEM); - savestate_WriteChunk(os,5,SF_NDS); - savestate_WriteChunk(os,60,SF_MMU); - savestate_WriteChunk(os,61,mmu_savestate); - savestate_WriteChunk(os,7,gpu_savestate); - savestate_WriteChunk(os,8,spu_savestate); - savestate_WriteChunk(os,90,SF_GFX3D); - savestate_WriteChunk(os,91,gfx3d_savestate); - savestate_WriteChunk(os,0xFFFFFFFF,(SFORMAT*)0); -} - -static bool ReadStateChunks(std::istream* is, s32 totalsize) -{ - bool ret = true; - while(totalsize > 0) - { - uint32 size; - u32 t; - if(!read32le(&t,is)) { ret=false; break; } - if(t == 0xFFFFFFFF) goto done; - if(!read32le(&size,is)) { ret=false; break; } - switch(t) - { - case 1: if(!ReadStateChunk(is,SF_ARM9,size)) ret=false; break; - case 2: if(!ReadStateChunk(is,SF_ARM7,size)) ret=false; break; - case 3: if(!cp15_loadstate(is)) ret=false; break; - case 4: if(!ReadStateChunk(is,SF_MEM,size)) ret=false; break; - case 5: if(!ReadStateChunk(is,SF_NDS,size)) ret=false; break; - case 60: if(!ReadStateChunk(is,SF_MMU,size)) ret=false; break; - case 61: if(!mmu_loadstate(is)) ret=false; break; - case 7: if(!gpu_loadstate(is)) ret=false; break; - case 8: if(!spu_loadstate(is)) ret=false; break; - case 90: if(!ReadStateChunk(is,SF_GFX3D,size)) ret=false; break; - case 91: if(!gfx3d_loadstate(is)) ret=false; break; - default: - ret=false; - break; - } - if(!ret) return false; - } -done: - - return ret; -} - -static void loadstate() -{ - // This should regenerate the vram banks - for (int i = 0; i < 0xA; i++) - _MMU_write08[ARMCPU_ARM9](0x04000240+i, _MMU_read08[ARMCPU_ARM9](0x04000240+i)); - - // This should regenerate the graphics power control register - _MMU_write16[ARMCPU_ARM9](0x04000304, _MMU_read16[ARMCPU_ARM9](0x04000304)); - - // This should regenerate the graphics configuration - for (int i = REG_BASE_DISPA; i<=REG_BASE_DISPA + 0x7F; i+=2) - _MMU_write16[ARMCPU_ARM9](i, _MMU_read16[ARMCPU_ARM9](i)); - for (int i = REG_BASE_DISPB; i<=REG_BASE_DISPB + 0x7F; i+=2) - _MMU_write16[ARMCPU_ARM9](i, _MMU_read16[ARMCPU_ARM9](i)); -} - -static bool savestate_load(std::istream* is) -{ - char header[16]; - is->read(header,16); - if(is->fail() || memcmp(header,magic,16)) - return false; - - u32 ssversion,dversion,len,comprlen; - if(!read32le(&ssversion,is)) return false; - if(!read32le(&dversion,is)) return false; - if(!read32le(&len,is)) return false; - if(!read32le(&comprlen,is)) return false; - - if(ssversion != SAVESTATE_VERSION) return false; - - std::vector buf(len); - - if(comprlen != 0xFFFFFFFF) { -#ifndef HAVE_LIBZ - //without libz, we can't decompress this savestate - return false; -#endif - std::vector cbuf(comprlen); - is->read(&cbuf[0],comprlen); - if(is->fail()) return false; - -#ifdef HAVE_LIBZ - uLongf uncomprlen = len; - int error = uncompress((uint8*)&buf[0],&uncomprlen,(uint8*)&cbuf[0],comprlen); - if(error != Z_OK || uncomprlen != len) - return false; -#endif - } else { - is->read((char*)&buf[0],len); - } - - //GO!! READ THE SAVESTATE - //THERE IS NO GOING BACK NOW - //reset the emulator first to clean out the host's state - - //while the series of resets below should work, - //we are testing the robustness of the savestate system with this full reset. - //the full reset wipes more things, so we can make sure that they are being restored correctly - NDS_Reset(); - - //GPU_Reset(MainScreen.gpu, 0); - //GPU_Reset(SubScreen.gpu, 1); - //gfx3d_reset(); - //gpu3D->NDS_3D_Reset(); - //SPU_Reset(); - - - memorystream mstemp(&buf); - bool x = ReadStateChunks(&mstemp,(s32)len); - - loadstate(); - - return x; -} - -bool savestate_load(const char *file_name) -{ - std::ifstream f; - f.open(file_name,std::ios_base::binary|std::ios_base::in); - if(!f) return false; - - return savestate_load(&f); -} + //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}, + + //fifos + { "F0ST", 1, 1, ipc_fifo.sendTail}, + { "F0RT", 1, 1, ipc_fifo.recvTail}, + { "FSB0", 4, 16, &ipc_fifo.sendBuf[0]}, + { "FRB0", 4, 16, &ipc_fifo.recvBuf[0]}, + { "FSB1", 4, 16, &ipc_fifo.sendBuf[1]}, + { "FRB1", 4, 16, &ipc_fifo.recvBuf[1]}, + { 0 } +}; + + +static void mmu_savestate(std::ostream* os) +{ + //version + write32le(0,os); + + write32le(MMU.bupmem.size,os); + os->write((char*)MMU.bupmem.data,MMU.bupmem.size); +} + +static 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; +} + +static void cp15_saveone(armcp15_t *cp15, std::ostream* os) +{ + write32le(cp15->IDCode,os); + write32le(cp15->cacheType,os); + write32le(cp15->TCMSize,os); + write32le(cp15->ctrl,os); + write32le(cp15->DCConfig,os); + write32le(cp15->ICConfig,os); + write32le(cp15->writeBuffCtrl,os); + write32le(cp15->und,os); + write32le(cp15->DaccessPerm,os); + write32le(cp15->IaccessPerm,os); + write32le(cp15->protectBaseSize0,os); + write32le(cp15->protectBaseSize1,os); + write32le(cp15->protectBaseSize2,os); + write32le(cp15->protectBaseSize3,os); + write32le(cp15->protectBaseSize4,os); + write32le(cp15->protectBaseSize5,os); + write32le(cp15->protectBaseSize6,os); + write32le(cp15->protectBaseSize7,os); + write32le(cp15->cacheOp,os); + write32le(cp15->DcacheLock,os); + write32le(cp15->IcacheLock,os); + write32le(cp15->ITCMRegion,os); + write32le(cp15->DTCMRegion,os); + write32le(cp15->processID,os); + write32le(cp15->RAM_TAG,os); + write32le(cp15->testState,os); + write32le(cp15->cacheDbg,os); + for(int i=0;i<8;i++) write32le(cp15->regionWriteMask_USR[i],os); + for(int i=0;i<8;i++) write32le(cp15->regionWriteMask_SYS[i],os); + for(int i=0;i<8;i++) write32le(cp15->regionReadMask_USR[i],os); + for(int i=0;i<8;i++) write32le(cp15->regionReadMask_SYS[i],os); + for(int i=0;i<8;i++) write32le(cp15->regionExecuteMask_USR[i],os); + for(int i=0;i<8;i++) write32le(cp15->regionExecuteMask_SYS[i],os); + for(int i=0;i<8;i++) write32le(cp15->regionWriteSet_USR[i],os); + for(int i=0;i<8;i++) write32le(cp15->regionWriteSet_SYS[i],os); + for(int i=0;i<8;i++) write32le(cp15->regionReadSet_USR[i],os); + for(int i=0;i<8;i++) write32le(cp15->regionReadSet_SYS[i],os); + for(int i=0;i<8;i++) write32le(cp15->regionExecuteSet_USR[i],os); + for(int i=0;i<8;i++) write32le(cp15->regionExecuteSet_SYS[i],os); +} + +static void cp15_savestate(std::ostream* os) +{ + //version + write32le(0,os); + + cp15_saveone((armcp15_t *)NDS_ARM9.coproc[15],os); + cp15_saveone((armcp15_t *)NDS_ARM7.coproc[15],os); +} + +static bool cp15_loadone(armcp15_t *cp15, std::istream* is) +{ + if(!read32le(&cp15->IDCode,is)) return false; + if(!read32le(&cp15->cacheType,is)) return false; + if(!read32le(&cp15->TCMSize,is)) return false; + if(!read32le(&cp15->ctrl,is)) return false; + if(!read32le(&cp15->DCConfig,is)) return false; + if(!read32le(&cp15->ICConfig,is)) return false; + if(!read32le(&cp15->writeBuffCtrl,is)) return false; + if(!read32le(&cp15->und,is)) return false; + if(!read32le(&cp15->DaccessPerm,is)) return false; + if(!read32le(&cp15->IaccessPerm,is)) return false; + if(!read32le(&cp15->protectBaseSize0,is)) return false; + if(!read32le(&cp15->protectBaseSize1,is)) return false; + if(!read32le(&cp15->protectBaseSize2,is)) return false; + if(!read32le(&cp15->protectBaseSize3,is)) return false; + if(!read32le(&cp15->protectBaseSize4,is)) return false; + if(!read32le(&cp15->protectBaseSize5,is)) return false; + if(!read32le(&cp15->protectBaseSize6,is)) return false; + if(!read32le(&cp15->protectBaseSize7,is)) return false; + if(!read32le(&cp15->cacheOp,is)) return false; + if(!read32le(&cp15->DcacheLock,is)) return false; + if(!read32le(&cp15->IcacheLock,is)) return false; + if(!read32le(&cp15->ITCMRegion,is)) return false; + if(!read32le(&cp15->DTCMRegion,is)) return false; + if(!read32le(&cp15->processID,is)) return false; + if(!read32le(&cp15->RAM_TAG,is)) return false; + if(!read32le(&cp15->testState,is)) return false; + if(!read32le(&cp15->cacheDbg,is)) return false; + for(int i=0;i<8;i++) if(!read32le(&cp15->regionWriteMask_USR[i],is)) return false; + for(int i=0;i<8;i++) if(!read32le(&cp15->regionWriteMask_SYS[i],is)) return false; + for(int i=0;i<8;i++) if(!read32le(&cp15->regionReadMask_USR[i],is)) return false; + for(int i=0;i<8;i++) if(!read32le(&cp15->regionReadMask_SYS[i],is)) return false; + for(int i=0;i<8;i++) if(!read32le(&cp15->regionExecuteMask_USR[i],is)) return false; + for(int i=0;i<8;i++) if(!read32le(&cp15->regionExecuteMask_SYS[i],is)) return false; + for(int i=0;i<8;i++) if(!read32le(&cp15->regionWriteSet_USR[i],is)) return false; + for(int i=0;i<8;i++) if(!read32le(&cp15->regionWriteSet_SYS[i],is)) return false; + for(int i=0;i<8;i++) if(!read32le(&cp15->regionReadSet_USR[i],is)) return false; + for(int i=0;i<8;i++) if(!read32le(&cp15->regionReadSet_SYS[i],is)) return false; + for(int i=0;i<8;i++) if(!read32le(&cp15->regionExecuteSet_USR[i],is)) return false; + for(int i=0;i<8;i++) if(!read32le(&cp15->regionExecuteSet_SYS[i],is)) return false; + + return true; +} + +static bool cp15_loadstate(std::istream* is) +{ + //read version + int version; + if(read32le(&version,is) != 1) return false; + if(version != 0) return false; + + if(!cp15_loadone((armcp15_t *)NDS_ARM9.coproc[15],is)) return false; + if(!cp15_loadone((armcp15_t *)NDS_ARM7.coproc[15],is)) return false; + + return true; +} + + + +/* Format time and convert to string */ +static char * format_time(time_t cal_time) +{ + struct tm *time_struct; + static char string[30]; + + time_struct=localtime(&cal_time); + strftime(string, sizeof string, "%Y-%m-%d %H:%M", time_struct); + + return(string); +} + +void clear_savestates() +{ + u8 i; + for( i = 0; i < NB_STATES; i++ ) + savestates[i].exists = FALSE; +} + +/* Scan for existing savestates and update struct */ +void scan_savestates() +{ + struct stat sbuf; + char filename[MAX_PATH]; + u8 i; + + clear_savestates(); + + for( i = 1; i <= NB_STATES; i++ ) + { + strncpy(filename, szRomBaseName,MAX_PATH); + if (strlen(filename) + strlen(".dst") + strlen("-2147483648") /* = biggest string for i */ >MAX_PATH) return ; + sprintf(filename+strlen(filename), "%d.dst", i); + if( stat(filename,&sbuf) == -1 ) continue; + savestates[i-1].exists = TRUE; + strncpy(savestates[i-1].date, format_time(sbuf.st_mtime),40-strlen(savestates[i-1].date)); + } + + return ; +} + +void savestate_slot(int num) +{ + struct stat sbuf; + char filename[MAX_PATH]; + + strncpy(filename, szRomBaseName,MAX_PATH); + if (strlen(filename) + strlen(".dst") + strlen("-2147483648") /* = biggest string for num */ >MAX_PATH) return ; + sprintf(filename+strlen(filename), "%d.dst", num); + savestate_save(filename); + + savestates[num-1].exists = TRUE; + if( stat(filename,&sbuf) == -1 ) return; + strncpy(savestates[num-1].date, format_time(sbuf.st_mtime),40-strlen(savestates[num-1].date)); +} + +void loadstate_slot(int num) +{ + char filename[MAX_PATH]; + strncpy(filename, szRomBaseName,MAX_PATH); + if (strlen(filename) + strlen(".dst") + strlen("-2147483648") /* = biggest string for num */ >MAX_PATH) return ; + sprintf(filename+strlen(filename), "%d.dst", num); + savestate_load(filename); +} + +u8 sram_read (u32 address) { + address = address - SRAM_ADDRESS; + + if ( address > SRAM_SIZE ) + return 0; + + return MMU.CART_RAM[address]; + +} + +void sram_write (u32 address, u8 value) { + + address = address - SRAM_ADDRESS; + + if ( address < SRAM_SIZE ) + MMU.CART_RAM[address] = value; + +} + +int sram_load (const char *file_name) { + + FILE *file; + size_t elems_read; + + file = fopen ( file_name, "rb" ); + if( file == NULL ) + return 0; + + elems_read = fread ( MMU.CART_RAM, SRAM_SIZE, 1, file ); + + fclose ( file ); + + return 1; + +} + +int sram_save (const char *file_name) { + + FILE *file; + size_t elems_written; + + file = fopen ( file_name, "wb" ); + if( file == NULL ) + return 0; + + elems_written = fwrite ( MMU.CART_RAM, SRAM_SIZE, 1, file ); + + fclose ( file ); + + return 1; + +} + +static SFORMAT *CheckS(SFORMAT *sf, u32 size, u32 count, char *desc) +{ + while(sf->v) + { + //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(sf->size != size || sf->count != count) + return 0; + return sf; + } + sf++; + } + return 0; +} + + +static bool ReadStateChunk(std::istream* is, SFORMAT *sf, int size) +{ + SFORMAT *tmp; + int temp = is->tellg(); + + while(is->tellg()read(toa,4); + if(is->fail()) + return false; + + if(!read32le(&sz,is)) return false; + if(!read32le(&count,is)) return false; + + if((tmp=CheckS(sf,sz,count,toa))) + { + if(sz == 1) { + //special case: read a huge byte array + is->read((char *)tmp->v,count); + } else { + for(unsigned int i=0;iread((char *)tmp->v + i*sz,sz); + + #ifndef LOCAL_LE + FlipByteOrder((u8*)tmp->v + i*sz,sz); + #endif + } + } + } + else + is->seekg(sz*count,std::ios::cur); + } // while(...) + return true; +} + + + +static int SubWrite(std::ostream* os, SFORMAT *sf) +{ + uint32 acc=0; + + while(sf->v) + { + //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; + //} + + int count = sf->count; + int size = sf->size; + + //add size of current node to the accumulator + acc += sizeof(sf->desc) + sizeof(sf->size) + sizeof(sf->count); + acc += count * size; + + if(os) //Are we writing or calculating the size of this block? + { + os->write(sf->desc,4); + write32le(sf->size,os); + write32le(sf->count,os); + + if(size == 1) { + //special case: write a huge byte array + os->write((char *)sf->v,count); + } else { + for(int i=0;iv + i*size, size); + #endif + + os->write((char*)sf->v + i*size,size); + + //Now restore the original byte order. + #ifndef LOCAL_LE + FlipByteOrder((u8*)sf->v + i*size, size); + #endif + } + } + } + sf++; + } + + return(acc); +} + +static int savestate_WriteChunk(std::ostream* os, int type, SFORMAT *sf) +{ + write32le(type,os); + if(!sf) return 4; + int bsize = SubWrite((std::ostream*)0,sf); + write32le(bsize,os); + + if(!SubWrite(os,sf)) + { + return 8; + } + return (bsize+8); +} + +static void savestate_WriteChunk(std::ostream* os, int type, void (*saveproc)(std::ostream* os)) +{ + //get the size + memorystream mstemp; + saveproc(&mstemp); + mstemp.flush(); + u32 size = mstemp.size(); + + //write the type, size, and data + write32le(type,os); + write32le(size,os); + os->write(mstemp.buf(),size); +} + +static void writechunks(std::ostream* os); + +static bool savestate_save(std::ostream* outstream, int compressionLevel) +{ + //generate the savestate in memory first + memorystream ms; + std::ostream* os = (std::ostream*)&ms; + writechunks(os); + ms.flush(); + + //save the length of the file + u32 len = ms.size(); + + u32 comprlen = 0xFFFFFFFF; + u8* cbuf = (u8*)ms.buf(); + +#ifdef HAVE_LIBZ + //compress the data + int error = Z_OK; + if(compressionLevel != Z_NO_COMPRESSION) + { + uLongf comprlen2; + //worst case compression. + //zlib says "0.1% larger than sourceLen plus 12 bytes" + comprlen = (len>>9)+12 + len; + cbuf = new u8[comprlen]; + /* Workaround to make it compile under linux 64bit */ + comprlen2 = comprlen; + error = compress2(cbuf,&comprlen2,(u8*)ms.buf(),len,compressionLevel); + comprlen = (u32)comprlen2; + } +#endif + + //dump the header + outstream->write(magic,16); + write32le(SAVESTATE_VERSION,outstream); + write32le(DESMUME_VERSION_NUMERIC,outstream); //desmume version + write32le(len,outstream); //uncompressed length + write32le(comprlen,outstream); //compressed length (-1 if it is not compressed) + + outstream->write((char*)cbuf,comprlen==(u32)-1?len:comprlen); + if(cbuf != (uint8*)ms.buf()) delete[] cbuf; +#ifdef HAVE_LIBZ + return error == Z_OK; +#else + return true; +#endif +} + +bool savestate_save (const char *file_name) +{ + memorystream ms; + size_t elems_written; +#ifdef HAVE_LIBZ + if(!savestate_save(&ms, Z_DEFAULT_COMPRESSION)) +#else + if(!savestate_save(&ms, 0)) +#endif + return false; + ms.flush(); + FILE* file = fopen(file_name,"wb"); + if(file) + { + elems_written = fwrite(ms.buf(),1,ms.size(),file); + fclose(file); + return (elems_written == ms.size()); + } else return false; +} + +//u8 GPU_screen[4*256*192]; + +static void writechunks(std::ostream* os) { + savestate_WriteChunk(os,1,SF_ARM9); + savestate_WriteChunk(os,2,SF_ARM7); + savestate_WriteChunk(os,3,cp15_savestate); + savestate_WriteChunk(os,4,SF_MEM); + savestate_WriteChunk(os,5,SF_NDS); + savestate_WriteChunk(os,60,SF_MMU); + savestate_WriteChunk(os,61,mmu_savestate); + savestate_WriteChunk(os,7,gpu_savestate); + savestate_WriteChunk(os,8,spu_savestate); + savestate_WriteChunk(os,90,SF_GFX3D); + savestate_WriteChunk(os,91,gfx3d_savestate); + savestate_WriteChunk(os,0xFFFFFFFF,(SFORMAT*)0); +} + +static bool ReadStateChunks(std::istream* is, s32 totalsize) +{ + bool ret = true; + while(totalsize > 0) + { + uint32 size; + u32 t; + if(!read32le(&t,is)) { ret=false; break; } + if(t == 0xFFFFFFFF) goto done; + if(!read32le(&size,is)) { ret=false; break; } + switch(t) + { + case 1: if(!ReadStateChunk(is,SF_ARM9,size)) ret=false; break; + case 2: if(!ReadStateChunk(is,SF_ARM7,size)) ret=false; break; + case 3: if(!cp15_loadstate(is)) ret=false; break; + case 4: if(!ReadStateChunk(is,SF_MEM,size)) ret=false; break; + case 5: if(!ReadStateChunk(is,SF_NDS,size)) ret=false; break; + case 60: if(!ReadStateChunk(is,SF_MMU,size)) ret=false; break; + case 61: if(!mmu_loadstate(is)) ret=false; break; + case 7: if(!gpu_loadstate(is)) ret=false; break; + case 8: if(!spu_loadstate(is)) ret=false; break; + case 90: if(!ReadStateChunk(is,SF_GFX3D,size)) ret=false; break; + case 91: if(!gfx3d_loadstate(is)) ret=false; break; + default: + ret=false; + break; + } + if(!ret) return false; + } +done: + + return ret; +} + +static void loadstate() +{ + // This should regenerate the vram banks + for (int i = 0; i < 0xA; i++) + _MMU_write08(0x04000240+i, _MMU_read08(0x04000240+i)); + + // This should regenerate the graphics power control register + _MMU_write16(0x04000304, _MMU_read16(0x04000304)); + + // This should regenerate the graphics configuration + for (int i = REG_BASE_DISPA; i<=REG_BASE_DISPA + 0x7F; i+=2) + _MMU_write16(i, _MMU_read16(i)); + for (int i = REG_BASE_DISPB; i<=REG_BASE_DISPB + 0x7F; i+=2) + _MMU_write16(i, _MMU_read16(i)); +} + +static bool savestate_load(std::istream* is) +{ + char header[16]; + is->read(header,16); + if(is->fail() || memcmp(header,magic,16)) + return false; + + u32 ssversion,dversion,len,comprlen; + if(!read32le(&ssversion,is)) return false; + if(!read32le(&dversion,is)) return false; + if(!read32le(&len,is)) return false; + if(!read32le(&comprlen,is)) return false; + + if(ssversion != SAVESTATE_VERSION) return false; + + std::vector buf(len); + + if(comprlen != 0xFFFFFFFF) { +#ifndef HAVE_LIBZ + //without libz, we can't decompress this savestate + return false; +#endif + std::vector cbuf(comprlen); + is->read(&cbuf[0],comprlen); + if(is->fail()) return false; + +#ifdef HAVE_LIBZ + uLongf uncomprlen = len; + int error = uncompress((uint8*)&buf[0],&uncomprlen,(uint8*)&cbuf[0],comprlen); + if(error != Z_OK || uncomprlen != len) + return false; +#endif + } else { + is->read((char*)&buf[0],len); + } + + //GO!! READ THE SAVESTATE + //THERE IS NO GOING BACK NOW + //reset the emulator first to clean out the host's state + + //while the series of resets below should work, + //we are testing the robustness of the savestate system with this full reset. + //the full reset wipes more things, so we can make sure that they are being restored correctly + NDS_Reset(); + + //GPU_Reset(MainScreen.gpu, 0); + //GPU_Reset(SubScreen.gpu, 1); + //gfx3d_reset(); + //gpu3D->NDS_3D_Reset(); + //SPU_Reset(); + + + memorystream mstemp(&buf); + bool x = ReadStateChunks(&mstemp,(s32)len); + + loadstate(); + + return x; +} + +bool savestate_load(const char *file_name) +{ + std::ifstream f; + f.open(file_name,std::ios_base::binary|std::ios_base::in); + if(!f) return false; + + return savestate_load(&f); +} diff --git a/desmume/src/thumb_instructions.cpp b/desmume/src/thumb_instructions.cpp index 3e30f7aa9..fbe4fb6d1 100644 --- a/desmume/src/thumb_instructions.cpp +++ b/desmume/src/thumb_instructions.cpp @@ -875,22 +875,22 @@ TEMPLATE static u32 FASTCALL OP_B_COND() TEMPLATE static u32 FASTCALL OP_SWI_THUMB() { - if(cpu->swi_tab) { + if(cpu->swi_tab) { //zero 25-dec-2008 - in arm, we were masking to 0x1F. //this is probably safer since an invalid opcode could crash the emu //u32 swinum = cpu->instruction & 0xFF; - u32 swinum = cpu->instruction & 0x1F; - return cpu->swi_tab[swinum](cpu) + 3; - } + u32 swinum = cpu->instruction & 0x1F; + return cpu->swi_tab[swinum]() + 3; + } else { /* we use an irq thats not in the irq tab, as it was replaced duie to a changed intVector */ Status_Reg tmp = cpu->CPSR; armcpu_switchMode(cpu, SVC); /* enter svc mode */ - cpu->R[14] = cpu->next_instruction; /* jump to swi Vector */ + cpu->R[14] = cpu->next_instruction; /* jump to swi Vector */ cpu->SPSR = tmp; /* save old CPSR as new SPSR */ cpu->CPSR.bits.T = 0; /* handle as ARM32 code */ - cpu->CPSR.bits.I = 1; + cpu->CPSR.bits.I = 1; cpu->R[15] = cpu->intVector + 0x08; cpu->next_instruction = cpu->R[15]; return 3;