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