Search
lxdream.org :: lxdream/src/dreamcast.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/dreamcast.c
changeset 23:1ec3acd0594d
prev18:9a1b5d75703f
next25:fa2d21d57942
author nkeynes
date Fri Dec 23 11:44:55 2005 +0000 (16 years ago)
permissions -rw-r--r--
last change Start of "real" time slices, general structure in place now
view annotate diff log raw
     1 #include <errno.h>
     2 #include "dream.h"
     3 #include "mem.h"
     4 #include "aica/aica.h"
     5 #include "asic.h"
     6 #include "ide.h"
     7 #include "dreamcast.h"
     8 #include "maple.h"
     9 #include "modules.h"
    11 /* Central switchboard for the system */
    13 #define MAX_MODULES 32
    14 static int num_modules = 0;
    15 static int dreamcast_state = 0;
    16 static char *dreamcast_config = "DEFAULT";
    17 dreamcast_module_t modules[MAX_MODULES];
    19 struct save_state_header {
    20     char magic[16];
    21     uint32_t version;
    22     uint32_t module_count;
    23 };
    26 /**
    27  * This function is responsible for defining how all the pieces of the
    28  * dreamcast actually fit together. Among other things, this lets us
    29  * (reasonably) easily redefine the structure for eg various versions of the
    30  * Naomi.
    31  *
    32  * Note currently the locations of the various MMIO pages are hard coded in
    33  * the MMIO definitions - they should probably be moved here.
    34  */
    35 void dreamcast_configure( )
    36 {
    37     /* Register the memory framework */
    38     dreamcast_register_module( &mem_module );
    40     /* Setup standard memory map */
    41     mem_create_ram_region( 0x0C000000, 16 MB, MEM_REGION_MAIN );
    42     mem_create_ram_region( 0x00800000, 2 MB, MEM_REGION_AUDIO );
    43     mem_create_ram_region( 0x00703000, 8 KB, MEM_REGION_AUDIO_SCRATCH );
    44     mem_create_ram_region( 0x05000000, 8 MB, MEM_REGION_VIDEO );
    45     mem_load_rom( "dcboot.rom", 0x00000000, 0x00200000, 0x89f2b1a1 );
    46     mem_load_rom( "dcflash.rom",0x00200000, 0x00020000, 0x357c3568 );
    48     /* Load in the rest of the core modules */
    49     dreamcast_register_module( &sh4_module );
    50     dreamcast_register_module( &asic_module );
    51     dreamcast_register_module( &pvr2_module );
    52     dreamcast_register_module( &aica_module );
    53     dreamcast_register_module( &maple_module );
    54     dreamcast_register_module( &ide_module );
    56     /* Attach any default maple devices, ie a pair of controllers */
    57     maple_device_t controller1 = controller_new();
    58     maple_device_t controller2 = controller_new();
    59     maple_attach_device( controller1, 0, 0 );
    60     maple_attach_device( controller2, 1, 0 );
    61 }
    63 void dreamcast_register_module( dreamcast_module_t module ) 
    64 {
    65     modules[num_modules++] = module;
    66     if( module->init != NULL )
    67 	module->init();
    68 }
    71 void dreamcast_init( void )
    72 {
    73     dreamcast_configure();
    74     dreamcast_state = STATE_STOPPED;
    75 }
    77 void dreamcast_reset( void )
    78 {
    79     int i;
    80     for( i=0; i<num_modules; i++ ) {
    81 	if( modules[i]->reset != NULL )
    82 	    modules[i]->reset();
    83     }
    84 }
    86 void dreamcast_run( void )
    87 {
    88     int i;
    89     if( dreamcast_state != STATE_RUNNING ) {
    90 	for( i=0; i<num_modules; i++ ) {
    91 	    if( modules[i]->start != NULL )
    92 		modules[i]->start();
    93 	}
    94     }
    95     dreamcast_state = STATE_RUNNING;
    96     while( dreamcast_state == STATE_RUNNING ) {
    97 	for( i=0; i<num_modules; i++ ) {
    98 	    if( modules[i]->run_time_slice != NULL )
    99 		modules[i]->run_time_slice( TIMESLICE_LENGTH );
   100 	}
   102     }
   104     for( i=0; i<num_modules; i++ ) {
   105 	if( modules[i]->stop != NULL )
   106 	    modules[i]->stop();
   107     }
   108     dreamcast_state = STATE_STOPPED;
   109     update_gui();
   110 }
   112 void dreamcast_stop( void )
   113 {
   114     if( dreamcast_state == STATE_RUNNING )
   115 	dreamcast_state = STATE_STOPPING;
   116 }
   118 int dreamcast_load_state( const gchar *filename )
   119 {
   120     int i,j;
   121     uint32_t count, len;
   122     int have_read[MAX_MODULES];
   123     char tmp[64];
   124     struct save_state_header header;
   125     FILE *f;
   127     f = fopen( filename, "r" );
   128     if( f == NULL ) return errno;
   130     fread( &header, sizeof(header), 1, f );
   131     if( strncmp( header.magic, DREAMCAST_SAVE_MAGIC, 16 ) != 0 ) {
   132 	ERROR( "Not a DreamOn save state file" );
   133 	return 1;
   134     }
   135     if( header.version != DREAMCAST_SAVE_VERSION ) {
   136 	ERROR( "DreamOn save state version not supported" );
   137 	return 1;
   138     }
   139     if( header.module_count > MAX_MODULES ) {
   140 	ERROR( "DreamOn save state is corrupted (bad module count)" );
   141 	return 1;
   142     }
   143     for( i=0; i<MAX_MODULES; i++ ) {
   144 	have_read[i] = 0;
   145     }
   147     for( i=0; i<header.module_count; i++ ) {
   148 	fread(tmp, 4, 1, f );
   149 	if( strncmp(tmp, "BLCK", 4) != 0 ) {
   150 	    ERROR( "DreamOn save state is corrupted (missing block header %d)", i );
   151 	    return 2;
   152 	}
   153 	len = fread_string(tmp, sizeof(tmp), f );
   154 	if( len > 64 || len < 1 ) {
   155 	    ERROR( "DreamOn save state is corrupted (bad string)" );
   156 	    return 2;
   157 	}
   159 	/* Find the matching module by name */
   160 	for( j=0; j<num_modules; j++ ) {
   161 	    if( strcmp(modules[j]->name,tmp) == 0 ) {
   162 		have_read[j] = 1;
   163 		if( modules[j]->load == NULL ) {
   164 		    ERROR( "DreamOn save state is corrupted (no loader for %s)", modules[j]->name );
   165 		    return 2;
   166 		} else if( modules[j]->load(f) != 0 ) {
   167 		    ERROR( "DreamOn save state is corrupted (%s failed)", modules[j]->name );
   168 		    return 2;
   169 		}
   170 		break;
   171 	    }
   172 	}
   173 	if( j == num_modules ) {
   174 	    ERROR( "DreamOn save state contains unrecognized section" );
   175 	    return 2;
   176 	}
   177     }
   179     /* Any modules that we didn't load - reset to the default state.
   180      * (ie it's not an error to skip a module if you don't actually
   181      * care about its state).
   182      */
   183     for( j=0; j<num_modules; j++ ) {
   184 	if( have_read[j] == 0 && modules[j]->reset != NULL ) {
   185 	    modules[j]->reset();
   186 	}
   187     }
   188     fclose(f);
   189     INFO( "Save state read from %s", filename );
   190 }
   192 int dreamcast_save_state( const gchar *filename )
   193 {
   194     int i;
   195     FILE *f;
   196     struct save_state_header header;
   198     f = fopen( filename, "w" );
   199     if( f == NULL )
   200 	return errno;
   201     strcpy( header.magic, DREAMCAST_SAVE_MAGIC );
   202     header.version = DREAMCAST_SAVE_VERSION;
   203     header.module_count = 0;
   205     for( i=0; i<num_modules; i++ ) {
   206 	if( modules[i]->save != NULL )
   207 	    header.module_count++;
   208     }
   209     fwrite( &header, sizeof(header), 1, f );
   210     for( i=0; i<num_modules; i++ ) {
   211 	if( modules[i]->save != NULL ) {
   212 	    fwrite( "BLCK", 4, 1, f );
   213 	    fwrite_string( modules[i]->name, f );
   214 	    modules[i]->save(f);
   215 	}
   216     }
   217     fclose( f );
   218     INFO( "Save state written to %s", filename );
   219 }
.