Skip to content

Commit

Permalink
Fixed load/save state for Master System.
Browse files Browse the repository at this point in the history
  • Loading branch information
FluBBaOfWard committed Oct 17, 2021
1 parent 49c2f29 commit b0a317a
Show file tree
Hide file tree
Showing 11 changed files with 132 additions and 58 deletions.
3 changes: 3 additions & 0 deletions History.txt
Expand Up @@ -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.
Expand Down
4 changes: 2 additions & 2 deletions 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:

Expand All @@ -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!
Expand Down
4 changes: 4 additions & 0 deletions S8DS.xcodeproj/project.pbxproj
Expand Up @@ -63,6 +63,8 @@
9C4C21D026E4EF13007D0280 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
9C4DF1E224BB5F6F00FB4EB0 /* AY38910.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AY38910.h; sourceTree = "<group>"; };
9C4DF1E324BB5F6F00FB4EB0 /* AY38910.i */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c.preprocessed; path = AY38910.i; sourceTree = "<group>"; };
9C4EB1C1271C3A840072D38E /* MasterSystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MasterSystem.h; sourceTree = "<group>"; };
9C4EB1C2271C3A840072D38E /* MasterSystem.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = MasterSystem.c; sourceTree = "<group>"; };
9C5082C425E2C4B400A8E1BA /* ARMZ80.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARMZ80.h; sourceTree = "<group>"; };
9C5082C525E2C4B400A8E1BA /* ARMZ80.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = ARMZ80.s; sourceTree = "<group>"; };
9C5082C625E2C4B400A8E1BA /* ARMZ80mac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARMZ80mac.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -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 */,
Expand Down
22 changes: 20 additions & 2 deletions source/Cart.h
Expand Up @@ -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"
Expand Down
87 changes: 40 additions & 47 deletions source/Cart.s
Expand Up @@ -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
Expand Down Expand Up @@ -991,80 +992,59 @@ mdE:
addeq r0,r0,#2
b mdE2
;@----------------------------------------------------------------------------
packState: ;@ Called from ui.c.
;@int packState(u32 *statePtr), copy state to <here>, 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:
.long EMU_SRAM,0x8000
.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
Expand All @@ -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


Expand Down Expand Up @@ -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:
Expand Down
13 changes: 7 additions & 6 deletions source/FileHandling.c
Expand Up @@ -14,14 +14,14 @@
#include "Shared/EmuSettings.h"
#include "Shared/FileHelper.h"
#include "Gui.h"
#include "MasterSystem.h"
#include "RomLoading.h"
#include "Equates.h"
#include "SegaVDP/SegaVDP.h"
#include "Cart.h"
#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";

Expand Down Expand Up @@ -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.");
Expand All @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion source/Gui.c
Expand Up @@ -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

Expand Down
31 changes: 31 additions & 0 deletions source/MasterSystem.c
@@ -0,0 +1,31 @@
#include <nds.h>

#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;
}
21 changes: 21 additions & 0 deletions 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
2 changes: 2 additions & 0 deletions source/Sound.h
Expand Up @@ -6,7 +6,9 @@ extern "C" {
#endif

#include <maxmod9.h>
#include "SN76496/SN76496.h"

extern SN76496 SN76496_0;
void soundInit(void);
void soundSetFrequency(void);
void setMuteSoundGUI(void);
Expand Down
1 change: 1 addition & 0 deletions source/Sound.s
Expand Up @@ -12,6 +12,7 @@
.global VblSound2
.global SMSJSoundControlW
.global SMSJSoundControlR
.global SN76496_0
.global SN76496_W
.global SN76496_0_W
.global SN76496_1_W
Expand Down

0 comments on commit b0a317a

Please sign in to comment.