1 /*
2 * UAE - The Un*x Amiga Emulator
3 *
4 * Save/restore emulator state
5 *
6 * (c) 1999-2001 Toni Wilen
7 *
8 * see below for ASF-structure
9 */
10
11 /* Features:
12 *
13 * - full CPU state (68000/68010/68020/68030/68040/68060)
14 * - FPU (68881/68882/68040/68060)
15 * - full CIA-A and CIA-B state (with all internal registers)
16 * - saves all custom registers and audio internal state.
17 * - Chip, Bogo, Fast, Z3 and Picasso96 RAM supported
18 * - disk drive type, imagefile, track and motor state
19 * - Kickstart ROM version, address and size is saved. This data is not used during restore yet.
20 * - Action Replay state is saved
21 */
22
23 /* Notes:
24 *
25 * - blitter state is not saved, blitter is forced to finish immediately if it
26 * was active
27 * - disk DMA state is completely saved
28 * - does not ask for statefile name and description. Currently uses DF0's disk
29 * image name (".adf" is replaced with ".asf")
30 * - only Amiga state is restored, harddisk support, autoconfig, expansion boards etc..
31 * are not saved/restored (and probably never will).
32 * - use this for saving games that can't be saved to disk
33 */
34
35 /* Usage :
36 *
37 * save:
38 *
39 * set savestate_state = STATE_DOSAVE, savestate_filename = "..."
40 *
41 * restore:
42 *
43 * set savestate_state = STATE_DORESTORE, savestate_filename = "..."
44 *
45 */
46
47 #define OPEN_LOG 0
48
49 #include "sysconfig.h"
50 #include "sysdeps.h"
51
52 #include "options.h"
53 #include "uae/memory.h"
54 #include "zfile.h"
55 #include "ar.h"
56 #include "autoconf.h"
57 #include "custom.h"
58 #include "newcpu.h"
59 #include "savestate.h"
60 #include "uae.h"
61 #include "gui.h"
62 #include "audio.h"
63 #include "filesys.h"
64 #include "inputrecord.h"
65 #include "disk.h"
66 #include "threaddep/thread.h"
67 #include "a2091.h"
68 #include "devices.h"
69
70 #ifdef FSUAE // NL
71 #include "uae/fs.h"
72 #endif
73
74 int savestate_state = 0;
75
76 #ifdef SAVESTATE
77
78 static int savestate_first_capture;
79
80 static bool new_blitter = false;
81
82 static int replaycounter;
83
84 struct zfile *savestate_file;
85 static int savestate_docompress, savestate_specialdump, savestate_nodialogs;
86
87 TCHAR savestate_fname[MAX_DPATH];
88
89 #define STATEFILE_ALLOC_SIZE 600000
90 static int statefile_alloc;
91 static int staterecords_max = 1000;
92 static int staterecords_first = 0;
93 static struct zfile *staterecord_statefile;
94 struct staterecord
95 {
96 int len;
97 int inuse;
98 uae_u8 *cpu;
99 uae_u8 *data;
100 uae_u8 *end;
101 int inprecoffset;
102 };
103
104 static struct staterecord **staterecords;
105
state_incompatible_warn(void)106 static void state_incompatible_warn (void)
107 {
108 static int warned;
109 int dowarn = 0;
110 int i;
111
112 #ifdef BSDSOCKET
113 if (currprefs.socket_emu)
114 dowarn = 1;
115 #endif
116 #ifdef UAESERIAL
117 if (currprefs.uaeserial)
118 dowarn = 1;
119 #endif
120 #ifdef SCSIEMU
121 if (currprefs.scsi)
122 dowarn = 1;
123 #endif
124 #ifdef CATWEASEL
125 if (currprefs.catweasel)
126 dowarn = 1;
127 #endif
128 #ifdef FILESYS
129 for(i = 0; i < currprefs.mountitems; i++) {
130 struct mountedinfo mi;
131 int type = get_filesys_unitconfig (&currprefs, i, &mi);
132 if (mi.ismounted && type != FILESYS_VIRTUAL && type != FILESYS_HARDFILE && type != FILESYS_HARDFILE_RDB)
133 dowarn = 1;
134 }
135 #endif
136 if (!warned && dowarn) {
137 warned = 1;
138 notify_user (NUMSG_STATEHD);
139 }
140 }
141
142 #endif
143
144 /* functions for reading/writing bytes, shorts and longs in big-endian
145 * format independent of host machine's endianess */
146
147 static uae_u8 *storepos;
save_store_pos_func(uae_u8 ** dstp)148 void save_store_pos_func (uae_u8 **dstp)
149 {
150 storepos = *dstp;
151 *dstp += 4;
152 }
save_store_size_func(uae_u8 ** dstp)153 void save_store_size_func (uae_u8 **dstp)
154 {
155 uae_u8 *p = storepos;
156 save_u32_func (&p, *dstp - storepos);
157 }
restore_store_pos_func(uae_u8 ** srcp)158 void restore_store_pos_func (uae_u8 **srcp)
159 {
160 storepos = *srcp;
161 *srcp += 4;
162 }
restore_store_size_func(uae_u8 ** srcp)163 void restore_store_size_func (uae_u8 **srcp)
164 {
165 uae_u8 *p = storepos;
166 uae_u32 len = restore_u32_func (&p);
167 *srcp = storepos + len;
168 }
169
save_u32_func(uae_u8 ** dstp,uae_u32 v)170 void save_u32_func (uae_u8 **dstp, uae_u32 v)
171 {
172 uae_u8 *dst = *dstp;
173 *dst++ = (uae_u8)(v >> 24);
174 *dst++ = (uae_u8)(v >> 16);
175 *dst++ = (uae_u8)(v >> 8);
176 *dst++ = (uae_u8)(v >> 0);
177 *dstp = dst;
178 }
save_u64_func(uae_u8 ** dstp,uae_u64 v)179 void save_u64_func (uae_u8 **dstp, uae_u64 v)
180 {
181 save_u32_func (dstp, (uae_u32)(v >> 32));
182 save_u32_func (dstp, (uae_u32)v);
183 }
save_u16_func(uae_u8 ** dstp,uae_u16 v)184 void save_u16_func (uae_u8 **dstp, uae_u16 v)
185 {
186 uae_u8 *dst = *dstp;
187 *dst++ = (uae_u8)(v >> 8);
188 *dst++ = (uae_u8)(v >> 0);
189 *dstp = dst;
190 }
save_u8_func(uae_u8 ** dstp,uae_u8 v)191 void save_u8_func (uae_u8 **dstp, uae_u8 v)
192 {
193 uae_u8 *dst = *dstp;
194 *dst++ = v;
195 *dstp = dst;
196 }
save_string_func(uae_u8 ** dstp,const TCHAR * from)197 void save_string_func (uae_u8 **dstp, const TCHAR *from)
198 {
199 uae_u8 *dst = *dstp;
200 char *s, *s2;
201 s2 = s = uutf8 (from);
202 while (s && *s)
203 *dst++ = *s++;
204 *dst++ = 0;
205 *dstp = dst;
206 xfree (s2);
207 }
save_path_func(uae_u8 ** dstp,const TCHAR * from,int type)208 void save_path_func (uae_u8 **dstp, const TCHAR *from, int type)
209 {
210 save_string_func (dstp, from);
211 }
212
restore_u32_func(uae_u8 ** dstp)213 uae_u32 restore_u32_func (uae_u8 **dstp)
214 {
215 uae_u32 v;
216 uae_u8 *dst = *dstp;
217 v = (dst[0] << 24) | (dst[1] << 16) | (dst[2] << 8) | (dst[3]);
218 *dstp = dst + 4;
219 return v;
220 }
restore_u64_func(uae_u8 ** dstp)221 uae_u64 restore_u64_func (uae_u8 **dstp)
222 {
223 uae_u64 v;
224
225 v = restore_u32_func (dstp);
226 v <<= 32;
227 v |= restore_u32_func (dstp);
228 return v;
229 }
restore_u16_func(uae_u8 ** dstp)230 uae_u16 restore_u16_func (uae_u8 **dstp)
231 {
232 uae_u16 v;
233 uae_u8 *dst = *dstp;
234 v=(dst[0] << 8) | (dst[1]);
235 *dstp = dst + 2;
236 return v;
237 }
restore_u8_func(uae_u8 ** dstp)238 uae_u8 restore_u8_func (uae_u8 **dstp)
239 {
240 uae_u8 v;
241 uae_u8 *dst = *dstp;
242 v = dst[0];
243 *dstp = dst + 1;
244 return v;
245 }
restore_string_func(uae_u8 ** dstp)246 TCHAR *restore_string_func (uae_u8 **dstp)
247 {
248 int len;
249 uae_u8 v;
250 uae_u8 *dst = *dstp;
251 char *top, *to;
252 TCHAR *s;
253
254 len = strlen ((char*)dst) + 1;
255 top = to = xmalloc (char, len);
256 do {
257 v = *dst++;
258 *top++ = v;
259 } while (v);
260 *dstp = dst;
261 s = utf8u (to);
262 xfree (to);
263 return s;
264 }
265
266 #ifdef SAVESTATE
267
restore_path_func(uae_u8 ** dstp,int type)268 TCHAR *restore_path_func (uae_u8 **dstp, int type)
269 {
270 TCHAR *newpath;
271 TCHAR *s;
272 TCHAR tmp[MAX_DPATH], tmp2[MAX_DPATH];
273
274 s = restore_string_func (dstp);
275 if (s[0] == 0)
276 return s;
277 if (zfile_exists (s))
278 return s;
279 if (type == SAVESTATE_PATH_HD)
280 return s;
281 getfilepart (tmp, sizeof tmp / sizeof (TCHAR), s);
282 if (zfile_exists (tmp)) {
283 xfree (s);
284 return my_strdup (tmp);
285 }
286 for (int i = 0; i < MAX_PATHS; i++) {
287 newpath = NULL;
288 if (type == SAVESTATE_PATH_FLOPPY)
289 newpath = currprefs.path_floppy.path[i];
290 else if (type == SAVESTATE_PATH_VDIR || type == SAVESTATE_PATH_HDF)
291 newpath = currprefs.path_hardfile.path[i];
292 else if (type == SAVESTATE_PATH_CD)
293 newpath = currprefs.path_cd.path[i];
294 if (newpath == NULL || newpath[0] == 0)
295 break;
296 _tcscpy (tmp2, newpath);
297 fixtrailing (tmp2);
298 _tcscat (tmp2, tmp);
299 fullpath (tmp2, sizeof tmp2 / sizeof (TCHAR));
300 if (zfile_exists (tmp2)) {
301 xfree (s);
302 return my_strdup (tmp2);
303 }
304 }
305 getpathpart (tmp2, sizeof tmp2 / sizeof (TCHAR), savestate_fname);
306 _tcscat (tmp2, tmp);
307 if (zfile_exists (tmp2)) {
308 xfree (s);
309 return my_strdup (tmp2);
310 }
311 return s;
312 }
313
314 /* read and write IFF-style hunks */
315
save_chunk(struct zfile * f,uae_u8 * chunk,unsigned int len,const TCHAR * name,int compress)316 static void save_chunk (struct zfile *f, uae_u8 *chunk, unsigned int len, const TCHAR *name, int compress)
317 {
318 uae_u8 tmp[8], *dst;
319 uae_u8 zero[4]= { 0, 0, 0, 0 };
320 uae_u32 flags;
321 unsigned int pos;
322 unsigned int chunklen, len2;
323 char *s;
324
325 if (!chunk)
326 return;
327
328 if (compress < 0) {
329 zfile_fwrite (chunk, 1, len, f);
330 return;
331 }
332
333 /* chunk name */
334 s = ua (name);
335 zfile_fwrite (s, 1, 4, f);
336 xfree (s);
337 pos = zfile_ftell (f);
338 /* chunk size */
339 dst = &tmp[0];
340 chunklen = len + 4 + 4 + 4;
341 save_u32 (chunklen);
342 zfile_fwrite (&tmp[0], 1, 4, f);
343 /* chunk flags */
344 flags = 0;
345 dst = &tmp[0];
346 save_u32 (flags | compress);
347 zfile_fwrite (&tmp[0], 1, 4, f);
348 /* chunk data */
349 if (compress) {
350 int tmplen = len;
351 size_t opos;
352 dst = &tmp[0];
353 save_u32 (len);
354 opos = zfile_ftell (f);
355 zfile_fwrite (&tmp[0], 1, 4, f);
356 len = zfile_zcompress (f, chunk, len);
357 if (len > 0) {
358 zfile_fseek (f, pos, SEEK_SET);
359 dst = &tmp[0];
360 save_u32 (len + 4 + 4 + 4 + 4);
361 zfile_fwrite (&tmp[0], 1, 4, f);
362 zfile_fseek (f, 0, SEEK_END);
363 } else {
364 len = tmplen;
365 compress = 0;
366 zfile_fseek (f, opos, SEEK_SET);
367 dst = &tmp[0];
368 save_u32 (flags);
369 zfile_fwrite (&tmp[0], 1, 4, f);
370 }
371 }
372 if (!compress)
373 zfile_fwrite (chunk, 1, len, f);
374 /* alignment */
375 len2 = 4 - (len & 3);
376 if (len2)
377 zfile_fwrite (zero, 1, len2, f);
378
379 write_log (_T("Chunk '%s' chunk size %u (%u)\n"), name, chunklen, len);
380 }
381
restore_chunk(struct zfile * f,TCHAR * name,unsigned int * len,unsigned int * totallen,size_t * filepos)382 static uae_u8 *restore_chunk (struct zfile *f, TCHAR *name, unsigned int *len, unsigned int *totallen, size_t *filepos)
383 {
384 uae_u8 tmp[6], dummy[4], *mem, *src;
385 uae_u32 flags;
386 int len2;
387
388 *totallen = 0;
389 /* chunk name */
390 zfile_fread (tmp, 1, 4, f);
391 tmp[4] = 0;
392 au_copy (name, 5, (char*)tmp);
393 /* chunk size */
394 zfile_fread (tmp, 1, 4, f);
395 src = tmp;
396 len2 = restore_u32 () - 4 - 4 - 4;
397 if (len2 < 0)
398 len2 = 0;
399 *len = len2;
400 if (len2 == 0) {
401 *filepos = zfile_ftell (f);
402 return 0;
403 }
404
405 /* chunk flags */
406 zfile_fread (tmp, 1, 4, f);
407 src = tmp;
408 flags = restore_u32 ();
409 *totallen = *len;
410 if (flags & 1) {
411 zfile_fread (tmp, 1, 4, f);
412 src = tmp;
413 *totallen = restore_u32 ();
414 *filepos = zfile_ftell (f) - 4 - 4 - 4;
415 len2 -= 4;
416 } else {
417 *filepos = zfile_ftell (f) - 4 - 4;
418 }
419 /* chunk data. RAM contents will be loaded during the reset phase,
420 no need to malloc multiple megabytes here. */
421 if (_tcscmp (name, _T("CRAM")) != 0
422 && _tcscmp (name, _T("BRAM")) != 0
423 && _tcscmp (name, _T("FRAM")) != 0
424 && _tcscmp (name, _T("ZRAM")) != 0
425 && _tcscmp (name, _T("ZCRM")) != 0
426 && _tcscmp (name, _T("PRAM")) != 0
427 && _tcscmp (name, _T("A3K1")) != 0
428 && _tcscmp (name, _T("A3K2")) != 0
429 && _tcscmp (name, _T("BORO")) != 0
430 )
431 {
432 /* extra bytes at the end needed to handle old statefiles that now have new fields */
433 mem = xcalloc (uae_u8, *totallen + 100);
434 if (!mem)
435 return NULL;
436 if (flags & 1) {
437 zfile_zuncompress (mem, *totallen, f, len2);
438 } else {
439 zfile_fread (mem, 1, len2, f);
440 }
441 } else {
442 mem = 0;
443 zfile_fseek (f, len2, SEEK_CUR);
444 }
445
446 /* alignment */
447 len2 = 4 - (len2 & 3);
448 if (len2)
449 zfile_fread (dummy, 1, len2, f);
450 return mem;
451 }
452
restore_ram(size_t filepos,uae_u8 * memory)453 void restore_ram (size_t filepos, uae_u8 *memory)
454 {
455 uae_u8 tmp[8];
456 uae_u8 *src = tmp;
457 int size, fullsize;
458 uae_u32 flags;
459
460 if (filepos == 0 || memory == NULL)
461 return;
462 zfile_fseek (savestate_file, filepos, SEEK_SET);
463 zfile_fread (tmp, 1, sizeof tmp, savestate_file);
464 size = restore_u32 ();
465 flags = restore_u32 ();
466 size -= 4 + 4 + 4;
467 if (flags & 1) {
468 zfile_fread (tmp, 1, 4, savestate_file);
469 src = tmp;
470 fullsize = restore_u32 ();
471 size -= 4;
472 zfile_zuncompress (memory, fullsize, savestate_file, size);
473 } else {
474 zfile_fread (memory, 1, size, savestate_file);
475 }
476 }
477
restore_log(uae_u8 * src)478 static uae_u8 *restore_log (uae_u8 *src)
479 {
480 #if OPEN_LOG > 0
481 TCHAR *s = utf8u (src);
482 write_log (_T("%s\n"), s);
483 xfree (s);
484 #endif
485 src += strlen ((char*)src) + 1;
486 return src;
487 }
488
restore_header(uae_u8 * src)489 static void restore_header (uae_u8 *src)
490 {
491 TCHAR *emuname, *emuversion, *description;
492
493 restore_u32 ();
494 emuname = restore_string ();
495 emuversion = restore_string ();
496 description = restore_string ();
497 write_log (_T("Saved with: '%s %s', description: '%s'\n"),
498 emuname, emuversion, description);
499 xfree (description);
500 xfree (emuversion);
501 xfree (emuname);
502 }
503
504 /* restore all subsystems */
505
restore_state(const TCHAR * filename)506 void restore_state (const TCHAR *filename)
507 {
508 #ifdef FSUAE
509 printf("restore_state from %s\n", filename);
510 #endif
511 struct zfile *f;
512 uae_u8 *chunk,*end;
513 TCHAR name[5];
514 unsigned int len, totallen;
515 size_t filepos, filesize;
516 int z3num;
517
518 chunk = 0;
519 f = zfile_fopen (filename, _T("rb"), ZFD_NORMAL);
520 if (!f)
521 goto error;
522 zfile_fseek (f, 0, SEEK_END);
523 filesize = zfile_ftell (f);
524 zfile_fseek (f, 0, SEEK_SET);
525 savestate_state = STATE_RESTORE;
526 savestate_init ();
527
528 chunk = restore_chunk (f, name, &len, &totallen, &filepos);
529 if (!chunk || _tcsncmp (name, _T("ASF "), 4)) {
530 write_log (_T("%s is not an AmigaStateFile\n"), filename);
531 goto error;
532 }
533 write_log (_T("STATERESTORE: '%s'\n"), filename);
534 set_config_changed ();
535 savestate_file = f;
536 restore_header (chunk);
537 xfree (chunk);
538 devices_restore_start();
539 z3num = 0;
540 for (;;) {
541 name[0] = 0;
542 chunk = end = restore_chunk (f, name, &len, &totallen, &filepos);
543 write_log (_T("Chunk '%s' size %u (%u)\n"), name, len, totallen);
544 if (!_tcscmp (name, _T("END "))) {
545 #ifdef _DEBUG
546 if (filesize > filepos + 8)
547 continue;
548 #endif
549 break;
550 }
551 if (!_tcscmp (name, _T("CRAM"))) {
552 restore_cram (totallen, filepos);
553 continue;
554 } else if (!_tcscmp (name, _T("BRAM"))) {
555 restore_bram (totallen, filepos);
556 continue;
557 } else if (!_tcscmp (name, _T("A3K1"))) {
558 restore_a3000lram (totallen, filepos);
559 continue;
560 } else if (!_tcscmp (name, _T("A3K2"))) {
561 restore_a3000hram (totallen, filepos);
562 continue;
563 #ifdef AUTOCONFIG
564 } else if (!_tcscmp (name, _T("FRAM"))) {
565 restore_fram (totallen, filepos, 0);
566 continue;
567 } else if (!_tcscmp (name, _T("FRA2"))) {
568 restore_fram (totallen, filepos, 1);
569 continue;
570 } else if (!_tcscmp (name, _T("ZRAM"))) {
571 restore_zram (totallen, filepos, z3num++);
572 continue;
573 } else if (!_tcscmp (name, _T("ZCRM"))) {
574 restore_zram (totallen, filepos, -1);
575 continue;
576 } else if (!_tcscmp (name, _T("BORO"))) {
577 restore_bootrom (totallen, filepos);
578 continue;
579 #endif
580 #ifdef PICASSO96
581 } else if (!_tcscmp (name, _T("PRAM"))) {
582 restore_pram (totallen, filepos);
583 continue;
584 #endif
585 } else if (!_tcscmp (name, _T("CYCS"))) {
586 end = restore_cycles (chunk);
587 } else if (!_tcscmp (name, _T("CPU "))) {
588 end = restore_cpu (chunk);
589 } else if (!_tcscmp (name, _T("CPUX")))
590 end = restore_cpu_extra (chunk);
591 else if (!_tcscmp (name, _T("CPUT")))
592 end = restore_cpu_trace (chunk);
593 #ifdef FPUEMU
594 else if (!_tcscmp (name, _T("FPU ")))
595 end = restore_fpu (chunk);
596 #endif
597 #ifdef MMUEMU
598 else if (!_tcscmp (name, _T("MMU ")))
599 end = restore_mmu (chunk);
600 #endif
601 else if (!_tcscmp (name, _T("AGAC")))
602 end = restore_custom_agacolors (chunk);
603 else if (!_tcscmp (name, _T("SPR0")))
604 end = restore_custom_sprite (0, chunk);
605 else if (!_tcscmp (name, _T("SPR1")))
606 end = restore_custom_sprite (1, chunk);
607 else if (!_tcscmp (name, _T("SPR2")))
608 end = restore_custom_sprite (2, chunk);
609 else if (!_tcscmp (name, _T("SPR3")))
610 end = restore_custom_sprite (3, chunk);
611 else if (!_tcscmp (name, _T("SPR4")))
612 end = restore_custom_sprite (4, chunk);
613 else if (!_tcscmp (name, _T("SPR5")))
614 end = restore_custom_sprite (5, chunk);
615 else if (!_tcscmp (name, _T("SPR6")))
616 end = restore_custom_sprite (6, chunk);
617 else if (!_tcscmp (name, _T("SPR7")))
618 end = restore_custom_sprite (7, chunk);
619 else if (!_tcscmp (name, _T("CIAA")))
620 end = restore_cia (0, chunk);
621 else if (!_tcscmp (name, _T("CIAB")))
622 end = restore_cia (1, chunk);
623 else if (!_tcscmp (name, _T("CHIP")))
624 end = restore_custom (chunk);
625 else if (!_tcscmp (name, _T("CINP")))
626 end = restore_input (chunk);
627 else if (!_tcscmp (name, _T("CHPX")))
628 end = restore_custom_extra (chunk);
629 else if (!_tcscmp (name, _T("CHPD")))
630 end = restore_custom_event_delay (chunk);
631 else if (!_tcscmp (name, _T("AUD0")))
632 end = restore_audio (0, chunk);
633 else if (!_tcscmp (name, _T("AUD1")))
634 end = restore_audio (1, chunk);
635 else if (!_tcscmp (name, _T("AUD2")))
636 end = restore_audio (2, chunk);
637 else if (!_tcscmp (name, _T("AUD3")))
638 end = restore_audio (3, chunk);
639 else if (!_tcscmp (name, _T("BLIT")))
640 end = restore_blitter (chunk);
641 else if (!_tcscmp (name, _T("BLTX")))
642 end = restore_blitter_new (chunk);
643 else if (!_tcscmp (name, _T("DISK")))
644 end = restore_floppy (chunk);
645 else if (!_tcscmp (name, _T("DSK0")))
646 end = restore_disk (0, chunk);
647 else if (!_tcscmp (name, _T("DSK1")))
648 end = restore_disk (1, chunk);
649 else if (!_tcscmp (name, _T("DSK2")))
650 end = restore_disk (2, chunk);
651 else if (!_tcscmp (name, _T("DSK3")))
652 end = restore_disk (3, chunk);
653 else if (!_tcscmp (name, _T("DSD0")))
654 end = restore_disk2 (0, chunk);
655 else if (!_tcscmp (name, _T("DSD1")))
656 end = restore_disk2 (1, chunk);
657 else if (!_tcscmp (name, _T("DSD2")))
658 end = restore_disk2 (2, chunk);
659 else if (!_tcscmp (name, _T("DSD3")))
660 end = restore_disk2 (3, chunk);
661 else if (!_tcscmp (name, _T("KEYB")))
662 end = restore_keyboard (chunk);
663 #ifdef AUTOCONFIG
664 else if (!_tcscmp (name, _T("EXPA")))
665 end = restore_expansion (chunk);
666 #endif
667 else if (!_tcscmp (name, _T("ROM ")))
668 end = restore_rom (chunk);
669 #ifdef PICASSO96
670 else if (!_tcscmp (name, _T("P96 ")))
671 end = restore_p96 (chunk);
672 #endif
673 #ifdef ACTION_REPLAY
674 else if (!_tcscmp (name, _T("ACTR")))
675 end = restore_action_replay (chunk);
676 else if (!_tcscmp (name, _T("HRTM")))
677 end = restore_hrtmon (chunk);
678 #endif
679 #ifdef FILESYS
680 else if (!_tcscmp (name, _T("FSYS")))
681 end = restore_filesys (chunk);
682 else if (!_tcscmp (name, _T("FSYC")))
683 end = restore_filesys_common (chunk);
684 #endif
685 #ifdef CD32
686 else if (!_tcscmp (name, _T("CD32")))
687 end = restore_akiko (chunk);
688 #endif
689 #ifdef CDTV
690 else if (!_tcscmp (name, _T("CDTV")))
691 end = restore_cdtv (chunk);
692 #if 0
693 else if (!_tcscmp (name, _T("DMAC")))
694 end = restore_cdtv_dmac (chunk);
695 #endif
696 #endif
697 #if 0
698 else if (!_tcscmp (name, _T("DMC2")))
699 end = restore_scsi_dmac (WDTYPE_A3000, chunk);
700 else if (!_tcscmp (name, _T("DMC3")))
701 end = restore_scsi_dmac (WDTYPE_A2091, chunk);
702 else if (!_tcscmp (name, _T("DMC3")))
703 end = restore_scsi_dmac (WDTYPE_A2091_2, chunk);
704 else if (!_tcscmp (name, _T("SCS2")))
705 end = restore_scsi_device (WDTYPE_A3000, chunk);
706 else if (!_tcscmp (name, _T("SCS3")))
707 end = restore_scsi_device (WDTYPE_A2091, chunk);
708 else if (!_tcscmp (name, _T("SCS4")))
709 end = restore_scsi_device (WDTYPE_A2091_2, chunk);
710 #endif
711 #ifdef SCSIEMU
712 else if (!_tcscmp (name, _T("SCSD")))
713 end = restore_scsidev (chunk);
714 #endif
715 else if (!_tcscmp (name, _T("GAYL")))
716 end = restore_gayle (chunk);
717 else if (!_tcscmp (name, _T("IDE ")))
718 end = restore_gayle_ide (chunk);
719 else if (!_tcsncmp (name, _T("CDU"), 3))
720 end = restore_cd (name[3] - '0', chunk);
721 #ifdef A2065
722 else if (!_tcsncmp (name, _T("2065"), 4))
723 end = restore_a2065 (chunk);
724 #endif
725 else if (!_tcsncmp (name, _T("DMWP"), 4))
726 end = restore_debug_memwatch (chunk);
727
728 else if (!_tcscmp (name, _T("CONF")))
729 end = restore_configuration (chunk);
730 else if (!_tcscmp (name, _T("LOG ")))
731 end = restore_log (chunk);
732 else {
733 end = chunk + len;
734 write_log (_T("unknown chunk '%s' size %d bytes\n"), name, len);
735 }
736 if (end == NULL)
737 write_log (_T("Chunk '%s', size %d bytes was not accepted!\n"),
738 name, len);
739 else if (totallen != end - chunk)
740 write_log (_T("Chunk '%s' total size %d bytes but read %ld bytes!\n"),
741 name, totallen, end - chunk);
742 xfree (chunk);
743 }
744 target_addtorecent (filename, 0);
745 return;
746
747 error:
748 savestate_state = 0;
749 savestate_file = 0;
750 if (chunk)
751 xfree (chunk);
752 if (f)
753 zfile_fclose (f);
754 }
755
savestate_restore_finish(void)756 void savestate_restore_finish (void)
757 {
758 if (!isrestore ())
759 return;
760 #ifdef FSUAE
761 printf("savestate_restore_finish\n");
762 #endif
763 zfile_fclose (savestate_file);
764 savestate_file = 0;
765 restore_cpu_finish ();
766 restore_audio_finish ();
767 restore_disk_finish ();
768 restore_blitter_finish ();
769 #ifdef CD32
770 restore_akiko_finish ();
771 #endif
772 #ifdef CDTV
773 restore_cdtv_finish ();
774 #endif
775 #ifdef PICASSO96
776 restore_p96_finish ();
777 #endif
778 #ifdef A2065
779 restore_a2065_finish ();
780 #endif
781 restore_cia_finish ();
782 restore_debug_memwatch_finish ();
783 savestate_state = 0;
784 init_hz_normal();
785 audio_activate();
786 #ifdef FSUAE
787 uae_callback(uae_on_restore_state_finished, savestate_fname);
788 #endif
789 }
790
791 /* 1=compressed,2=not compressed,3=ram dump,4=audio dump */
savestate_initsave(const TCHAR * filename,int mode,int nodialogs,bool save)792 void savestate_initsave (const TCHAR *filename, int mode, int nodialogs, bool save)
793 {
794 if (filename == NULL) {
795 savestate_fname[0] = 0;
796 savestate_docompress = 0;
797 savestate_specialdump = 0;
798 savestate_nodialogs = 0;
799 return;
800 }
801 _tcscpy (savestate_fname, filename);
802 savestate_docompress = (mode == 1) ? 1 : 0;
803 savestate_specialdump = (mode == 3) ? 1 : (mode == 4) ? 2 : 0;
804 savestate_nodialogs = nodialogs;
805 new_blitter = false;
806 if (save) {
807 savestate_free ();
808 inprec_close (true);
809 }
810 }
811
save_rams(struct zfile * f,int comp)812 static void save_rams (struct zfile *f, int comp)
813 {
814 uae_u8 *dst;
815 int len;
816
817 dst = save_cram (&len);
818 save_chunk (f, dst, len, _T("CRAM"), comp);
819 dst = save_bram (&len);
820 save_chunk (f, dst, len, _T("BRAM"), comp);
821 dst = save_a3000lram (&len);
822 save_chunk (f, dst, len, _T("A3K1"), comp);
823 dst = save_a3000hram (&len);
824 save_chunk (f, dst, len, _T("A3K2"), comp);
825 #ifdef AUTOCONFIG
826 dst = save_fram (&len, 0);
827 save_chunk (f, dst, len, _T("FRAM"), comp);
828 dst = save_fram (&len, 1);
829 save_chunk (f, dst, len, _T("FRA2"), comp);
830 dst = save_zram (&len, 0);
831 save_chunk (f, dst, len, _T("ZRAM"), comp);
832 dst = save_zram (&len, 1);
833 save_chunk (f, dst, len, _T("ZRAM"), comp);
834 dst = save_zram (&len, -1);
835 save_chunk (f, dst, len, _T("ZCRM"), comp);
836 dst = save_bootrom (&len);
837 save_chunk (f, dst, len, _T("BORO"), comp);
838 #endif
839 #ifdef PICASSO96
840 dst = save_pram (&len);
841 save_chunk (f, dst, len, _T("PRAM"), comp);
842 #endif
843 }
844
845 /* Save all subsystems */
846
save_state_internal(struct zfile * f,const TCHAR * description,int comp,bool savepath)847 static int save_state_internal (struct zfile *f, const TCHAR *description, int comp, bool savepath)
848 {
849 uae_u8 endhunk[] = { 'E', 'N', 'D', ' ', 0, 0, 0, 8 };
850 uae_u8 header[1000];
851 TCHAR tmp[100];
852 uae_u8 *dst;
853 TCHAR name[5];
854 int i, len;
855
856 write_log (_T("STATESAVE (%s):\n"), f ? zfile_getname (f) : _T("<internal>"));
857 dst = header;
858 save_u32 (0);
859 save_string (_T("UAE"));
860 _stprintf (tmp, _T("%d.%d.%d"), UAEMAJOR, UAEMINOR, UAESUBREV);
861 save_string (tmp);
862 save_string (description);
863 save_chunk (f, header, dst-header, _T("ASF "), 0);
864
865 dst = save_cycles (&len, 0);
866 save_chunk (f, dst, len, _T("CYCS"), 0);
867 xfree (dst);
868
869 dst = save_cpu (&len, 0);
870 save_chunk (f, dst, len, _T("CPU "), 0);
871 xfree (dst);
872
873 dst = save_cpu_extra (&len, 0);
874 save_chunk (f, dst, len, _T("CPUX"), 0);
875 xfree (dst);
876
877 dst = save_cpu_trace (&len, 0);
878 save_chunk (f, dst, len, _T("CPUT"), 0);
879 xfree (dst);
880
881 #ifdef FPUEMU
882 dst = save_fpu (&len,0 );
883 save_chunk (f, dst, len, _T("FPU "), 0);
884 xfree (dst);
885 #endif
886
887 #ifdef MMUEMU
888 dst = save_mmu (&len, 0);
889 save_chunk (f, dst, len, _T("MMU "), 0);
890 xfree (dst);
891 #endif
892
893 _tcscpy(name, _T("DSKx"));
894 for (i = 0; i < 4; i++) {
895 dst = save_disk (i, &len, 0, savepath);
896 if (dst) {
897 name[3] = i + '0';
898 save_chunk (f, dst, len, name, 0);
899 xfree (dst);
900 }
901 }
902 _tcscpy(name, _T("DSDx"));
903 for (i = 0; i < 4; i++) {
904 dst = save_disk2 (i, &len, 0);
905 if (dst) {
906 name[3] = i + '0';
907 save_chunk (f, dst, len, name, comp);
908 xfree (dst);
909 }
910 }
911
912
913 dst = save_floppy (&len, 0);
914 save_chunk (f, dst, len, _T("DISK"), 0);
915 xfree (dst);
916
917 dst = save_custom (&len, 0, 0);
918 save_chunk (f, dst, len, _T("CHIP"), 0);
919 xfree (dst);
920
921 dst = save_custom_extra (&len, 0);
922 save_chunk (f, dst, len, _T("CHPX"), 0);
923 xfree (dst);
924
925 dst = save_custom_event_delay (&len, 0);
926 save_chunk (f, dst, len, _T("CHPD"), 0);
927 xfree (dst);
928
929 dst = save_blitter_new (&len, 0);
930 save_chunk (f, dst, len, _T("BLTX"), 0);
931 xfree (dst);
932 if (new_blitter == false) {
933 dst = save_blitter (&len, 0);
934 save_chunk (f, dst, len, _T("BLIT"), 0);
935 xfree (dst);
936 }
937
938 dst = save_input (&len, 0);
939 save_chunk (f, dst, len, _T("CINP"), 0);
940 xfree (dst);
941
942 dst = save_custom_agacolors (&len, 0);
943 save_chunk (f, dst, len, _T("AGAC"), 0);
944 xfree (dst);
945
946 _tcscpy (name, _T("SPRx"));
947 for (i = 0; i < 8; i++) {
948 dst = save_custom_sprite (i, &len, 0);
949 name[3] = i + '0';
950 save_chunk (f, dst, len, name, 0);
951 xfree (dst);
952 }
953
954 _tcscpy (name, _T("AUDx"));
955 for (i = 0; i < 4; i++) {
956 dst = save_audio (i, &len, 0);
957 name[3] = i + '0';
958 save_chunk (f, dst, len, name, 0);
959 xfree (dst);
960 }
961
962 dst = save_cia (0, &len, 0);
963 save_chunk (f, dst, len, _T("CIAA"), 0);
964 xfree (dst);
965
966 dst = save_cia (1, &len, 0);
967 save_chunk (f, dst, len, _T("CIAB"), 0);
968 xfree (dst);
969
970 dst = save_keyboard (&len, NULL);
971 save_chunk (f, dst, len, _T("KEYB"), 0);
972 xfree (dst);
973
974 #ifdef AUTOCONFIG
975 dst = save_expansion (&len, 0);
976 save_chunk (f, dst, len, _T("EXPA"), 0);
977 #endif
978 #ifdef A2065
979 dst = save_a2065 (&len, NULL);
980 save_chunk (f, dst, len, _T("2065"), 0);
981 #endif
982 #ifdef PICASSO96
983 dst = save_p96 (&len, 0);
984 save_chunk (f, dst, len, _T("P96 "), 0);
985 #endif
986 save_rams (f, comp);
987
988 dst = save_rom (1, &len, 0);
989 do {
990 if (!dst)
991 break;
992 save_chunk (f, dst, len, _T("ROM "), 0);
993 xfree (dst);
994 } while ((dst = save_rom (0, &len, 0)));
995
996 #ifdef CD32
997 dst = save_akiko (&len, NULL);
998 save_chunk (f, dst, len, _T("CD32"), 0);
999 xfree (dst);
1000 #endif
1001 #ifdef CDTV
1002 dst = save_cdtv (&len, NULL);
1003 save_chunk (f, dst, len, _T("CDTV"), 0);
1004 xfree (dst);
1005 #if 0
1006 dst = save_cdtv_dmac (&len, NULL);
1007 save_chunk (f, dst, len, _T("DMAC"), 0);
1008 xfree (dst);
1009 #endif
1010 #endif
1011 #if 0
1012 dst = save_scsi_dmac (WDTYPE_A3000, &len, NULL);
1013 save_chunk (f, dst, len, _T("DMC2"), 0);
1014 xfree (dst);
1015 for (i = 0; i < 8; i++) {
1016 dst = save_scsi_device (WDTYPE_A3000, i, &len, NULL);
1017 save_chunk (f, dst, len, _T("SCS2"), 0);
1018 xfree (dst);
1019 }
1020 for (int ii = 0; ii < 2; ii++) {
1021 dst = save_scsi_dmac (ii == 0 ? WDTYPE_A2091 : WDTYPE_A2091_2, &len, NULL);
1022 save_chunk (f, dst, len, ii == 0 ? _T("DMC3") : _T("DMC4"), 0);
1023 xfree (dst);
1024 for (i = 0; i < 8; i++) {
1025 dst = save_scsi_device (ii == 0 ? WDTYPE_A2091 : WDTYPE_A2091_2, i, &len, NULL);
1026 save_chunk (f, dst, len, ii == 0 ? _T("SCS3") : _T("SCS4"), 0);
1027 xfree (dst);
1028 }
1029 }
1030 #endif
1031 #ifdef SCSIEMU
1032 for (i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) {
1033 dst = save_scsidev (i, &len, NULL);
1034 save_chunk (f, dst, len, _T("SCSD"), 0);
1035 xfree (dst);
1036 }
1037 #endif
1038 #ifdef ACTION_REPLAY
1039 dst = save_action_replay (&len, NULL);
1040 save_chunk (f, dst, len, _T("ACTR"), comp);
1041 dst = save_hrtmon (&len, NULL);
1042 save_chunk (f, dst, len, _T("HRTM"), comp);
1043 #endif
1044 #ifdef FILESYS
1045 dst = save_filesys_common (&len);
1046 if (dst) {
1047 save_chunk (f, dst, len, _T("FSYC"), 0);
1048 for (i = 0; i < nr_units (); i++) {
1049 dst = save_filesys (i, &len);
1050 if (dst) {
1051 save_chunk (f, dst, len, _T("FSYS"), 0);
1052 xfree (dst);
1053 }
1054 }
1055 }
1056 #endif
1057 dst = save_gayle (&len, NULL);
1058 if (dst) {
1059 save_chunk (f, dst, len, _T("GAYL"), 0);
1060 xfree(dst);
1061 }
1062 for (i = 0; i < 4; i++) {
1063 dst = save_gayle_ide (i, &len, NULL);
1064 if (dst) {
1065 save_chunk (f, dst, len, _T("IDE "), 0);
1066 xfree (dst);
1067 }
1068 }
1069
1070 for (i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) {
1071 dst = save_cd (i, &len);
1072 if (dst) {
1073 _stprintf (name, _T("CDU%d"), i);
1074 save_chunk (f, dst, len, name, 0);
1075 }
1076 }
1077
1078 dst = save_debug_memwatch (&len, NULL);
1079 if (dst) {
1080 save_chunk (f, dst, len, _T("DMWP"), 0);
1081 xfree(dst);
1082 }
1083
1084 /* add fake END tag, makes it easy to strip CONF and LOG hunks */
1085 /* move this if you want to use CONF or LOG hunks when restoring state */
1086 zfile_fwrite (endhunk, 1, 8, f);
1087
1088 dst = save_configuration (&len, false);
1089 if (dst) {
1090 save_chunk (f, dst, len, _T("CONF"), comp);
1091 xfree(dst);
1092 }
1093 len = 30000;
1094 dst = save_log (TRUE, &len);
1095 if (dst) {
1096 save_chunk (f, dst, len, _T("LOG "), comp);
1097 xfree (dst);
1098 }
1099
1100 zfile_fwrite (endhunk, 1, 8, f);
1101
1102 return 1;
1103 }
1104
save_state(const TCHAR * filename,const TCHAR * description)1105 int save_state (const TCHAR *filename, const TCHAR *description)
1106 {
1107 #ifdef FSUAE
1108 printf("save_state %s\n", filename);
1109 #endif
1110 struct zfile *f;
1111 int comp = savestate_docompress;
1112
1113 if (!savestate_specialdump && !savestate_nodialogs) {
1114 state_incompatible_warn ();
1115 if (!save_filesys_cando ()) {
1116 gui_message (_T("Filesystem active. Try again later."));
1117 return -1;
1118 }
1119 }
1120 new_blitter = false;
1121 savestate_nodialogs = 0;
1122 custom_prepare_savestate ();
1123 f = zfile_fopen (filename, _T("w+b"), 0);
1124 if (!f)
1125 return 0;
1126 if (savestate_specialdump) {
1127 size_t pos;
1128 if (savestate_specialdump == 2)
1129 write_wavheader (f, 0, 22050);
1130 pos = zfile_ftell (f);
1131 save_rams (f, -1);
1132 if (savestate_specialdump == 2) {
1133 int len, len2, i;
1134 uae_u8 *tmp;
1135 len = zfile_ftell (f) - pos;
1136 tmp = xmalloc (uae_u8, len);
1137 zfile_fseek(f, pos, SEEK_SET);
1138 len2 = zfile_fread (tmp, 1, len, f);
1139 for (i = 0; i < len2; i++)
1140 tmp[i] += 0x80;
1141 write_wavheader (f, len, 22050);
1142 zfile_fwrite (tmp, len2, 1, f);
1143 xfree (tmp);
1144 }
1145 zfile_fclose (f);
1146 return 1;
1147 }
1148 int v = save_state_internal (f, description, comp, true);
1149 if (v)
1150 write_log (_T("Save of '%s' complete\n"), filename);
1151 zfile_fclose (f);
1152 savestate_state = 0;
1153 #ifdef FSUAE
1154 uae_callback(uae_on_save_state_finished, filename);
1155 #endif
1156 return v;
1157 }
1158
savestate_quick(int slot,int save)1159 void savestate_quick (int slot, int save)
1160 {
1161 #ifdef FSUAE
1162 printf("savestate_quick slot=%d save=%d\n", slot, save);
1163 #endif
1164 int i, len = _tcslen (savestate_fname);
1165 i = len - 1;
1166 #ifdef FSUAE
1167 while (i >= 0 && savestate_fname[i] != ' ')
1168 #else
1169 while (i >= 0 && savestate_fname[i] != '_')
1170 #endif
1171 i--;
1172 if (i < len - 6 || i <= 0) { /* "_?.uss" */
1173 i = len - 1;
1174 while (i >= 0 && savestate_fname[i] != '.')
1175 i--;
1176 if (i <= 0) {
1177 write_log (_T("savestate name skipped '%s'\n"), savestate_fname);
1178 return;
1179 }
1180 }
1181 _tcscpy (savestate_fname + i, _T(".uss"));
1182 if (slot > 0)
1183 #ifdef FSUAE
1184 _stprintf (savestate_fname + i, _T(" %d.uss"), slot);
1185 #else
1186 _stprintf (savestate_fname + i, _T("_%d.uss"), slot);
1187 #endif
1188 if (save) {
1189 write_log (_T("saving '%s'\n"), savestate_fname);
1190 #ifdef FSUAE
1191 savestate_docompress = g_amiga_savestate_docompress;
1192 #else
1193 savestate_docompress = 1;
1194 #endif
1195 save_state (savestate_fname, _T(""));
1196 } else {
1197 if (!zfile_exists (savestate_fname)) {
1198 write_log (_T("staterestore, file '%s' not found\n"), savestate_fname);
1199 return;
1200 }
1201 savestate_state = STATE_DORESTORE;
1202 write_log (_T("staterestore starting '%s'\n"), savestate_fname);
1203 }
1204 }
1205
savestate_check(void)1206 bool savestate_check (void)
1207 {
1208 if (vpos == 0 && !savestate_state) {
1209 if (hsync_counter == 0 && input_play == INPREC_PLAY_NORMAL)
1210 savestate_memorysave ();
1211 savestate_capture (0);
1212 }
1213 if (savestate_state == STATE_DORESTORE) {
1214 savestate_state = STATE_RESTORE;
1215 return true;
1216 } else if (savestate_state == STATE_DOREWIND) {
1217 savestate_state = STATE_REWIND;
1218 return true;
1219 }
1220 return false;
1221 }
1222
1223 static int rewindmode;
1224
1225
canrewind(int pos)1226 static struct staterecord *canrewind (int pos)
1227 {
1228 if (pos < 0)
1229 pos += staterecords_max;
1230 if (!staterecords)
1231 return 0;
1232 if (staterecords[pos] == NULL)
1233 return NULL;
1234 if (staterecords[pos]->inuse == 0)
1235 return NULL;
1236 if ((pos + 1) % staterecords_max == staterecords_first)
1237 return NULL;
1238 return staterecords[pos];
1239 }
1240
savestate_dorewind(int pos)1241 int savestate_dorewind (int pos)
1242 {
1243 rewindmode = pos;
1244 if (pos < 0)
1245 pos = replaycounter - 1;
1246 if (canrewind (pos)) {
1247 savestate_state = STATE_DOREWIND;
1248 write_log (_T("dorewind %d (%010ld/%03ld) -> %d\n"), replaycounter - 1, hsync_counter, vsync_counter, pos);
1249 return 1;
1250 }
1251 return 0;
1252 }
1253 #if 0
1254 void savestate_listrewind (void)
1255 {
1256 int i = replaycounter;
1257 int cnt;
1258 uae_u8 *p;
1259 uae_u32 pc;
1260
1261 cnt = 1;
1262 for (;;) {
1263 struct staterecord *st;
1264 st = &staterecords[i];
1265 if (!st->start)
1266 break;
1267 p = st->cpu + 17 * 4;
1268 pc = restore_u32_func (&p);
1269 console_out_f (_T("%d: PC=%08X %c\n"), cnt, pc, regs.pc == pc ? '*' : ' ');
1270 cnt++;
1271 i--;
1272 if (i < 0)
1273 i += MAX_STATERECORDS;
1274 }
1275 }
1276 #endif
1277
savestate_rewind(void)1278 void savestate_rewind (void)
1279 {
1280 int len, i, dummy;
1281 uae_u8 *p, *p2;
1282 struct staterecord *st;
1283 int pos;
1284 bool rewind = false;
1285
1286 if (hsync_counter % currprefs.statecapturerate <= 25 && rewindmode <= -2) {
1287 pos = replaycounter - 2;
1288 rewind = true;
1289 } else {
1290 pos = replaycounter - 1;
1291 }
1292 st = canrewind (pos);
1293 if (!st) {
1294 rewind = false;
1295 pos = replaycounter - 1;
1296 st = canrewind (pos);
1297 if (!st)
1298 return;
1299 }
1300 p = st->data;
1301 p2 = st->end;
1302 write_log (_T("rewinding %d -> %d\n"), replaycounter - 1, pos);
1303 hsync_counter = restore_u32_func (&p);
1304 vsync_counter = restore_u32_func (&p);
1305 p = restore_cpu (p);
1306 p = restore_cycles (p);
1307 p = restore_cpu_extra (p);
1308 if (restore_u32_func (&p))
1309 p = restore_cpu_trace (p);
1310 #ifdef FPUEMU
1311 if (restore_u32_func (&p))
1312 p = restore_fpu (p);
1313 #endif
1314 for (i = 0; i < 4; i++) {
1315 p = restore_disk (i, p);
1316 if (restore_u32_func (&p))
1317 p = restore_disk2 (i, p);
1318 }
1319 p = restore_floppy (p);
1320 p = restore_custom (p);
1321 p = restore_custom_extra (p);
1322 if (restore_u32_func (&p))
1323 p = restore_custom_event_delay (p);
1324 p = restore_blitter_new (p);
1325 p = restore_custom_agacolors (p);
1326 for (i = 0; i < 8; i++) {
1327 p = restore_custom_sprite (i, p);
1328 }
1329 for (i = 0; i < 4; i++) {
1330 p = restore_audio (i, p);
1331 }
1332 p = restore_cia (0, p);
1333 p = restore_cia (1, p);
1334 p = restore_keyboard (p);
1335 p = restore_inputstate (p);
1336 #ifdef AUTOCONFIG
1337 p = restore_expansion (p);
1338 #endif
1339 #ifdef PICASSO96
1340 if (restore_u32_func (&p))
1341 p = restore_p96 (p);
1342 #endif
1343 len = restore_u32_func (&p);
1344 memcpy (chipmem_bank.baseaddr, p, currprefs.chipmem_size > len ? len : currprefs.chipmem_size);
1345 p += len;
1346 len = restore_u32_func (&p);
1347 memcpy (save_bram (&dummy), p, currprefs.bogomem_size > len ? len : currprefs.bogomem_size);
1348 p += len;
1349 #ifdef AUTOCONFIG
1350 len = restore_u32_func (&p);
1351 memcpy (save_fram (&dummy, 0), p, currprefs.fastmem_size > len ? len : currprefs.fastmem_size);
1352 p += len;
1353 len = restore_u32_func (&p);
1354 memcpy (save_zram (&dummy, 0), p, currprefs.z3fastmem_size > len ? len : currprefs.z3fastmem_size);
1355 p += len;
1356 #endif
1357 #ifdef ACTION_REPLAY
1358 if (restore_u32_func (&p))
1359 p = restore_action_replay (p);
1360 if (restore_u32_func (&p))
1361 p = restore_hrtmon (p);
1362 #endif
1363 #ifdef CD32
1364 if (restore_u32_func (&p))
1365 p = restore_akiko (p);
1366 #endif
1367 #ifdef CDTV
1368 if (restore_u32_func (&p))
1369 p = restore_cdtv (p);
1370 if (restore_u32_func (&p))
1371 p = restore_cdtv_dmac (p);
1372 #endif
1373 #if 0
1374 if (restore_u32_func (&p))
1375 p = restore_scsi_dmac (WDTYPE_A2091, p);
1376 if (restore_u32_func (&p))
1377 p = restore_scsi_dmac (WDTYPE_A3000, p);
1378 #endif
1379 if (restore_u32_func (&p))
1380 p = restore_gayle (p);
1381 for (i = 0; i < 4; i++) {
1382 if (restore_u32_func (&p))
1383 p = restore_gayle_ide (p);
1384 }
1385 p += 4;
1386 if (p != p2) {
1387 gui_message (_T("reload failure, address mismatch %p != %p"), p, p2);
1388 uae_reset (0, 0);
1389 return;
1390 }
1391 inprec_setposition (st->inprecoffset, pos);
1392 write_log (_T("state %d restored. (%010ld/%03ld)\n"), pos, hsync_counter, vsync_counter);
1393 if (rewind) {
1394 replaycounter--;
1395 if (replaycounter < 0)
1396 replaycounter += staterecords_max;
1397 st = canrewind (replaycounter);
1398 st->inuse = 0;
1399 }
1400
1401 }
1402
1403 #define BS 10000
1404
bufcheck(struct staterecord * sr,uae_u8 * p,int len)1405 STATIC_INLINE int bufcheck (struct staterecord *sr, uae_u8 *p, int len)
1406 {
1407 if (p - sr->data + BS + len >= sr->len)
1408 return 1;
1409 return 0;
1410 }
1411
savestate_memorysave(void)1412 void savestate_memorysave (void)
1413 {
1414 new_blitter = true;
1415 // create real statefile in memory too for later saving
1416 zfile_fclose (staterecord_statefile);
1417 staterecord_statefile = zfile_fopen_empty (NULL, _T("statefile.inp.uss"));
1418 if (staterecord_statefile)
1419 save_state_internal (staterecord_statefile, _T("rerecording"), 1, false);
1420 }
1421
savestate_capture(int force)1422 void savestate_capture (int force)
1423 {
1424 uae_u8 *p, *p2, *p3, *dst;
1425 int i, len, tlen, retrycnt;
1426 struct staterecord *st;
1427 bool firstcapture = false;
1428
1429 #ifdef FILESYS
1430 if (nr_units ())
1431 return;
1432 #endif
1433 if (!staterecords)
1434 return;
1435 if (!input_record)
1436 return;
1437 if (currprefs.statecapturerate && hsync_counter == 0 && input_record == INPREC_RECORD_START && savestate_first_capture > 0) {
1438 // first capture
1439 force = true;
1440 firstcapture = true;
1441 } else if (savestate_first_capture < 0) {
1442 force = true;
1443 firstcapture = false;
1444 }
1445 if (!force) {
1446 if (currprefs.statecapturerate <= 0)
1447 return;
1448 if (hsync_counter % currprefs.statecapturerate)
1449 return;
1450 }
1451 savestate_first_capture = false;
1452
1453 retrycnt = 0;
1454 retry2:
1455 st = staterecords[replaycounter];
1456 if (st == NULL) {
1457 st = (struct staterecord*)xmalloc (uae_u8, statefile_alloc);
1458 st->len = statefile_alloc;
1459 } else if (retrycnt > 0) {
1460 write_log (_T("realloc %d -> %d\n"), st->len, st->len + STATEFILE_ALLOC_SIZE);
1461 st->len += STATEFILE_ALLOC_SIZE;
1462 st = (struct staterecord*)xrealloc (uae_u8, st, st->len);
1463 }
1464 if (st->len > statefile_alloc)
1465 statefile_alloc = st->len;
1466 st->inuse = 0;
1467 st->data = (uae_u8*)(st + 1);
1468 staterecords[replaycounter] = st;
1469 retrycnt++;
1470 p = p2 = st->data;
1471 tlen = 0;
1472 save_u32_func (&p, hsync_counter);
1473 save_u32_func (&p, vsync_counter);
1474 tlen += 8;
1475
1476 if (bufcheck (st, p, 0))
1477 goto retry;
1478 st->cpu = p;
1479 save_cpu (&len, p);
1480 tlen += len;
1481 p += len;
1482
1483 if (bufcheck (st, p, 0))
1484 goto retry;
1485 save_cycles (&len, p);
1486 tlen += len;
1487 p += len;
1488
1489 if (bufcheck (st, p, 0))
1490 goto retry;
1491 save_cpu_extra (&len, p);
1492 tlen += len;
1493 p += len;
1494
1495 if (bufcheck (st, p, 0))
1496 goto retry;
1497 p3 = p;
1498 save_u32_func (&p, 0);
1499 tlen += 4;
1500 if (save_cpu_trace (&len, p)) {
1501 save_u32_func (&p3, 1);
1502 tlen += len;
1503 p += len;
1504 }
1505
1506 #ifdef FPUEMU
1507 if (bufcheck (st, p, 0))
1508 goto retry;
1509 p3 = p;
1510 save_u32_func (&p, 0);
1511 tlen += 4;
1512 if (save_fpu (&len, p)) {
1513 save_u32_func (&p3, 1);
1514 tlen += len;
1515 p += len;
1516 }
1517 #endif
1518 for (i = 0; i < 4; i++) {
1519 if (bufcheck (st, p, 0))
1520 goto retry;
1521 save_disk (i, &len, p, true);
1522 tlen += len;
1523 p += len;
1524 p3 = p;
1525 save_u32_func (&p, 0);
1526 tlen += 4;
1527 if (save_disk2 (i, &len, p)) {
1528 save_u32_func (&p3, 1);
1529 tlen += len;
1530 p += len;
1531 }
1532 }
1533
1534 if (bufcheck (st, p, 0))
1535 goto retry;
1536 save_floppy (&len, p);
1537 tlen += len;
1538 p += len;
1539
1540 if (bufcheck (st, p, 0))
1541 goto retry;
1542 save_custom (&len, p, 0);
1543 tlen += len;
1544 p += len;
1545
1546 if (bufcheck (st, p, 0))
1547 goto retry;
1548 save_custom_extra (&len, p);
1549 tlen += len;
1550 p += len;
1551
1552 if (bufcheck (st, p, 0))
1553 goto retry;
1554 p3 = p;
1555 save_u32_func (&p, 0);
1556 tlen += 4;
1557 if (save_custom_event_delay (&len, p)) {
1558 save_u32_func (&p3, 1);
1559 tlen += len;
1560 p += len;
1561 }
1562
1563 if (bufcheck (st, p, 0))
1564 goto retry;
1565 save_blitter_new (&len, p);
1566 tlen += len;
1567 p += len;
1568
1569 if (bufcheck (st, p, 0))
1570 goto retry;
1571 save_custom_agacolors (&len, p);
1572 tlen += len;
1573 p += len;
1574 for (i = 0; i < 8; i++) {
1575 if (bufcheck (st, p, 0))
1576 goto retry;
1577 save_custom_sprite (i, &len, p);
1578 tlen += len;
1579 p += len;
1580 }
1581
1582 for (i = 0; i < 4; i++) {
1583 if (bufcheck (st, p, 0))
1584 goto retry;
1585 save_audio (i, &len, p);
1586 tlen += len;
1587 p += len;
1588 }
1589
1590 if (bufcheck (st, p, len))
1591 goto retry;
1592 save_cia (0, &len, p);
1593 tlen += len;
1594 p += len;
1595
1596 if (bufcheck (st, p, len))
1597 goto retry;
1598 save_cia (1, &len, p);
1599 tlen += len;
1600 p += len;
1601
1602 if (bufcheck (st, p, len))
1603 goto retry;
1604 save_keyboard (&len, p);
1605 tlen += len;
1606 p += len;
1607
1608 if (bufcheck (st, p, len))
1609 goto retry;
1610 save_inputstate (&len, p);
1611 tlen += len;
1612 p += len;
1613
1614 #ifdef AUTOCONFIG
1615 if (bufcheck (st, p, len))
1616 goto retry;
1617 save_expansion (&len, p);
1618 tlen += len;
1619 p += len;
1620 #endif
1621
1622 #ifdef PICASSO96
1623 if (bufcheck (st, p, 0))
1624 goto retry;
1625 p3 = p;
1626 save_u32_func (&p, 0);
1627 tlen += 4;
1628 if (save_p96 (&len, p)) {
1629 save_u32_func (&p3, 1);
1630 tlen += len;
1631 p += len;
1632 }
1633 #endif
1634
1635 dst = save_cram (&len);
1636 if (bufcheck (st, p, len))
1637 goto retry;
1638 save_u32_func (&p, len);
1639 memcpy (p, dst, len);
1640 tlen += len + 4;
1641 p += len;
1642 dst = save_bram (&len);
1643 if (bufcheck (st, p, len))
1644 goto retry;
1645 save_u32_func (&p, len);
1646 memcpy (p, dst, len);
1647 tlen += len + 4;
1648 p += len;
1649 #ifdef AUTOCONFIG
1650 dst = save_fram (&len, 0);
1651 if (bufcheck (st, p, len))
1652 goto retry;
1653 save_u32_func (&p, len);
1654 memcpy (p, dst, len);
1655 tlen += len + 4;
1656 p += len;
1657 dst = save_zram (&len, 0);
1658 if (bufcheck (st, p, len))
1659 goto retry;
1660 save_u32_func (&p, len);
1661 memcpy (p, dst, len);
1662 tlen += len + 4;
1663 p += len;
1664 #endif
1665 #ifdef ACTION_REPLAY
1666 if (bufcheck (st, p, 0))
1667 goto retry;
1668 p3 = p;
1669 save_u32_func (&p, 0);
1670 tlen += 4;
1671 if (save_action_replay (&len, p)) {
1672 save_u32_func (&p3, 1);
1673 tlen += len;
1674 p += len;
1675 }
1676 if (bufcheck (st, p, 0))
1677 goto retry;
1678 p3 = p;
1679 save_u32_func (&p, 0);
1680 tlen += 4;
1681 if (save_hrtmon (&len, p)) {
1682 save_u32_func (&p3, 1);
1683 tlen += len;
1684 p += len;
1685 }
1686 #endif
1687 #ifdef CD32
1688 if (bufcheck (st, p, 0))
1689 goto retry;
1690 p3 = p;
1691 save_u32_func (&p, 0);
1692 tlen += 4;
1693 if (save_akiko (&len, p)) {
1694 save_u32_func (&p3, 1);
1695 tlen += len;
1696 p += len;
1697 }
1698 #endif
1699 #ifdef CDTV
1700 if (bufcheck (st, p, 0))
1701 goto retry;
1702 p3 = p;
1703 save_u32_func (&p, 0);
1704 tlen += 4;
1705 if (save_cdtv (&len, p)) {
1706 save_u32_func (&p3, 1);
1707 tlen += len;
1708 p += len;
1709 }
1710 if (bufcheck (st, p, 0))
1711 goto retry;
1712 p3 = p;
1713 save_u32_func (&p, 0);
1714 tlen += 4;
1715 if (save_cdtv_dmac (&len, p)) {
1716 save_u32_func (&p3, 1);
1717 tlen += len;
1718 p += len;
1719 }
1720 #endif
1721 #if 0
1722 if (bufcheck (st, p, 0))
1723 goto retry;
1724 p3 = p;
1725 save_u32_func (&p, 0);
1726 tlen += 4;
1727 if (save_scsi_dmac (WDTYPE_A2091, &len, p)) {
1728 save_u32_func (&p3, 1);
1729 tlen += len;
1730 p += len;
1731 }
1732 if (bufcheck (st, p, 0))
1733 goto retry;
1734 p3 = p;
1735 save_u32_func (&p, 0);
1736 tlen += 4;
1737 if (save_scsi_dmac (WDTYPE_A3000, &len, p)) {
1738 save_u32_func (&p3, 1);
1739 tlen += len;
1740 p += len;
1741 }
1742 #endif
1743 if (bufcheck (st, p, 0))
1744 goto retry;
1745 p3 = p;
1746 save_u32_func (&p, 0);
1747 tlen += 4;
1748 if (save_gayle (&len, p)) {
1749 save_u32_func (&p3, 1);
1750 tlen += len;
1751 p += len;
1752 }
1753 for (i = 0; i < 4; i++) {
1754 if (bufcheck (st, p, 0))
1755 goto retry;
1756 p3 = p;
1757 save_u32_func (&p, 0);
1758 tlen += 4;
1759 if (save_gayle_ide (i, &len, p)) {
1760 save_u32_func (&p3, 1);
1761 tlen += len;
1762 p += len;
1763 }
1764 }
1765 save_u32_func (&p, tlen);
1766 st->end = p;
1767 st->inuse = 1;
1768 st->inprecoffset = inprec_getposition ();
1769
1770 replaycounter++;
1771 if (replaycounter >= staterecords_max)
1772 replaycounter -= staterecords_max;
1773 if (replaycounter == staterecords_first) {
1774 staterecords_first++;
1775 if (staterecords_first >= staterecords_max)
1776 staterecords_first -= staterecords_max;
1777 }
1778
1779 write_log (_T("state capture %d (%010ld/%03ld,%ld/%d) (%ld bytes, alloc %d)\n"),
1780 replaycounter, hsync_counter, vsync_counter,
1781 hsync_counter % current_maxvpos (), current_maxvpos (),
1782 st->end - st->data, statefile_alloc);
1783
1784 if (firstcapture) {
1785 savestate_memorysave ();
1786 input_record++;
1787 for (i = 0; i < 4; i++) {
1788 bool wp = true;
1789 DISK_validate_filename (&currprefs, currprefs.floppyslots[i].df, false, &wp, NULL, NULL);
1790 inprec_recorddiskchange (i, currprefs.floppyslots[i].df, wp);
1791 }
1792 input_record--;
1793 }
1794
1795
1796 return;
1797 retry:
1798 if (retrycnt < 10)
1799 goto retry2;
1800 write_log (_T("can't save, too small capture buffer or out of memory\n"));
1801 return;
1802 }
1803
savestate_free(void)1804 void savestate_free (void)
1805 {
1806 xfree (staterecords);
1807 staterecords = NULL;
1808 }
1809
savestate_capture_request(void)1810 void savestate_capture_request (void)
1811 {
1812 savestate_first_capture = -1;
1813 }
1814
savestate_init(void)1815 void savestate_init (void)
1816 {
1817 savestate_free ();
1818 replaycounter = 0;
1819 staterecords_max = currprefs.statecapturebuffersize;
1820 staterecords = xcalloc (struct staterecord*, staterecords_max);
1821 statefile_alloc = STATEFILE_ALLOC_SIZE;
1822 if (input_record && savestate_state != STATE_DORESTORE) {
1823 zfile_fclose (staterecord_statefile);
1824 staterecord_statefile = NULL;
1825 inprec_close (false);
1826 inprec_open (NULL, NULL);
1827 savestate_first_capture = 1;
1828 }
1829 }
1830
1831
statefile_save_recording(const TCHAR * filename)1832 void statefile_save_recording (const TCHAR *filename)
1833 {
1834 if (!staterecord_statefile)
1835 return;
1836 struct zfile *zf = zfile_fopen (filename, _T("wb"), 0);
1837 if (zf) {
1838 int len = zfile_size (staterecord_statefile);
1839 uae_u8 *data = zfile_getdata (staterecord_statefile, 0, len);
1840 zfile_fwrite (data, len, 1, zf);
1841 xfree (data);
1842 zfile_fclose (zf);
1843 write_log (_T("input statefile '%s' saved\n"), filename);
1844 }
1845 }
1846
1847
1848 /*
1849
1850 My (Toni Wilen <twilen@arabuusimiehet.com>)
1851 proposal for Amiga-emulators' state-save format
1852
1853 Feel free to comment...
1854
1855 This is very similar to IFF-fileformat
1856 Every hunk must end to 4 byte boundary,
1857 fill with zero bytes if needed
1858
1859 version 0.8
1860
1861 HUNK HEADER (beginning of every hunk)
1862
1863 hunk name (4 ascii-characters)
1864 hunk size (including header)
1865 hunk flags
1866
1867 bit 0 = chunk contents are compressed with zlib (maybe RAM chunks only?)
1868
1869 HEADER
1870
1871 "ASF " (AmigaStateFile)
1872
1873 statefile version
1874 emulator name ("uae", "fellow" etc..)
1875 emulator version string (example: "0.8.15")
1876 free user writable comment string
1877
1878 CPU
1879
1880 "CPU "
1881
1882 CPU model 4 (68000,68010,68020,68030,68040,68060)
1883 CPU typeflags bit 0=EC-model or not, bit 31 = clock rate included
1884 D0-D7 8*4=32
1885 A0-A6 7*4=32
1886 PC 4
1887 unused 4
1888 68000 prefetch (IRC) 2
1889 68000 prefetch (IR) 2
1890 USP 4
1891 ISP 4
1892 SR/CCR 2
1893 flags 4 (bit 0=CPU was HALTed)
1894
1895 CPU specific registers
1896
1897 68000: SR/CCR is last saved register
1898 68010: save also DFC,SFC and VBR
1899 68020: all 68010 registers and CAAR,CACR and MSP
1900 etc..
1901
1902 68010+:
1903
1904 DFC 4
1905 SFC 4
1906 VBR 4
1907
1908 68020+:
1909
1910 CAAR 4
1911 CACR 4
1912 MSP 4
1913
1914 68030+:
1915
1916 AC0 4
1917 AC1 4
1918 ACUSR 2
1919 TT0 4
1920 TT1 4
1921
1922 68040+:
1923
1924 ITT0 4
1925 ITT1 4
1926 DTT0 4
1927 DTT1 4
1928 TCR 4
1929 URP 4
1930 SRP 4
1931
1932 68060:
1933
1934 BUSCR 4
1935 PCR 4
1936
1937 All:
1938
1939 Clock in KHz 4 (only if bit 31 in flags)
1940 4 (spare, only if bit 31 in flags)
1941
1942
1943 FPU (only if used)
1944
1945 "FPU "
1946
1947 FPU model 4 (68881/68882/68040/68060)
1948 FPU typeflags 4 (bit 31 = clock rate included)
1949 FP0-FP7 4+4+2 (80 bits)
1950 FPCR 4
1951 FPSR 4
1952 FPIAR 4
1953
1954 Clock in KHz 4 (only if bit 31 in flags)
1955 4 (spare, only if bit 31 in flags)
1956
1957 MMU (when and if MMU is supported in future..)
1958
1959 "MMU "
1960
1961 MMU model 4 (68040)
1962 flags 4 (none defined yet)
1963
1964 CUSTOM CHIPS
1965
1966 "CHIP"
1967
1968 chipset flags 4 OCS=0,ECSAGNUS=1,ECSDENISE=2,AGA=4
1969 ECSAGNUS and ECSDENISE can be combined
1970
1971 DFF000-DFF1FF 352 (0x120 - 0x17f and 0x0a0 - 0xdf excluded)
1972
1973 sprite registers (0x120 - 0x17f) saved with SPRx chunks
1974 audio registers (0x0a0 - 0xdf) saved with AUDx chunks
1975
1976 AGA COLORS
1977
1978 "AGAC"
1979
1980 AGA color 8 banks * 32 registers *
1981 registers LONG (XRGB) = 1024
1982
1983 SPRITE
1984
1985 "SPR0" - "SPR7"
1986
1987
1988 SPRxPT 4
1989 SPRxPOS 2
1990 SPRxCTL 2
1991 SPRxDATA 2
1992 SPRxDATB 2
1993 AGA sprite DATA/DATB 3 * 2 * 2
1994 sprite "armed" status 1
1995
1996 sprites maybe armed in non-DMA mode
1997 use bit 0 only, other bits are reserved
1998
1999
2000 AUDIO
2001 "AUD0" "AUD1" "AUD2" "AUD3"
2002
2003 audio state 1
2004 machine mode
2005 AUDxVOL 1
2006 irq? 1
2007 data_written? 1
2008 internal AUDxLEN 2
2009 AUDxLEN 2
2010 internal AUDxPER 2
2011 AUDxPER 2
2012 internal AUDxLC 4
2013 AUDxLC 4
2014 evtime? 4
2015
2016 BLITTER
2017
2018 "BLIT"
2019
2020 internal blitter state
2021
2022 flags 4
2023 bit 0=blitter active
2024 bit 1=fill carry bit
2025 internal ahold 4
2026 internal bhold 4
2027 internal hsize 2
2028 internal vsize 2
2029
2030 CIA
2031
2032 "CIAA" and "CIAB"
2033
2034 BFE001-BFEF01 16*1 (CIAA)
2035 BFD000-BFDF00 16*1 (CIAB)
2036
2037 internal registers
2038
2039 IRQ mask (ICR) 1 BYTE
2040 timer latches 2 timers * 2 BYTES (LO/HI)
2041 latched tod 3 BYTES (LO/MED/HI)
2042 alarm 3 BYTES (LO/MED/HI)
2043 flags 1 BYTE
2044 bit 0=tod latched (read)
2045 bit 1=tod stopped (write)
2046 div10 counter 1 BYTE
2047
2048 FLOPPY DRIVES
2049
2050 "DSK0" "DSK1" "DSK2" "DSK3"
2051
2052 drive state
2053
2054 drive ID-word 4
2055 state 1 (bit 0: motor on, bit 1: drive disabled, bit 2: current id bit)
2056 rw-head track 1
2057 dskready 1
2058 id-mode 1 (ID mode bit number 0-31)
2059 floppy information
2060
2061 bits from 4
2062 beginning of track
2063 CRC of disk-image 4 (used during restore to check if image
2064 is correct)
2065 disk-image null-terminated
2066 file name
2067
2068 INTERNAL FLOPPY CONTROLLER STATUS
2069
2070 "DISK"
2071
2072 current DMA word 2
2073 DMA word bit offset 1
2074 WORDSYNC found 1 (no=0,yes=1)
2075 hpos of next bit 1
2076 DSKLENGTH status 0=off,1=written once,2=written twice
2077 unused 2
2078
2079 RAM SPACE
2080
2081 "xRAM" (CRAM = chip, BRAM = bogo, FRAM = fast, ZRAM = Z3, P96 = RTG RAM, A3K1/A3K2 = MB RAM)
2082
2083 start address 4 ("bank"=chip/slow/fast etc..)
2084 of RAM "bank"
2085 RAM "bank" size 4
2086 RAM flags 4 (bit 0 = zlib compressed)
2087 RAM "bank" contents
2088
2089 ROM SPACE
2090
2091 "ROM "
2092
2093 ROM start 4
2094 address
2095 size of ROM 4
2096 ROM type 4 KICK=0
2097 ROM flags 4
2098 ROM version 2
2099 ROM revision 2
2100 ROM CRC 4 see below
2101 ROM-image ID-string null terminated, see below
2102 path to rom image
2103 ROM contents (Not mandatory, use hunk size to check if
2104 this hunk contains ROM data or not)
2105
2106 Kickstart ROM:
2107 ID-string is "Kickstart x.x"
2108 ROM version: version in high word and revision in low word
2109 Kickstart ROM version and revision can be found from ROM start
2110 + 12 (version) and +14 (revision)
2111
2112 ROM version and CRC is only meant for emulator to automatically
2113 find correct image from its ROM-directory during state restore.
2114
2115 Usually saving ROM contents is not good idea.
2116
2117 ACTION REPLAY
2118
2119 "ACTR"
2120
2121 Model (1,2,3) 4
2122 path to rom image
2123 RAM space (depends on model)
2124 ROM CRC 4
2125
2126 "CDx "
2127
2128 Flags 4 (bit 0 = scsi, bit 1 = ide, bit 2 = image)
2129 Path (for example image file or drive letter)
2130
2131 END
2132 hunk "END " ends, remember hunk size 8!
2133
2134
2135 EMULATOR SPECIFIC HUNKS
2136
2137 Read only if "emulator name" in header is same as used emulator.
2138 Maybe useful for configuration?
2139
2140 misc:
2141
2142 - save only at position 0,0 before triggering VBLANK interrupt
2143 - all data must be saved in bigendian format
2144 - should we strip all paths from image file names?
2145
2146 */
2147
2148 #endif /* SAVESTATE */
2149