99// state.cpp: state saving
1010//
1111// 01/20/2009 Cleaned up interface, added loading from memory
12- // Moved signature-related stuff out of RACE_STATE (A.K.)
12+ // Moved signature-related stuff out of race_state (A.K.)
1313// 09/11/2008 Initial version (Akop Karapetyan)
1414//
1515// ////////////////////////////////////////////////////////////////////
2727#undef PC
2828#endif
2929
30- /* sizeof() tends to report a larger size, IIRC */
31- /* #define RACE_STATE_HEADER_SIZE sizeof(struct RACE_STATE_HEADER) */
32- #define RACE_STATE_HEADER_SIZE 0x41
33- struct RACE_STATE_HEADER
30+ #define CURRENT_SAVE_STATE_VERSION 0x11
31+
32+ struct race_state_header
3433{
35- u8 state_version; /* State version, currently = 0x10 */
34+ u8 state_version; /* State version */
3635 u8 rom_signature[0x40 ]; /* Rom signature, for verification */
3736};
3837
39- struct RACE_STATE
38+ struct race_state_0x11
4039{
4140 /* Memory */
4241 u8 ram[0xc000 ];
@@ -62,27 +61,64 @@ struct RACE_STATE
6261
6362 /* DMA */
6463 u8 ldcRegs[64 ];
65- };
64+ };
65+
66+ struct race_state_0x10 /* Older state format */
67+ {
68+ // Save state version
69+ u8 state_version; // = 0x10
70+
71+ // Rom signature
72+ u8 rom_signature[0x40 ];
73+
74+ // Memory
75+ u8 ram[0xc000 ];
76+ u8 cpuram[0x08a0 ];// 0xC000]; 0x38000
77+
78+ // TLCS-900h Registers
79+ u32 pc, sr;
80+ u8 f_dash;
81+ u32 gpr[23 ];
82+
83+ // Z80 Registers
84+ cz80_struc RACE_cz80_struc;
85+ u32 PC_offset;
86+ s32 Z80_ICount;
87+
88+ // Sound Chips
89+ int sndCycles;
90+ SoundChip toneChip;
91+ SoundChip noiseChip;
92+
93+ // Timers
94+ int timer0, timer1, timer2, timer3;
95+
96+ // DMA
97+ u8 ldcRegs[64 ];
98+ };
6699
67- static int state_store (struct RACE_STATE *rs);
68- static int state_restore (struct RACE_STATE *rs);
100+ typedef struct race_state_0x11 race_state_t ;
101+
102+ static int state_store (race_state_t *rs);
103+ static int state_restore (race_state_t *rs);
104+ static int state_restore_0x10 (FILE *stream);
69105
70106int state_store_mem (void *state)
71107{
72- return state_store ((struct RACE_STATE *)state);
108+ return state_store ((race_state_t *)state);
73109}
74110
75111int state_restore_mem (void *state)
76112{
77- return state_restore ((struct RACE_STATE *)state);
113+ return state_restore ((race_state_t *)state);
78114}
79115
80116int state_get_size ()
81117{
82- return sizeof (struct RACE_STATE );
118+ return sizeof (race_state_t );
83119}
84120
85- static int state_store (struct RACE_STATE *rs)
121+ static int state_store (race_state_t *rs)
86122{
87123 int i = 0 ;
88124
@@ -151,7 +187,7 @@ static int state_store(struct RACE_STATE *rs)
151187 return 1 ;
152188}
153189
154- static int state_restore (struct RACE_STATE *rs)
190+ static int state_restore (race_state_t *rs)
155191{
156192 int i = 0 ;
157193
@@ -225,20 +261,30 @@ static int state_restore(struct RACE_STATE *rs)
225261}
226262
227263int state_restore (FILE *stream)
228- {
264+ {
265+ /* Note current position (in case of compatibility rewinds */
266+ long read_pos = ftell (stream);
267+
229268 /* Read header */
230- struct RACE_STATE_HEADER rsh;
231- if (fread (&rsh, RACE_STATE_HEADER_SIZE , 1 , stream) < 1 )
269+ struct race_state_header rsh;
270+ if (fread (&rsh, sizeof (rsh) , 1 , stream) < 1 )
232271 return 0 ;
233272
234- /* Verify state version & signature */
235- if (rsh.state_version != 0x10 )
236- return 0 ;
273+ /* Verify state version */
274+ if (rsh.state_version == 0x10 )
275+ {
276+ fseek (stream, read_pos, SEEK_SET ); /* Rewind and load old format */
277+ return state_restore_0x10 (stream);
278+ }
279+ else if (rsh.state_version != CURRENT_SAVE_STATE_VERSION )
280+ return 0 ; /* Unsupported version */
281+
282+ /* Verify ROM signature */
237283 if (memcmp (mainrom, rsh.rom_signature , sizeof (rsh.rom_signature )) != 0 )
238284 return 0 ;
239285
240286 /* Read state data */
241- struct RACE_STATE rs;
287+ race_state_t rs;
242288 if (fread (&rs, sizeof (rs), 1 , stream) < 1 )
243289 return 0 ;
244290
@@ -249,17 +295,17 @@ int state_restore(FILE *stream)
249295int state_store (FILE *stream)
250296{
251297 /* Set version & ROM signature information */
252- struct RACE_STATE_HEADER rsh;
253- rsh.state_version = 0x10 ;
298+ struct race_state_header rsh;
299+ rsh.state_version = CURRENT_SAVE_STATE_VERSION ;
254300 memcpy (rsh.rom_signature , mainrom, sizeof (rsh.rom_signature ));
255301
256302 /* Initialize state data */
257- struct RACE_STATE rs;
303+ race_state_t rs;
258304 if (!state_store (&rs))
259305 return 0 ;
260306
261307 /* Write to file */
262- if (fwrite (&rsh, RACE_STATE_HEADER_SIZE , 1 , stream) < 1 )
308+ if (fwrite (&rsh, sizeof (rsh) , 1 , stream) < 1 )
263309 return 0 ;
264310 if (fwrite (&rs, sizeof (rs), 1 , stream) < 1 )
265311 return 0 ;
@@ -277,7 +323,8 @@ int state_store(char* filename)
277323 fclose (stream);
278324
279325 return status;
280- }
326+ }
327+
281328int state_restore (char * filename)
282329{
283330 FILE *stream;
@@ -290,3 +337,85 @@ int state_restore(char* filename)
290337 return status;
291338}
292339
340+ static int state_restore_0x10 (FILE *stream)
341+ {
342+ struct race_state_0x10 rs;
343+ if (fread (&rs, sizeof (rs), 1 , stream) < 1 )
344+ return 0 ;
345+
346+ // Verify state version
347+ if (rs.state_version != 0x10 )
348+ return 0 ;
349+
350+ // Verify ROM signature
351+ if (memcmp (mainrom, rs.rom_signature , sizeof (rs.rom_signature )) != 0 )
352+ return 0 ;
353+
354+ // TLCS-900h Registers
355+ gen_regsPC = rs.pc ;
356+ gen_regsSR = rs.sr ;
357+ F2 = rs.f_dash ;
358+
359+ int i = 0 ;
360+ gen_regsXWA0 = rs.gpr [i++];
361+ gen_regsXBC0 = rs.gpr [i++];
362+ gen_regsXDE0 = rs.gpr [i++];
363+ gen_regsXHL0 = rs.gpr [i++];
364+
365+ gen_regsXWA1 = rs.gpr [i++];
366+ gen_regsXBC1 = rs.gpr [i++];
367+ gen_regsXDE1 = rs.gpr [i++];
368+ gen_regsXHL1 = rs.gpr [i++];
369+
370+ gen_regsXWA2 = rs.gpr [i++];
371+ gen_regsXBC2 = rs.gpr [i++];
372+ gen_regsXDE2 = rs.gpr [i++];
373+ gen_regsXHL2 = rs.gpr [i++];
374+
375+ gen_regsXWA3 = rs.gpr [i++];
376+ gen_regsXBC3 = rs.gpr [i++];
377+ gen_regsXDE3 = rs.gpr [i++];
378+ gen_regsXHL3 = rs.gpr [i++];
379+
380+ gen_regsXIX = rs.gpr [i++];
381+ gen_regsXIY = rs.gpr [i++];
382+ gen_regsXIZ = rs.gpr [i++];
383+ gen_regsXSP = rs.gpr [i++];
384+
385+ gen_regsSP = rs.gpr [i++];
386+ gen_regsXSSP = rs.gpr [i++];
387+ gen_regsXNSP = rs.gpr [i++];
388+
389+ // Z80 Registers
390+ extern cz80_struc *RACE_cz80_struc;
391+ extern s32 Z80_ICount;
392+ int size_of_z80 =
393+ (u32 )(&(RACE_cz80_struc->CycleSup )) - (u32 )(&(RACE_cz80_struc->BC ));
394+
395+ memcpy (RACE_cz80_struc, &rs.RACE_cz80_struc , size_of_z80);
396+ Z80_ICount = rs.Z80_ICount ;
397+ Cz80_Set_PC (RACE_cz80_struc, rs.PC_offset );
398+
399+ // Sound Chips
400+ extern int sndCycles;
401+ sndCycles = rs.sndCycles ;
402+ memcpy (&toneChip, &rs.toneChip , sizeof (SoundChip));
403+ memcpy (&noiseChip, &rs.noiseChip , sizeof (SoundChip));
404+
405+ // Timers
406+ timer0 = rs.timer0 ;
407+ timer1 = rs.timer1 ;
408+ timer2 = rs.timer2 ;
409+ timer3 = rs.timer3 ;
410+
411+ // DMA
412+ memcpy (&ldcRegs, &rs.ldcRegs , sizeof (ldcRegs));
413+
414+ // Memory
415+ memcpy (mainram, rs.ram , sizeof (rs.ram ));
416+ memcpy (&mainram[0x20000 ], rs.cpuram , sizeof (rs.cpuram ));
417+
418+ tlcs_reinit ();
419+
420+ return 1 ;
421+ }
0 commit comments