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