Search
lxdream.org :: lxdream :: r17:944f75eea496
lxdream 0.9.1
released Jun 29
Download Now
changeset17:944f75eea496
parent16:f383e7640da4
child18:9a1b5d75703f
authornkeynes
dateTue Dec 13 14:47:59 2005 +0000 (13 years ago)
More work on load/save state - save state a little more structured now
Memory save now in
src/Makefile.am
src/Makefile.in
src/dreamcast.c
src/dreamcast.h
src/mem.c
src/modules.h
src/util.c
1.1 --- a/src/Makefile.am Tue Dec 13 12:17:26 2005 +0000
1.2 +++ b/src/Makefile.am Tue Dec 13 14:47:59 2005 +0000
1.3 @@ -23,7 +23,7 @@
1.4 sh4/sh4mmio.c sh4/sh4mmio.h sh4/watch.c \
1.5 aica/armcore.c aica/armcore.h aica/armdasm.c aica/armmem.c \
1.6 aica/aica.c aica/aica.h \
1.7 - fileio.c ipbin.c
1.8 + fileio.c ipbin.c util.c
1.9
1.10 dream_LDADD = @PACKAGE_LIBS@ $(INTLLIBS)
1.11
2.1 --- a/src/Makefile.in Tue Dec 13 12:17:26 2005 +0000
2.2 +++ b/src/Makefile.in Tue Dec 13 14:47:59 2005 +0000
2.3 @@ -150,7 +150,7 @@
2.4 sh4/sh4mmio.c sh4/sh4mmio.h sh4/watch.c \
2.5 aica/armcore.c aica/armcore.h aica/armdasm.c aica/armmem.c \
2.6 aica/aica.c aica/aica.h \
2.7 - fileio.c ipbin.c
2.8 + fileio.c ipbin.c util.c
2.9
2.10
2.11 dream_LDADD = @PACKAGE_LIBS@ $(INTLLIBS)
2.12 @@ -172,7 +172,7 @@
2.13 intc.$(OBJEXT) sh4mem.$(OBJEXT) sh4core.$(OBJEXT) \
2.14 sh4dasm.$(OBJEXT) sh4mmio.$(OBJEXT) watch.$(OBJEXT) \
2.15 armcore.$(OBJEXT) armdasm.$(OBJEXT) armmem.$(OBJEXT) \
2.16 - aica.$(OBJEXT) fileio.$(OBJEXT) ipbin.$(OBJEXT)
2.17 + aica.$(OBJEXT) fileio.$(OBJEXT) ipbin.$(OBJEXT) util.$(OBJEXT)
2.18 dream_OBJECTS = $(am_dream_OBJECTS)
2.19 dream_DEPENDENCIES =
2.20 dream_LDFLAGS =
2.21 @@ -193,7 +193,8 @@
2.22 @AMDEP_TRUE@ ./$(DEPDIR)/pvr2.Po ./$(DEPDIR)/sh4core.Po \
2.23 @AMDEP_TRUE@ ./$(DEPDIR)/sh4dasm.Po ./$(DEPDIR)/sh4mem.Po \
2.24 @AMDEP_TRUE@ ./$(DEPDIR)/sh4mmio.Po ./$(DEPDIR)/support.Po \
2.25 -@AMDEP_TRUE@ ./$(DEPDIR)/video.Po ./$(DEPDIR)/watch.Po
2.26 +@AMDEP_TRUE@ ./$(DEPDIR)/util.Po ./$(DEPDIR)/video.Po \
2.27 +@AMDEP_TRUE@ ./$(DEPDIR)/watch.Po
2.28 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
2.29 $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
2.30 CCLD = $(CC)
2.31 @@ -271,6 +272,7 @@
2.32 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sh4mem.Po@am__quote@
2.33 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sh4mmio.Po@am__quote@
2.34 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/support.Po@am__quote@
2.35 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/util.Po@am__quote@
2.36 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/video.Po@am__quote@
2.37 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/watch.Po@am__quote@
2.38
3.1 --- a/src/dreamcast.c Tue Dec 13 12:17:26 2005 +0000
3.2 +++ b/src/dreamcast.c Tue Dec 13 14:47:59 2005 +0000
3.3 @@ -12,6 +12,7 @@
3.4 #define MAX_MODULES 32
3.5 static int num_modules = 0;
3.6 static int dreamcast_state = 0;
3.7 +static char *dreamcast_config = "DEFAULT";
3.8 dreamcast_module_t modules[MAX_MODULES];
3.9
3.10 /**
3.11 @@ -93,28 +94,76 @@
3.12 struct save_state_header {
3.13 char magic[16];
3.14 uint32_t version;
3.15 + uint32_t module_count;
3.16 };
3.17
3.18 -void dreamcast_load_state( FILE *f )
3.19 +
3.20 +int dreamcast_load_state( FILE *f )
3.21 {
3.22 - int i;
3.23 + int i,j;
3.24 + uint32_t count, len;
3.25 + int have_read[MAX_MODULES];
3.26 + char tmp[64];
3.27 struct save_state_header header;
3.28
3.29 fread( &header, sizeof(header), 1, f );
3.30 if( strncmp( header.magic, DREAMCAST_SAVE_MAGIC, 16 ) != 0 ) {
3.31 ERROR( "Not a DreamOn save state file" );
3.32 - return;
3.33 + return 1;
3.34 }
3.35 if( header.version != DREAMCAST_SAVE_VERSION ) {
3.36 ERROR( "DreamOn save state version not supported" );
3.37 - return;
3.38 + return 1;
3.39 + }
3.40 + fread( &count, sizeof(count), 1, f );
3.41 + if( count > MAX_MODULES ) {
3.42 + ERROR( "DreamOn save state is corrupted" );
3.43 + return 1;
3.44 + }
3.45 + for( i=0; i<MAX_MODULES; i++ ) {
3.46 + have_read[i] = 0;
3.47 }
3.48
3.49 - for( i=0; i<num_modules; i++ ) {
3.50 - if( modules[i]->load != NULL )
3.51 - modules[i]->load(f);
3.52 - else if( modules[i]->reset != NULL )
3.53 - modules[i]->reset();
3.54 + for( i=0; i<count; i++ ) {
3.55 + fread(tmp, 4, 1, f );
3.56 + if( strcmp(tmp, "BLCK") != 0 ) {
3.57 + ERROR( "DreamOn save state is corrupted" );
3.58 + return 2;
3.59 + }
3.60 + len = fread_string(tmp, sizeof(tmp), f );
3.61 + if( len > 64 || len < 1 ) {
3.62 + ERROR( "DreamOn save state is corrupted" );
3.63 + return 2;
3.64 + }
3.65 +
3.66 + /* Find the matching module by name */
3.67 + for( j=0; j<num_modules; j++ ) {
3.68 + if( strcmp(modules[j]->name,tmp) == 0 ) {
3.69 + have_read[j] = 1;
3.70 + if( modules[j]->load == NULL ) {
3.71 + ERROR( "DreamOn save state is corrupted" );
3.72 + return 2;
3.73 + } else if( modules[j]->load(f) != 0 ) {
3.74 + ERROR( "DreamOn save state is corrupted" );
3.75 + return 2;
3.76 + }
3.77 + break;
3.78 + }
3.79 + }
3.80 + if( j == num_modules ) {
3.81 + ERROR( "DreamOn save state contains unrecognized section" );
3.82 + return 2;
3.83 + }
3.84 + }
3.85 +
3.86 + /* Any modules that we didn't load - reset to the default state.
3.87 + * (ie it's not an error to skip a module if you don't actually
3.88 + * care about its state).
3.89 + */
3.90 + for( j=0; j<num_modules; j++ ) {
3.91 + if( have_read[j] == 0 && modules[j]->reset != NULL ) {
3.92 + modules[j]->reset();
3.93 + }
3.94 }
3.95 }
3.96
3.97 @@ -125,9 +174,13 @@
3.98
3.99 strcpy( header.magic, DREAMCAST_SAVE_MAGIC );
3.100 header.version = DREAMCAST_SAVE_VERSION;
3.101 + header.module_count = num_modules;
3.102 fwrite( &header, sizeof(header), 1, f );
3.103 + fwrite_string( dreamcast_config, f );
3.104 for( i=0; i<num_modules; i++ ) {
3.105 if( modules[i]->save != NULL ) {
3.106 + fwrite( "BLCK", 4, 1, f );
3.107 + fwrite_string( modules[i]->name, f );
3.108 modules[i]->save(f);
3.109 }
3.110 }
4.1 --- a/src/dreamcast.h Tue Dec 13 12:17:26 2005 +0000
4.2 +++ b/src/dreamcast.h Tue Dec 13 14:47:59 2005 +0000
4.3 @@ -17,7 +17,7 @@
4.4 #define DREAMCAST_SAVE_VERSION 0x00010000
4.5
4.6 void dreamcast_save_state( FILE *f );
4.7 -void dreamcast_load_state( FILE *f );
4.8 +int dreamcast_load_state( FILE *f );
4.9
4.10 #ifdef __cplusplus
4.11 }
5.1 --- a/src/mem.c Tue Dec 13 12:17:26 2005 +0000
5.2 +++ b/src/mem.c Tue Dec 13 14:47:59 2005 +0000
5.3 @@ -1,5 +1,5 @@
5.4 /**
5.5 - * $Id: mem.c,v 1.3 2005-12-12 13:11:07 nkeynes Exp $
5.6 + * $Id: mem.c,v 1.4 2005-12-13 14:47:59 nkeynes Exp $
5.7 * mem.c is responsible for creating and maintaining the overall system memory
5.8 * map, as visible from the SH4 processor.
5.9 *
5.10 @@ -34,8 +34,10 @@
5.11
5.12 char **page_map = NULL;
5.13
5.14 +int mem_load(FILE *f);
5.15 +void mem_save(FILE *f);
5.16 struct dreamcast_module mem_module =
5.17 - { "MEM", mem_init, mem_reset, NULL, NULL, NULL, NULL };
5.18 + { "MEM", mem_init, mem_reset, NULL, NULL, mem_save, mem_load };
5.19
5.20 struct mem_region mem_rgn[MAX_MEM_REGIONS];
5.21 struct mmio_region *io_rgn[MAX_IO_REGIONS];
5.22 @@ -83,6 +85,40 @@
5.23 }
5.24 }
5.25
5.26 +void mem_save( FILE *f )
5.27 +{
5.28 + int i;
5.29 + uint32_t len;
5.30 +
5.31 + /* All memory regions */
5.32 + fwrite( &num_mem_rgns, sizeof(num_mem_rgns), 1, f );
5.33 + for( i=0; i<num_mem_rgns; i++ ) {
5.34 + fwrite_string( mem_rgn[i].name, f );
5.35 + fwrite( &mem_rgn[i].base, sizeof(uint32_t), 1, f );
5.36 + fwrite( &mem_rgn[i].flags, sizeof(int), 1, f );
5.37 + fwrite( &mem_rgn[i].size, sizeof(uint32_t), 1, f );
5.38 + fwrite( mem_rgn[i].mem, mem_rgn[i].size, 1, f );
5.39 + }
5.40 +
5.41 + /* All MMIO regions */
5.42 + fwrite( &num_io_rgns, sizeof(num_io_rgns), 1, f );
5.43 + for( i=0; i<num_io_rgns; i++ ) {
5.44 + fwrite_string( io_rgn[i]->id, f );
5.45 + fwrite( &io_rgn[i]->base, sizeof( uint32_t ), 1, f );
5.46 + fwrite( io_rgn[i]->mem, 4096, 1, f );
5.47 + }
5.48 +}
5.49 +
5.50 +int mem_load( FILE *f )
5.51 +{
5.52 + char tmp[64];
5.53 + uint32_t len;
5.54 + int i;
5.55 +
5.56 + /* All memory regions */
5.57 +
5.58 +}
5.59 +
5.60 struct mem_region *mem_map_region( void *mem, uint32_t base, uint32_t size,
5.61 char *name, int flags )
5.62 {
6.1 --- a/src/modules.h Tue Dec 13 12:17:26 2005 +0000
6.2 +++ b/src/modules.h Tue Dec 13 14:47:59 2005 +0000
6.3 @@ -41,8 +41,9 @@
6.4 /**
6.5 * Load the saved module state from the FILE stream. May be NULL, in which
6.6 * case reset() will be called instead.
6.7 + * @return 0 on success, nonzero on failure.
6.8 */
6.9 - void (*load)(FILE *);
6.10 + int (*load)(FILE *);
6.11 } *dreamcast_module_t;
6.12
6.13 void dreamcast_register_module( dreamcast_module_t );
6.14 @@ -57,6 +58,9 @@
6.15 extern struct dreamcast_module pvr2_module;
6.16 extern struct dreamcast_module gui_module;
6.17
6.18 +void fwrite_string( char *s, FILE *f );
6.19 +int fread_string( char *s, int maxlen, FILE *f );
6.20 +
6.21 #ifdef __cplusplus
6.22 }
6.23 #endif
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/src/util.c Tue Dec 13 14:47:59 2005 +0000
7.3 @@ -0,0 +1,24 @@
7.4 +#include "dream.h"
7.5 +#include "modules.h"
7.6 +
7.7 +void fwrite_string( char *s, FILE *f )
7.8 +{
7.9 + uint32_t len = 0;
7.10 + if( s == NULL ) {
7.11 + fwrite( &len, sizeof(len), 1, f );
7.12 + } else {
7.13 + len = strlen(s)+1;
7.14 + fwrite( &len, sizeof(len), 1, f );
7.15 + fwrite( s, len, 1, f );
7.16 + }
7.17 +}
7.18 +
7.19 +int fread_string( char *s, int maxlen, FILE *f )
7.20 +{
7.21 + uint32_t len;
7.22 + fread( &len, sizeof(len), 1, f );
7.23 + if( len != 0 ) {
7.24 + fread( s, len > maxlen ? maxlen : len, 1, f );
7.25 + }
7.26 + return len;
7.27 +}
.