diff --git a/History.txt b/History.txt index 8da14a1..4486d6f 100644 --- a/History.txt +++ b/History.txt @@ -2,6 +2,9 @@ S8DS revision history -=-=-=-=-=-=-=-=-=-=-=- +V1.1.5 - 2021-10-17 (FluBBa) + Fixed load/save state. + V1.1.4 - 2021-10-16 (FluBBa) Reverted a GG_IO optimization. Fixed TV noise graphics after Power off. diff --git a/README.md b/README.md index dc6ed3f..dfce364 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# S8DS V1.1.4 +# S8DS V1.1.5 This is a SEGA 8Bit emulator for the NDS, it support the following systems: @@ -23,7 +23,7 @@ Missing: Correct sprite collision. Speech samples. - YM2413 emulation. + Good YM2413 emulation. EEPROM save for the few GG games that use it. Check your roms! diff --git a/S8DS.xcodeproj/project.pbxproj b/S8DS.xcodeproj/project.pbxproj index 1ae4e3e..960cbf3 100644 --- a/S8DS.xcodeproj/project.pbxproj +++ b/S8DS.xcodeproj/project.pbxproj @@ -63,6 +63,8 @@ 9C4C21D026E4EF13007D0280 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 9C4DF1E224BB5F6F00FB4EB0 /* AY38910.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AY38910.h; sourceTree = ""; }; 9C4DF1E324BB5F6F00FB4EB0 /* AY38910.i */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c.preprocessed; path = AY38910.i; sourceTree = ""; }; + 9C4EB1C1271C3A840072D38E /* MasterSystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MasterSystem.h; sourceTree = ""; }; + 9C4EB1C2271C3A840072D38E /* MasterSystem.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = MasterSystem.c; sourceTree = ""; }; 9C5082C425E2C4B400A8E1BA /* ARMZ80.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARMZ80.h; sourceTree = ""; }; 9C5082C525E2C4B400A8E1BA /* ARMZ80.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = ARMZ80.s; sourceTree = ""; }; 9C5082C625E2C4B400A8E1BA /* ARMZ80mac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARMZ80mac.h; sourceTree = ""; }; @@ -329,6 +331,8 @@ A49D34451757E54900BD9B4B /* Main.c */, A49D343F1757E54900BD9B4B /* Gui.h */, A49D343E1757E54900BD9B4B /* Gui.c */, + 9C4EB1C1271C3A840072D38E /* MasterSystem.h */, + 9C4EB1C2271C3A840072D38E /* MasterSystem.c */, 35E683AC1C663E9B00FCFE8A /* Cart.h */, A49D34371757E54900BD9B4B /* Cart.s */, 35E683AD1C66453300FCFE8A /* cpu.h */, diff --git a/source/Cart.h b/source/Cart.h index d9dcba6..68a6881 100644 --- a/source/Cart.h +++ b/source/Cart.h @@ -32,8 +32,26 @@ extern void *g_BIOSBASE_SORDM5; void loadCart(int); void ejectCart(void); -int packState(u32 *statePtr); -void unpackState(u32 *statePtr); + +/** +* Saves the state of cart to the destination. +* @param *destination: Where to save the state. +* @return The size of the state. +*/ +int cartSaveState(void *destination); + +/** +* Loads the state of cart from the source. +* @param *source: Where to load the state from. +* @return The size of the state. +*/ +int cartLoadState(const void *source); + +/** + * Gets the state size of cart state. + * @return The size of the state. + */ +int cartGetStateSize(void); #ifdef __cplusplus } // extern "C" diff --git a/source/Cart.s b/source/Cart.s index bbb505d..d6d899c 100644 --- a/source/Cart.s +++ b/source/Cart.s @@ -6,8 +6,9 @@ .global loadCart .global ejectCart - .global packState - .global unpackState + .global cartSaveState + .global cartLoadState + .global cartGetStateSize .global g_emuFlags .global cartBase // .global scaling @@ -991,34 +992,29 @@ mdE: addeq r0,r0,#2 b mdE2 ;@---------------------------------------------------------------------------- -packState: ;@ Called from ui.c. -;@int packState(u32 *statePtr), copy state to , return size - .type packState STT_FUNC +cartSaveState: ;@ Called from C code. + .type cartSaveState STT_FUNC ;@---------------------------------------------------------------------------- - stmfd sp!,{r4-r5,z80pc,z80optbl,lr} - ldr z80optbl,=Z80OpTable + stmfd sp!,{r4-r5,lr} mov r5,r0 ;@ r5=where to copy state - bl fixCpuPCSave ;@ Adjust z80pc so it isn't based on rombase mov r0,#0 ;@ r0 holds total size (return value) - adr r4,saveLst ;@ r4=list of stuff to copy - mov r3,#(lstEnd-saveLst)/8 ;@ r3=items in list + mov r12,#(lstEnd-saveLst)/8 ;@ r4=items in list + adr r3,saveLst ;@ r3=list of stuff to copy ss1: - ldmia r4!,{r1,r2} ;@ r1=what to copy, r2=how much to copy + ldmia r3!,{r1,r2} ;@ r1=what to copy, r2=how much to copy add r0,r0,r2 ss0: - ldr r12,[r1],#4 - str r12,[r5],#4 + ldr r4,[r1],#4 + str r4,[r5],#4 subs r2,r2,#4 bne ss0 - subs r3,r3,#1 + subs r12,r12,#1 bne ss1 - bl fixCpuPCLoad - - ldmfd sp!,{r4-r5,z80pc,z80optbl,lr} + ldmfd sp!,{r4-r5,lr} bx lr saveLst: @@ -1026,45 +1022,29 @@ saveLst: .long EMU_RAM,0x2000 .long VDPRAM,0x4000 .long romInfo,12 -// .long z80State,72 - .long VDP0+vdpState,VDPSTATESIZE, - .long SoundVariables,60 + .long VDP0+vdpState,VDPSTATESIZE .long BankState,24 lstEnd: -fixCpuPCSave: - loadLastBank r1 - ldr r2,[z80optbl,#z80Regs+6*4] ;@ Z80 PC - sub r2,r2,r1 - str r2,[z80optbl,#z80Regs+6*4] ;@ Z80 PC - bx lr - -fixCpuPCLoad: - stmfd sp!,{r0,lr} - ldr z80pc,[z80optbl,#z80Regs+6*4] ;@ Z80 PC - encodePC - str z80pc,[z80optbl,#z80Regs+6*4] ;@ Z80 PC - ldmfd sp!,{r0,lr} - bx lr - ;@---------------------------------------------------------------------------- -unpackState: ;@ Called from ui.c -;@ void unpackState(u32 *stateptr) (stateptr must be word aligned) - .type unpackState STT_FUNC +cartLoadState: ;@ Called from C code. + .type cartLoadState STT_FUNC ;@---------------------------------------------------------------------------- - stmfd sp!,{r4-r5,z80optbl,lr} + stmfd sp!,{r4-r5,z80pc,z80optbl,lr} ldr z80optbl,=Z80OpTable - mov r4,#(lstEnd-saveLst)/8 ;@ Read entire state + mov r12,#(lstEnd-saveLst)/8 ;@ Read entire state adr r3,saveLst + mov r5,#0 ls1: ldmia r3!,{r1,r2} + add r5,r5,r2 ls0: - ldr r5,[r0],#4 - str r5,[r1],#4 + ldr r4,[r0],#4 + str r4,[r1],#4 subs r2,r2,#4 bne ls0 - subs r4,r4,#1 + subs r12,r12,#1 bne ls1 ldrb r0,BankMap4 @@ -1081,13 +1061,26 @@ ls0: bl reBankSwitch1_W bl reBankSwitch2_W - bl fixCpuPCLoad - bl paletteTxAll ldr vdpptr,=VDP0 bl VDPClearDirtyTiles - ldmfd sp!,{r4-r5,z80optbl,lr} + mov r0,r5 + ldmfd sp!,{r4-r5,z80pc,z80optbl,lr} + bx lr +;@---------------------------------------------------------------------------- +cartGetStateSize: ;@ Called from C code. + .type cartGetStateSize STT_FUNC +;@---------------------------------------------------------------------------- + mov r12,#(lstEnd-saveLst)/8 ;@ Read entire state + adr r3,saveLst + mov r0,#0 +sizeLoop1: + ldmia r3!,{r1,r2} + add r0,r0,r2 + subs r12,r12,#1 + bne sizeLoop1 + bx lr @@ -1621,7 +1614,7 @@ romMask: romMaskBackup: .long 0 -romInfo: ;@ Keep emuflags/BGmirror together for savestate/loadstate +romInfo: ;@ Keep emuflags together for savestate/loadstate g_emuFlags: .long 0 ;@ emuflags (label this so UI.C can take a peek) see equates.h for bitfields g_scalingSet: diff --git a/source/FileHandling.c b/source/FileHandling.c index d0ab1f3..ff7a8b5 100644 --- a/source/FileHandling.c +++ b/source/FileHandling.c @@ -14,6 +14,7 @@ #include "Shared/EmuSettings.h" #include "Shared/FileHelper.h" #include "Gui.h" +#include "MasterSystem.h" #include "RomLoading.h" #include "Equates.h" #include "SegaVDP/SegaVDP.h" @@ -21,7 +22,6 @@ #include "Gfx.h" #include "io.h" -#define STATESIZE (0x8000+0x2000+0x4000+12+104+VDPSTATESIZE+60+24) static const char *const folderName = "s8ds"; static const char *const settingName = "settings.cfg"; @@ -154,12 +154,12 @@ void loadState() { } strlcpy(stateName, currentFilename, sizeof(stateName)); strlcat(stateName, ".sta", sizeof(stateName)); + int stateSize = getStateSize(); if ( (file = fopen(stateName, "r")) ) { - if ( (statePtr = malloc(STATESIZE)) ) { + if ( (statePtr = malloc(stateSize)) ) { cls(0); drawText(" Loading state...", 11, 0); - fread(statePtr, 1, STATESIZE, file); - loadCart(g_emuFlags); + fread(statePtr, 1, stateSize, file); unpackState(statePtr); free(statePtr); infoOutput("Loaded state."); @@ -181,12 +181,13 @@ void saveState() { } strlcpy(stateName, currentFilename, sizeof(stateName)); strlcat(stateName, ".sta", sizeof(stateName)); + int stateSize = getStateSize(); if ( (file = fopen(stateName, "w")) ) { - if ( (statePtr = malloc(STATESIZE)) ) { + if ( (statePtr = malloc(stateSize)) ) { cls(0); drawText(" Saving state...", 11, 0); packState(statePtr); - fwrite(statePtr, 1, STATESIZE, file); + fwrite(statePtr, 1, stateSize, file); free(statePtr); infoOutput("Saved state."); } else { diff --git a/source/Gui.c b/source/Gui.c index c4880f6..e301b70 100644 --- a/source/Gui.c +++ b/source/Gui.c @@ -29,7 +29,7 @@ #include "AY38910/Version.h" #include "SCC/Version.h" -#define EMUVERSION "V1.1.4 2021-10-16" +#define EMUVERSION "V1.1.5 2021-10-17" extern u8 sordM5Input; // SordM5.s diff --git a/source/MasterSystem.c b/source/MasterSystem.c new file mode 100644 index 0000000..e03fc6d --- /dev/null +++ b/source/MasterSystem.c @@ -0,0 +1,31 @@ +#include + +#include "MasterSystem.h" +#include "Cart.h" +#include "Sound.h" +#include "SN76496/SN76496.h" +#include "ARMZ80/ARMZ80.h" + + +int packState(void *statePtr) { + int size = 0; + size += cartSaveState(statePtr+size); + size += sn76496SaveState(statePtr+size, &SN76496_0); + size += Z80SaveState(statePtr+size, &Z80OpTable); + return size; +} + +void unpackState(const void *statePtr) { + int size = 0; + size += cartLoadState(statePtr+size); + size += sn76496LoadState(&SN76496_0, statePtr+size); + size += Z80LoadState(&Z80OpTable, statePtr+size); +} + +int getStateSize() { + int size = 0; + size += cartGetStateSize(); + size += sn76496GetStateSize(); + size += Z80GetStateSize(); + return size; +} diff --git a/source/MasterSystem.h b/source/MasterSystem.h new file mode 100644 index 0000000..d4e7b28 --- /dev/null +++ b/source/MasterSystem.h @@ -0,0 +1,21 @@ +#ifndef MASTERSYSTEM_HEADER +#define MASTERSYSTEM_HEADER + +#ifdef __cplusplus +extern "C" { +#endif + +/// This runs all save state functions for each chip. +int packState(void *statePtr); + +/// This runs all load state functions for each chip. +void unpackState(const void *statePtr); + +/// Gets the total state size in bytes. +int getStateSize(void); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // MASTERSYSTEM_HEADER diff --git a/source/Sound.h b/source/Sound.h index 5bfc8cc..0a61a5f 100644 --- a/source/Sound.h +++ b/source/Sound.h @@ -6,7 +6,9 @@ extern "C" { #endif #include +#include "SN76496/SN76496.h" +extern SN76496 SN76496_0; void soundInit(void); void soundSetFrequency(void); void setMuteSoundGUI(void); diff --git a/source/Sound.s b/source/Sound.s index 5fdf261..8d89c78 100644 --- a/source/Sound.s +++ b/source/Sound.s @@ -12,6 +12,7 @@ .global VblSound2 .global SMSJSoundControlW .global SMSJSoundControlR + .global SN76496_0 .global SN76496_W .global SN76496_0_W .global SN76496_1_W