|
|
1.1 root 1: /*
1.1.1.4 root 2: Hatari - memorySnapShot.c
3:
4: This file is distributed under the GNU Public License, version 2 or at
5: your option any later version. Read the file gpl.txt for details.
1.1 root 6:
7: Memory Snapshot
8:
1.1.1.5 root 9: This handles the saving/restoring of the emulator's state so any game or
10: application can be saved and restored at any time. This is quite complicated
11: as we need to store all STRam, all chip states, all emulation variables and
12: then things get really complicated as we need to restore file handles
1.1 root 13: and such like.
1.1.1.5 root 14: To help keep things simple each file has one function which is used to
15: save/restore all variables that are local to it. We use one function to
16: reduce redundancy and the function 'MemorySnapShot_Store' decides if it
17: should save or restore the data.
1.1 root 18: */
1.1.1.6 ! root 19: char MemorySnapShot_rcsid[] = "Hatari $Id: memorySnapShot.c,v 1.9 2004/10/31 17:32:50 thothy Exp $";
1.1.1.4 root 20:
21: #include <SDL_types.h>
1.1.1.5 root 22: #include <errno.h>
1.1 root 23:
24: #include "main.h"
1.1.1.5 root 25: #include "blitter.h"
1.1 root 26: #include "debug.h"
27: #include "dialog.h"
28: #include "fdc.h"
29: #include "file.h"
30: #include "floppy.h"
31: #include "gemdos.h"
32: #include "ikbd.h"
33: #include "int.h"
34: #include "m68000.h"
35: #include "memorySnapShot.h"
36: #include "mfp.h"
37: #include "psg.h"
38: #include "reset.h"
39: #include "sound.h"
40: #include "tos.h"
41: #include "video.h"
1.1.1.2 root 42:
1.1 root 43:
1.1.1.6 ! root 44: #define VERSION_STRING "0.50 " /* Version number of compatible memory snapshots - Always 6 bytes (inc' NULL) */
! 45: #define VERSION_STRING_SIZE 6 /* Size of above (inc' NULL) */
! 46:
! 47:
1.1.1.5 root 48: #define COMPRESS_MEMORYSNAPSHOT /* Compress snapshots to reduce disc space used */
1.1 root 49:
1.1.1.5 root 50: #ifdef COMPRESS_MEMORYSNAPSHOT
1.1 root 51:
1.1.1.5 root 52: #include <zlib.h>
53: typedef gzFile MSS_File;
54:
55: #else
56:
57: typedef FILE* MSS_File;
1.1 root 58:
1.1.1.5 root 59: #endif
60:
61:
62: static MSS_File CaptureFile;
63: static BOOL bCaptureSave, bCaptureError;
64:
65:
66: /*-----------------------------------------------------------------------*/
1.1 root 67: /*
1.1.1.5 root 68: Open file.
1.1 root 69: */
1.1.1.5 root 70: static MSS_File MemorySnapShot_fopen(char *pszFileName, char *pszMode)
1.1 root 71: {
72: #ifdef COMPRESS_MEMORYSNAPSHOT
1.1.1.5 root 73: return gzopen(pszFileName, pszMode);
74: #else
75: return fopen(pszFileName, pszMode);
76: #endif
1.1 root 77: }
78:
1.1.1.5 root 79:
80: /*-----------------------------------------------------------------------*/
1.1 root 81: /*
1.1.1.5 root 82: Close file.
1.1 root 83: */
1.1.1.5 root 84: static void MemorySnapShot_fclose(MSS_File fhndl)
1.1 root 85: {
86: #ifdef COMPRESS_MEMORYSNAPSHOT
1.1.1.5 root 87: gzclose(fhndl);
88: #else
89: fclose(fhndl);
90: #endif
1.1 root 91: }
92:
1.1.1.5 root 93:
94: /*-----------------------------------------------------------------------*/
1.1 root 95: /*
1.1.1.5 root 96: Read from file.
1.1 root 97: */
1.1.1.5 root 98: static int MemorySnapShot_fread(MSS_File fhndl, char *buf, int len)
1.1 root 99: {
100: #ifdef COMPRESS_MEMORYSNAPSHOT
1.1.1.5 root 101: return gzread(fhndl, buf, len);
102: #else
103: return fread(buf, 1, len, fhndl);
104: #endif
1.1 root 105: }
106:
1.1.1.5 root 107:
108: /*-----------------------------------------------------------------------*/
1.1 root 109: /*
1.1.1.5 root 110: Write data to file.
1.1 root 111: */
1.1.1.5 root 112: static int MemorySnapShot_fwrite(MSS_File fhndl, char *buf, int len)
1.1 root 113: {
1.1.1.5 root 114: #ifdef COMPRESS_MEMORYSNAPSHOT
115: return gzwrite(fhndl, buf, len);
116: #else
117: return fwrite(buf, 1, len, fhndl);
118: #endif
1.1 root 119: }
120:
1.1.1.5 root 121:
122: /*-----------------------------------------------------------------------*/
1.1 root 123: /*
1.1.1.5 root 124: Open/Create snapshot file, and set flag so 'MemorySnapShot_Store' knows
125: how to handle data.
1.1 root 126: */
1.1.1.5 root 127: static BOOL MemorySnapShot_OpenFile(char *pszFileName, BOOL bSave)
1.1 root 128: {
1.1.1.5 root 129: char szString[256];
130: char VersionString[VERSION_STRING_SIZE];
1.1.1.3 root 131:
1.1.1.5 root 132: /* Set error */
133: bCaptureError = FALSE;
1.1 root 134:
1.1.1.5 root 135: /* Open file, set flag so 'MemorySnapShot_Store' can load to/save from file */
136: if (bSave)
137: {
138: /* Save */
139: CaptureFile = MemorySnapShot_fopen(pszFileName, "wb");
140: if (!CaptureFile)
141: {
142: fprintf(stderr, "Failed to open save file '%s': %s\n",
143: pszFileName, strerror(errno));
144: bCaptureError = TRUE;
145: return(FALSE);
146: }
147: bCaptureSave = TRUE;
148: /* Store version string */
149: MemorySnapShot_Store(VERSION_STRING, VERSION_STRING_SIZE);
150: }
151: else
152: {
153: /* Restore */
154: CaptureFile = MemorySnapShot_fopen(pszFileName, "rb");
155: if (!CaptureFile)
156: {
157: fprintf(stderr, "Failed to open file '%s': %s\n",
158: pszFileName, strerror(errno));
159: bCaptureError = TRUE;
160: return(FALSE);
161: }
162: bCaptureSave = FALSE;
163: /* Restore version string */
164: MemorySnapShot_Store(VersionString, VERSION_STRING_SIZE);
165: /* Does match current version? */
166: if (strcasecmp(VersionString, VERSION_STRING))
167: {
168: /* No, inform user and error */
169: sprintf(szString,"Unable to Restore Memory State.\n"
170: "File is only compatible with Hatari v%s", VersionString);
171: Main_Message(szString, PROG_NAME /*, MB_OK | MB_ICONSTOP*/);
172: bCaptureError = TRUE;
173: return(FALSE);
174: }
175: }
1.1 root 176:
1.1.1.5 root 177: /* All OK */
178: return(TRUE);
1.1 root 179: }
180:
1.1.1.5 root 181:
182: /*-----------------------------------------------------------------------*/
1.1 root 183: /*
1.1.1.5 root 184: Close snapshot file.
1.1 root 185: */
1.1.1.5 root 186: static void MemorySnapShot_CloseFile(void)
1.1 root 187: {
1.1.1.5 root 188: MemorySnapShot_fclose(CaptureFile);
1.1 root 189: }
190:
1.1.1.5 root 191:
192: /*-----------------------------------------------------------------------*/
1.1 root 193: /*
1.1.1.5 root 194: Save/Restore data to/from file.
1.1 root 195: */
196: void MemorySnapShot_Store(void *pData, int Size)
197: {
1.1.1.5 root 198: long nBytes;
1.1.1.3 root 199:
1.1.1.5 root 200: /* Check no file errors */
201: if (CaptureFile != NULL)
202: {
203: /* Saving or Restoring? */
204: if (bCaptureSave)
205: nBytes = MemorySnapShot_fwrite(CaptureFile, (char *)pData, Size);
206: else
207: nBytes = MemorySnapShot_fread(CaptureFile, (char *)pData, Size);
208:
209: /* Did save OK? */
210: if (nBytes != Size)
211: bCaptureError = TRUE;
212: }
1.1 root 213: }
214:
1.1.1.5 root 215:
216: /*-----------------------------------------------------------------------*/
1.1 root 217: /*
218: Save 'snapshot' of memory/chips/emulation variables
219: */
220: void MemorySnapShot_Capture(char *pszFileName)
221: {
1.1.1.5 root 222: /* Set to 'saving' */
223: if (MemorySnapShot_OpenFile(pszFileName,TRUE))
224: {
225: /* Capture each files details */
226: Main_MemorySnapShot_Capture(TRUE);
227: FDC_MemorySnapShot_Capture(TRUE);
228: Floppy_MemorySnapShot_Capture(TRUE);
229: GemDOS_MemorySnapShot_Capture(TRUE);
230: IKBD_MemorySnapShot_Capture(TRUE);
231: Int_MemorySnapShot_Capture(TRUE);
232: M68000_MemorySnapShot_Capture(TRUE);
233: MFP_MemorySnapShot_Capture(TRUE);
234: PSG_MemorySnapShot_Capture(TRUE);
235: Sound_MemorySnapShot_Capture(TRUE);
236: TOS_MemorySnapShot_Capture(TRUE);
237: Video_MemorySnapShot_Capture(TRUE);
238: Blitter_MemorySnapShot_Capture(TRUE);
239:
240: /* And close */
241: MemorySnapShot_CloseFile();
242: }
243:
244: /* Did error */
245: if (bCaptureError)
246: Main_Message("Unable to Save Memory State to file.", PROG_NAME /*, MB_OK | MB_ICONSTOP*/);
247: else
248: Main_Message("Memory State file saved.", PROG_NAME /*, MB_OK | MB_ICONINFORMATION*/);
1.1 root 249: }
250:
1.1.1.5 root 251:
252: /*-----------------------------------------------------------------------*/
1.1 root 253: /*
254: Restore 'snapshot' of memory/chips/emulation variables
255: */
256: void MemorySnapShot_Restore(char *pszFileName)
257: {
1.1.1.5 root 258: /* Set to 'restore' */
259: if (MemorySnapShot_OpenFile(pszFileName,FALSE))
260: {
261: /* Reset emulator to get things running */
262: Reset_Cold();
263:
264: /* Capture each files details */
265: Main_MemorySnapShot_Capture(FALSE);
266: FDC_MemorySnapShot_Capture(FALSE);
267: Floppy_MemorySnapShot_Capture(FALSE);
268: GemDOS_MemorySnapShot_Capture(FALSE);
269: IKBD_MemorySnapShot_Capture(FALSE);
270: Int_MemorySnapShot_Capture(FALSE);
271: M68000_MemorySnapShot_Capture(FALSE);
272: MFP_MemorySnapShot_Capture(FALSE);
273: PSG_MemorySnapShot_Capture(FALSE);
274: Sound_MemorySnapShot_Capture(FALSE);
275: TOS_MemorySnapShot_Capture(FALSE);
276: Video_MemorySnapShot_Capture(FALSE);
277: Blitter_MemorySnapShot_Capture(FALSE);
278:
279: /* And close */
280: MemorySnapShot_CloseFile();
281: }
282:
283: /* Did error? */
284: if (bCaptureError)
285: Main_Message("Unable to Restore Memory State from file.", PROG_NAME /*,MB_OK | MB_ICONSTOP*/);
286: else
287: Main_Message("Memory State file restored.", PROG_NAME /*,MB_OK | MB_ICONINFORMATION*/);
1.1 root 288: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.