|
|
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.8 ! root 19: char MemorySnapShot_rcsid[] = "Hatari $Id: memorySnapShot.c,v 1.19 2005/10/12 09:06:47 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.1.8 ! root 26: #include "configuration.h"
! 27: #include "dmaSnd.h"
1.1 root 28: #include "fdc.h"
29: #include "file.h"
30: #include "floppy.h"
31: #include "gemdos.h"
32: #include "ikbd.h"
33: #include "int.h"
1.1.1.7 root 34: #include "log.h"
1.1 root 35: #include "m68000.h"
36: #include "memorySnapShot.h"
37: #include "mfp.h"
38: #include "psg.h"
39: #include "reset.h"
40: #include "sound.h"
41: #include "tos.h"
42: #include "video.h"
1.1.1.2 root 43:
1.1 root 44:
1.1.1.8 ! root 45: #define VERSION_STRING "0.80 " /* Version number of compatible memory snapshots - Always 6 bytes (inc' NULL) */
1.1.1.6 root 46: #define VERSION_STRING_SIZE 6 /* Size of above (inc' NULL) */
47:
48:
1.1.1.8 ! root 49: #define COMPRESS_MEMORYSNAPSHOT /* Compress snapshots to reduce disk space used */
1.1 root 50:
1.1.1.5 root 51: #ifdef COMPRESS_MEMORYSNAPSHOT
1.1 root 52:
1.1.1.5 root 53: #include <zlib.h>
54: typedef gzFile MSS_File;
55:
56: #else
57:
58: typedef FILE* MSS_File;
1.1 root 59:
1.1.1.5 root 60: #endif
61:
62:
63: static MSS_File CaptureFile;
64: static BOOL bCaptureSave, bCaptureError;
65:
66:
67: /*-----------------------------------------------------------------------*/
1.1 root 68: /*
1.1.1.5 root 69: Open file.
1.1 root 70: */
1.1.1.7 root 71: static MSS_File MemorySnapShot_fopen(const char *pszFileName, const char *pszMode)
1.1 root 72: {
73: #ifdef COMPRESS_MEMORYSNAPSHOT
1.1.1.5 root 74: return gzopen(pszFileName, pszMode);
75: #else
76: return fopen(pszFileName, pszMode);
77: #endif
1.1 root 78: }
79:
1.1.1.5 root 80:
81: /*-----------------------------------------------------------------------*/
1.1 root 82: /*
1.1.1.5 root 83: Close file.
1.1 root 84: */
1.1.1.5 root 85: static void MemorySnapShot_fclose(MSS_File fhndl)
1.1 root 86: {
87: #ifdef COMPRESS_MEMORYSNAPSHOT
1.1.1.5 root 88: gzclose(fhndl);
89: #else
90: fclose(fhndl);
91: #endif
1.1 root 92: }
93:
1.1.1.5 root 94:
95: /*-----------------------------------------------------------------------*/
1.1 root 96: /*
1.1.1.5 root 97: Read from file.
1.1 root 98: */
1.1.1.5 root 99: static int MemorySnapShot_fread(MSS_File fhndl, char *buf, int len)
1.1 root 100: {
101: #ifdef COMPRESS_MEMORYSNAPSHOT
1.1.1.5 root 102: return gzread(fhndl, buf, len);
103: #else
104: return fread(buf, 1, len, fhndl);
105: #endif
1.1 root 106: }
107:
1.1.1.5 root 108:
109: /*-----------------------------------------------------------------------*/
1.1 root 110: /*
1.1.1.5 root 111: Write data to file.
1.1 root 112: */
1.1.1.7 root 113: static int MemorySnapShot_fwrite(MSS_File fhndl, const char *buf, int len)
1.1 root 114: {
1.1.1.5 root 115: #ifdef COMPRESS_MEMORYSNAPSHOT
116: return gzwrite(fhndl, buf, len);
117: #else
118: return fwrite(buf, 1, len, fhndl);
119: #endif
1.1 root 120: }
121:
1.1.1.5 root 122:
123: /*-----------------------------------------------------------------------*/
1.1 root 124: /*
1.1.1.5 root 125: Open/Create snapshot file, and set flag so 'MemorySnapShot_Store' knows
126: how to handle data.
1.1 root 127: */
1.1.1.8 ! root 128: static BOOL MemorySnapShot_OpenFile(const char *pszFileName, BOOL bSave)
1.1 root 129: {
1.1.1.5 root 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 */
1.1.1.8 ! root 149: strcpy(VersionString, VERSION_STRING);
! 150: MemorySnapShot_Store(VersionString, VERSION_STRING_SIZE);
1.1.1.5 root 151: }
152: else
153: {
154: /* Restore */
155: CaptureFile = MemorySnapShot_fopen(pszFileName, "rb");
156: if (!CaptureFile)
157: {
158: fprintf(stderr, "Failed to open file '%s': %s\n",
159: pszFileName, strerror(errno));
160: bCaptureError = TRUE;
161: return(FALSE);
162: }
163: bCaptureSave = FALSE;
164: /* Restore version string */
165: MemorySnapShot_Store(VersionString, VERSION_STRING_SIZE);
166: /* Does match current version? */
167: if (strcasecmp(VersionString, VERSION_STRING))
168: {
169: /* No, inform user and error */
1.1.1.8 ! root 170: Log_AlertDlg(LOG_WARN, "Unable to Restore Memory State.\nFile is "
1.1.1.7 root 171: "only compatible with Hatari v%s", VersionString);
1.1.1.5 root 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: */
1.1.1.8 ! root 220: void MemorySnapShot_Capture(const char *pszFileName)
1.1 root 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);
1.1.1.8 ! root 239: DmaSnd_MemorySnapShot_Capture(TRUE);
1.1.1.5 root 240:
241: /* And close */
242: MemorySnapShot_CloseFile();
243: }
244:
245: /* Did error */
246: if (bCaptureError)
1.1.1.7 root 247: Log_AlertDlg(LOG_ERROR, "Unable to save memory state to file.");
1.1.1.5 root 248: else
1.1.1.7 root 249: Log_AlertDlg(LOG_INFO, "Memory state file saved.");
1.1 root 250: }
251:
1.1.1.5 root 252:
253: /*-----------------------------------------------------------------------*/
1.1 root 254: /*
255: Restore 'snapshot' of memory/chips/emulation variables
256: */
1.1.1.8 ! root 257: void MemorySnapShot_Restore(const char *pszFileName)
1.1 root 258: {
1.1.1.5 root 259: /* Set to 'restore' */
260: if (MemorySnapShot_OpenFile(pszFileName,FALSE))
261: {
262: /* Reset emulator to get things running */
263: Reset_Cold();
264:
265: /* Capture each files details */
266: Main_MemorySnapShot_Capture(FALSE);
267: FDC_MemorySnapShot_Capture(FALSE);
268: Floppy_MemorySnapShot_Capture(FALSE);
269: GemDOS_MemorySnapShot_Capture(FALSE);
270: IKBD_MemorySnapShot_Capture(FALSE);
271: Int_MemorySnapShot_Capture(FALSE);
272: M68000_MemorySnapShot_Capture(FALSE);
273: MFP_MemorySnapShot_Capture(FALSE);
274: PSG_MemorySnapShot_Capture(FALSE);
275: Sound_MemorySnapShot_Capture(FALSE);
276: TOS_MemorySnapShot_Capture(FALSE);
277: Video_MemorySnapShot_Capture(FALSE);
278: Blitter_MemorySnapShot_Capture(FALSE);
1.1.1.8 ! root 279: DmaSnd_MemorySnapShot_Capture(FALSE);
1.1.1.5 root 280:
281: /* And close */
282: MemorySnapShot_CloseFile();
283: }
284:
285: /* Did error? */
286: if (bCaptureError)
1.1.1.7 root 287: Log_AlertDlg(LOG_ERROR, "Unable to restore memory state from file.");
1.1.1.5 root 288: else
1.1.1.7 root 289: Log_AlertDlg(LOG_INFO, "Memory state file restored.");
1.1 root 290: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.