Annotation of hatari/src/memorySnapShot.c, revision 1.1.1.7

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.7 ! root       19: char MemorySnapShot_rcsid[] = "Hatari $Id: memorySnapShot.c,v 1.14 2005/06/05 17:01:39 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 "dialog.h"
                     27: #include "fdc.h"
                     28: #include "file.h"
                     29: #include "floppy.h"
                     30: #include "gemdos.h"
                     31: #include "ikbd.h"
                     32: #include "int.h"
1.1.1.7 ! root       33: #include "log.h"
1.1       root       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.7 ! root       44: #define VERSION_STRING      "0.70 "   /* Version number of compatible memory snapshots - Always 6 bytes (inc' NULL) */
1.1.1.6   root       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.7 ! root       70: static MSS_File MemorySnapShot_fopen(const char *pszFileName, const 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.7 ! root      112: static int MemorySnapShot_fwrite(MSS_File fhndl, const 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 VersionString[VERSION_STRING_SIZE];
1.1.1.3   root      130: 
1.1.1.5   root      131:        /* Set error */
                    132:        bCaptureError = FALSE;
1.1       root      133: 
1.1.1.5   root      134:        /* Open file, set flag so 'MemorySnapShot_Store' can load to/save from file */
                    135:        if (bSave)
                    136:        {
                    137:                /* Save */
                    138:                CaptureFile = MemorySnapShot_fopen(pszFileName, "wb");
                    139:                if (!CaptureFile)
                    140:                {
                    141:                        fprintf(stderr, "Failed to open save file '%s': %s\n",
                    142:                                pszFileName, strerror(errno));
                    143:                        bCaptureError = TRUE;
                    144:                        return(FALSE);
                    145:                }
                    146:                bCaptureSave = TRUE;
                    147:                /* Store version string */
                    148:                MemorySnapShot_Store(VERSION_STRING, VERSION_STRING_SIZE);
                    149:        }
                    150:        else
                    151:        {
                    152:                /* Restore */
                    153:                CaptureFile = MemorySnapShot_fopen(pszFileName, "rb");
                    154:                if (!CaptureFile)
                    155:                {
                    156:                        fprintf(stderr, "Failed to open file '%s': %s\n",
                    157:                                pszFileName, strerror(errno));
                    158:                        bCaptureError = TRUE;
                    159:                        return(FALSE);
                    160:                }
                    161:                bCaptureSave = FALSE;
                    162:                /* Restore version string */
                    163:                MemorySnapShot_Store(VersionString, VERSION_STRING_SIZE);
                    164:                /* Does match current version? */
                    165:                if (strcasecmp(VersionString, VERSION_STRING))
                    166:                {
                    167:                        /* No, inform user and error */
1.1.1.7 ! root      168:                        Log_AlertDlg(LOG_WARN, "Unable to Restore Memory State.\nFile is"
        !           169:                                               "only compatible with Hatari v%s", VersionString);
1.1.1.5   root      170:                        bCaptureError = TRUE;
                    171:                        return(FALSE);
                    172:                }
                    173:        }
1.1       root      174: 
1.1.1.5   root      175:        /* All OK */
                    176:        return(TRUE);
1.1       root      177: }
                    178: 
1.1.1.5   root      179: 
                    180: /*-----------------------------------------------------------------------*/
1.1       root      181: /*
1.1.1.5   root      182:   Close snapshot file.
1.1       root      183: */
1.1.1.5   root      184: static void MemorySnapShot_CloseFile(void)
1.1       root      185: {
1.1.1.5   root      186:        MemorySnapShot_fclose(CaptureFile);
1.1       root      187: }
                    188: 
1.1.1.5   root      189: 
                    190: /*-----------------------------------------------------------------------*/
1.1       root      191: /*
1.1.1.5   root      192:   Save/Restore data to/from file.
1.1       root      193: */
                    194: void MemorySnapShot_Store(void *pData, int Size)
                    195: {
1.1.1.5   root      196:        long nBytes;
1.1.1.3   root      197: 
1.1.1.5   root      198:        /* Check no file errors */
                    199:        if (CaptureFile != NULL)
                    200:        {
                    201:                /* Saving or Restoring? */
                    202:                if (bCaptureSave)
                    203:                        nBytes = MemorySnapShot_fwrite(CaptureFile, (char *)pData, Size);
                    204:                else
                    205:                        nBytes = MemorySnapShot_fread(CaptureFile, (char *)pData, Size);
                    206: 
                    207:                /* Did save OK? */
                    208:                if (nBytes != Size)
                    209:                        bCaptureError = TRUE;
                    210:        }
1.1       root      211: }
                    212: 
1.1.1.5   root      213: 
                    214: /*-----------------------------------------------------------------------*/
1.1       root      215: /*
                    216:   Save 'snapshot' of memory/chips/emulation variables
                    217: */
                    218: void MemorySnapShot_Capture(char *pszFileName)
                    219: {
1.1.1.5   root      220:        /* Set to 'saving' */
                    221:        if (MemorySnapShot_OpenFile(pszFileName,TRUE))
                    222:        {
                    223:                /* Capture each files details */
                    224:                Main_MemorySnapShot_Capture(TRUE);
                    225:                FDC_MemorySnapShot_Capture(TRUE);
                    226:                Floppy_MemorySnapShot_Capture(TRUE);
                    227:                GemDOS_MemorySnapShot_Capture(TRUE);
                    228:                IKBD_MemorySnapShot_Capture(TRUE);
                    229:                Int_MemorySnapShot_Capture(TRUE);
                    230:                M68000_MemorySnapShot_Capture(TRUE);
                    231:                MFP_MemorySnapShot_Capture(TRUE);
                    232:                PSG_MemorySnapShot_Capture(TRUE);
                    233:                Sound_MemorySnapShot_Capture(TRUE);
                    234:                TOS_MemorySnapShot_Capture(TRUE);
                    235:                Video_MemorySnapShot_Capture(TRUE);
                    236:                Blitter_MemorySnapShot_Capture(TRUE);
                    237: 
                    238:                /* And close */
                    239:                MemorySnapShot_CloseFile();
                    240:        }
                    241: 
                    242:        /* Did error */
                    243:        if (bCaptureError)
1.1.1.7 ! root      244:                Log_AlertDlg(LOG_ERROR, "Unable to save memory state to file.");
1.1.1.5   root      245:        else
1.1.1.7 ! root      246:                Log_AlertDlg(LOG_INFO, "Memory state file saved.");
1.1       root      247: }
                    248: 
1.1.1.5   root      249: 
                    250: /*-----------------------------------------------------------------------*/
1.1       root      251: /*
                    252:   Restore 'snapshot' of memory/chips/emulation variables
                    253: */
                    254: void MemorySnapShot_Restore(char *pszFileName)
                    255: {
1.1.1.5   root      256:        /* Set to 'restore' */
                    257:        if (MemorySnapShot_OpenFile(pszFileName,FALSE))
                    258:        {
                    259:                /* Reset emulator to get things running */
                    260:                Reset_Cold();
                    261: 
                    262:                /* Capture each files details */
                    263:                Main_MemorySnapShot_Capture(FALSE);
                    264:                FDC_MemorySnapShot_Capture(FALSE);
                    265:                Floppy_MemorySnapShot_Capture(FALSE);
                    266:                GemDOS_MemorySnapShot_Capture(FALSE);
                    267:                IKBD_MemorySnapShot_Capture(FALSE);
                    268:                Int_MemorySnapShot_Capture(FALSE);
                    269:                M68000_MemorySnapShot_Capture(FALSE);
                    270:                MFP_MemorySnapShot_Capture(FALSE);
                    271:                PSG_MemorySnapShot_Capture(FALSE);
                    272:                Sound_MemorySnapShot_Capture(FALSE);
                    273:                TOS_MemorySnapShot_Capture(FALSE);
                    274:                Video_MemorySnapShot_Capture(FALSE);
                    275:                Blitter_MemorySnapShot_Capture(FALSE);
                    276: 
                    277:                /* And close */
                    278:                MemorySnapShot_CloseFile();
                    279:        }
                    280: 
                    281:        /* Did error? */
                    282:        if (bCaptureError)
1.1.1.7 ! root      283:                Log_AlertDlg(LOG_ERROR, "Unable to restore memory state from file.");
1.1.1.5   root      284:        else
1.1.1.7 ! root      285:                Log_AlertDlg(LOG_INFO, "Memory state file restored.");
1.1       root      286: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.