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

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

unix.superglobalmegacorp.com

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