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

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: }

unix.superglobalmegacorp.com

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