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

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.10! root       19: const char MemorySnapShot_rcsid[] = "Hatari $Id: memorySnapShot.c,v 1.37 2008/02/24 20:10:47 thothy Exp $";
        !            20: 
        !            21: #include <config.h>
1.1.1.4   root       22: 
                     23: #include <SDL_types.h>
1.1.1.9   root       24: #include <string.h>
1.1.1.5   root       25: #include <errno.h>
1.1       root       26: 
1.1.1.10! root       27: #if HAVE_STRINGS_H
        !            28: #include <strings.h>
        !            29: #endif
        !            30: 
1.1       root       31: #include "main.h"
1.1.1.5   root       32: #include "blitter.h"
1.1.1.8   root       33: #include "configuration.h"
                     34: #include "dmaSnd.h"
1.1       root       35: #include "fdc.h"
                     36: #include "file.h"
                     37: #include "floppy.h"
                     38: #include "gemdos.h"
                     39: #include "ikbd.h"
                     40: #include "int.h"
1.1.1.10! root       41: #include "ioMem.h"
1.1.1.7   root       42: #include "log.h"
1.1       root       43: #include "m68000.h"
                     44: #include "memorySnapShot.h"
                     45: #include "mfp.h"
                     46: #include "psg.h"
                     47: #include "reset.h"
                     48: #include "sound.h"
                     49: #include "tos.h"
                     50: #include "video.h"
1.1.1.2   root       51: 
1.1       root       52: 
1.1.1.10! root       53: #define VERSION_STRING      "1.0.0"   /* Version number of compatible memory snapshots - Always 6 bytes (inc' NULL) */
1.1.1.6   root       54: #define VERSION_STRING_SIZE    6      /* Size of above (inc' NULL) */
                     55: 
                     56: 
1.1.1.8   root       57: #define COMPRESS_MEMORYSNAPSHOT       /* Compress snapshots to reduce disk space used */
1.1       root       58: 
1.1.1.5   root       59: #ifdef COMPRESS_MEMORYSNAPSHOT
1.1       root       60: 
1.1.1.5   root       61: #include <zlib.h>
                     62: typedef gzFile MSS_File;
                     63: 
                     64: #else
                     65: 
                     66: typedef FILE* MSS_File;
1.1       root       67: 
1.1.1.5   root       68: #endif
                     69: 
                     70: 
                     71: static MSS_File CaptureFile;
                     72: static BOOL bCaptureSave, bCaptureError;
                     73: 
                     74: 
                     75: /*-----------------------------------------------------------------------*/
1.1.1.10! root       76: /**
        !            77:  * Open file.
        !            78:  */
1.1.1.7   root       79: static MSS_File MemorySnapShot_fopen(const char *pszFileName, const char *pszMode)
1.1       root       80: {
                     81: #ifdef COMPRESS_MEMORYSNAPSHOT
1.1.1.5   root       82:        return gzopen(pszFileName, pszMode);
                     83: #else
                     84:        return fopen(pszFileName, pszMode);
                     85: #endif
1.1       root       86: }
                     87: 
1.1.1.5   root       88: 
                     89: /*-----------------------------------------------------------------------*/
1.1.1.10! root       90: /**
        !            91:  * Close file.
        !            92:  */
1.1.1.5   root       93: static void MemorySnapShot_fclose(MSS_File fhndl)
1.1       root       94: {
                     95: #ifdef COMPRESS_MEMORYSNAPSHOT
1.1.1.5   root       96:        gzclose(fhndl);
                     97: #else
                     98:        fclose(fhndl);
                     99: #endif
1.1       root      100: }
                    101: 
1.1.1.5   root      102: 
                    103: /*-----------------------------------------------------------------------*/
1.1.1.10! root      104: /**
        !           105:  * Read from file.
        !           106:  */
1.1.1.5   root      107: static int MemorySnapShot_fread(MSS_File fhndl, char *buf, int len)
1.1       root      108: {
                    109: #ifdef COMPRESS_MEMORYSNAPSHOT
1.1.1.5   root      110:        return gzread(fhndl, buf, len);
                    111: #else
                    112:        return fread(buf, 1, len, fhndl);
                    113: #endif
1.1       root      114: }
                    115: 
1.1.1.5   root      116: 
                    117: /*-----------------------------------------------------------------------*/
1.1.1.10! root      118: /**
        !           119:  * Write data to file.
        !           120:  */
1.1.1.7   root      121: static int MemorySnapShot_fwrite(MSS_File fhndl, const char *buf, int len)
1.1       root      122: {
1.1.1.5   root      123: #ifdef COMPRESS_MEMORYSNAPSHOT
                    124:        return gzwrite(fhndl, buf, len);
                    125: #else
                    126:        return fwrite(buf, 1, len, fhndl);
                    127: #endif
1.1       root      128: }
                    129: 
1.1.1.5   root      130: 
                    131: /*-----------------------------------------------------------------------*/
1.1.1.10! root      132: /**
        !           133:  * Open/Create snapshot file, and set flag so 'MemorySnapShot_Store' knows
        !           134:  * how to handle data.
        !           135:  */
1.1.1.8   root      136: static BOOL MemorySnapShot_OpenFile(const char *pszFileName, BOOL bSave)
1.1       root      137: {
1.1.1.5   root      138:        char VersionString[VERSION_STRING_SIZE];
1.1.1.3   root      139: 
1.1.1.5   root      140:        /* Set error */
                    141:        bCaptureError = FALSE;
1.1       root      142: 
1.1.1.5   root      143:        /* Open file, set flag so 'MemorySnapShot_Store' can load to/save from file */
                    144:        if (bSave)
                    145:        {
                    146:                /* Save */
                    147:                CaptureFile = MemorySnapShot_fopen(pszFileName, "wb");
                    148:                if (!CaptureFile)
                    149:                {
                    150:                        fprintf(stderr, "Failed to open save file '%s': %s\n",
                    151:                                pszFileName, strerror(errno));
                    152:                        bCaptureError = TRUE;
                    153:                        return(FALSE);
                    154:                }
                    155:                bCaptureSave = TRUE;
                    156:                /* Store version string */
1.1.1.8   root      157:                strcpy(VersionString, VERSION_STRING);
                    158:                MemorySnapShot_Store(VersionString, VERSION_STRING_SIZE);
1.1.1.5   root      159:        }
                    160:        else
                    161:        {
                    162:                /* Restore */
                    163:                CaptureFile = MemorySnapShot_fopen(pszFileName, "rb");
                    164:                if (!CaptureFile)
                    165:                {
                    166:                        fprintf(stderr, "Failed to open file '%s': %s\n",
                    167:                                pszFileName, strerror(errno));
                    168:                        bCaptureError = TRUE;
                    169:                        return(FALSE);
                    170:                }
                    171:                bCaptureSave = FALSE;
                    172:                /* Restore version string */
                    173:                MemorySnapShot_Store(VersionString, VERSION_STRING_SIZE);
                    174:                /* Does match current version? */
                    175:                if (strcasecmp(VersionString, VERSION_STRING))
                    176:                {
                    177:                        /* No, inform user and error */
1.1.1.8   root      178:                        Log_AlertDlg(LOG_WARN, "Unable to Restore Memory State.\nFile is "
1.1.1.7   root      179:                                               "only compatible with Hatari v%s", VersionString);
1.1.1.5   root      180:                        bCaptureError = TRUE;
                    181:                        return(FALSE);
                    182:                }
                    183:        }
1.1       root      184: 
1.1.1.5   root      185:        /* All OK */
                    186:        return(TRUE);
1.1       root      187: }
                    188: 
1.1.1.5   root      189: 
                    190: /*-----------------------------------------------------------------------*/
1.1.1.10! root      191: /**
        !           192:  * Close snapshot file.
        !           193:  */
1.1.1.5   root      194: static void MemorySnapShot_CloseFile(void)
1.1       root      195: {
1.1.1.5   root      196:        MemorySnapShot_fclose(CaptureFile);
1.1       root      197: }
                    198: 
1.1.1.5   root      199: 
                    200: /*-----------------------------------------------------------------------*/
1.1.1.10! root      201: /**
        !           202:  * Save/Restore data to/from file.
        !           203:  */
1.1       root      204: void MemorySnapShot_Store(void *pData, int Size)
                    205: {
1.1.1.5   root      206:        long nBytes;
1.1.1.3   root      207: 
1.1.1.5   root      208:        /* Check no file errors */
                    209:        if (CaptureFile != NULL)
                    210:        {
                    211:                /* Saving or Restoring? */
                    212:                if (bCaptureSave)
                    213:                        nBytes = MemorySnapShot_fwrite(CaptureFile, (char *)pData, Size);
                    214:                else
                    215:                        nBytes = MemorySnapShot_fread(CaptureFile, (char *)pData, Size);
                    216: 
                    217:                /* Did save OK? */
                    218:                if (nBytes != Size)
                    219:                        bCaptureError = TRUE;
                    220:        }
1.1       root      221: }
                    222: 
1.1.1.5   root      223: 
                    224: /*-----------------------------------------------------------------------*/
1.1.1.10! root      225: /**
        !           226:  * Save 'snapshot' of memory/chips/emulation variables
        !           227:  */
        !           228: void MemorySnapShot_Capture(const char *pszFileName, BOOL bConfirm)
1.1       root      229: {
1.1.1.5   root      230:        /* Set to 'saving' */
                    231:        if (MemorySnapShot_OpenFile(pszFileName,TRUE))
                    232:        {
                    233:                /* Capture each files details */
1.1.1.10! root      234:                Configuration_MemorySnapShot_Capture(TRUE);
        !           235:                TOS_MemorySnapShot_Capture(TRUE);
1.1.1.5   root      236:                Main_MemorySnapShot_Capture(TRUE);
                    237:                FDC_MemorySnapShot_Capture(TRUE);
                    238:                Floppy_MemorySnapShot_Capture(TRUE);
                    239:                GemDOS_MemorySnapShot_Capture(TRUE);
                    240:                IKBD_MemorySnapShot_Capture(TRUE);
                    241:                Int_MemorySnapShot_Capture(TRUE);
                    242:                M68000_MemorySnapShot_Capture(TRUE);
                    243:                MFP_MemorySnapShot_Capture(TRUE);
                    244:                PSG_MemorySnapShot_Capture(TRUE);
                    245:                Sound_MemorySnapShot_Capture(TRUE);
                    246:                Video_MemorySnapShot_Capture(TRUE);
                    247:                Blitter_MemorySnapShot_Capture(TRUE);
1.1.1.8   root      248:                DmaSnd_MemorySnapShot_Capture(TRUE);
1.1.1.5   root      249: 
                    250:                /* And close */
                    251:                MemorySnapShot_CloseFile();
                    252:        }
                    253: 
                    254:        /* Did error */
                    255:        if (bCaptureError)
1.1.1.7   root      256:                Log_AlertDlg(LOG_ERROR, "Unable to save memory state to file.");
1.1.1.10! root      257:        else if (bConfirm)
1.1.1.7   root      258:                Log_AlertDlg(LOG_INFO, "Memory state file saved.");
1.1       root      259: }
                    260: 
1.1.1.5   root      261: 
                    262: /*-----------------------------------------------------------------------*/
1.1.1.10! root      263: /**
        !           264:  * Restore 'snapshot' of memory/chips/emulation variables
        !           265:  */
        !           266: void MemorySnapShot_Restore(const char *pszFileName, BOOL bConfirm)
1.1       root      267: {
1.1.1.5   root      268:        /* Set to 'restore' */
                    269:        if (MemorySnapShot_OpenFile(pszFileName,FALSE))
                    270:        {
1.1.1.10! root      271:                Configuration_MemorySnapShot_Capture(FALSE);
        !           272:                TOS_MemorySnapShot_Capture(FALSE);
        !           273: 
1.1.1.5   root      274:                /* Reset emulator to get things running */
1.1.1.10! root      275:                IoMem_UnInit();  IoMem_Init();
1.1.1.5   root      276:                Reset_Cold();
                    277: 
                    278:                /* Capture each files details */
                    279:                Main_MemorySnapShot_Capture(FALSE);
                    280:                FDC_MemorySnapShot_Capture(FALSE);
                    281:                Floppy_MemorySnapShot_Capture(FALSE);
                    282:                GemDOS_MemorySnapShot_Capture(FALSE);
                    283:                IKBD_MemorySnapShot_Capture(FALSE);
                    284:                Int_MemorySnapShot_Capture(FALSE);
                    285:                M68000_MemorySnapShot_Capture(FALSE);
                    286:                MFP_MemorySnapShot_Capture(FALSE);
                    287:                PSG_MemorySnapShot_Capture(FALSE);
                    288:                Sound_MemorySnapShot_Capture(FALSE);
                    289:                Video_MemorySnapShot_Capture(FALSE);
                    290:                Blitter_MemorySnapShot_Capture(FALSE);
1.1.1.8   root      291:                DmaSnd_MemorySnapShot_Capture(FALSE);
1.1.1.5   root      292: 
                    293:                /* And close */
                    294:                MemorySnapShot_CloseFile();
                    295:        }
                    296: 
                    297:        /* Did error? */
                    298:        if (bCaptureError)
1.1.1.7   root      299:                Log_AlertDlg(LOG_ERROR, "Unable to restore memory state from file.");
1.1.1.10! root      300:        else if (bConfirm)
1.1.1.7   root      301:                Log_AlertDlg(LOG_INFO, "Memory state file restored.");
1.1       root      302: }
1.1.1.10! root      303: 
        !           304: 
        !           305: /*-----------------------------------------------------------------------*/
        !           306: /*
        !           307:  * Save and restore functions required by the UAE CPU core...
        !           308:  * ... don't use them in normal Hatari code!
        !           309:  */
        !           310: #include <savestate.h>
        !           311: 
        !           312: void save_u32(uae_u32 data)
        !           313: {
        !           314:        MemorySnapShot_Store(&data, 4);
        !           315: }
        !           316: 
        !           317: void save_u16(uae_u16 data)
        !           318: {
        !           319:        MemorySnapShot_Store(&data, 2);
        !           320: }
        !           321: 
        !           322: uae_u32 restore_u32(void)
        !           323: {
        !           324:        uae_u32 data;
        !           325:        MemorySnapShot_Store(&data, 4);
        !           326:        return data;
        !           327: }
        !           328: 
        !           329: uae_u16 restore_u16(void)
        !           330: {
        !           331:        uae_u16 data;
        !           332:        MemorySnapShot_Store(&data, 2);
        !           333:        return data;
        !           334: }

unix.superglobalmegacorp.com

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