Annotation of previous/src/memorySnapShot.c, revision 1.1

1.1     ! root        1: /*
        !             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.
        !             6: 
        !             7:   Memory Snapshot
        !             8: 
        !             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
        !            13:   and such like.
        !            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.
        !            18: */
        !            19: const char MemorySnapShot_fileid[] = "Hatari memorySnapShot.c : " __DATE__ " " __TIME__;
        !            20: 
        !            21: #include <SDL_types.h>
        !            22: #include <errno.h>
        !            23: 
        !            24: #include "main.h"
        !            25: #include "configuration.h"
        !            26: #include "debugui.h"
        !            27: #include "file.h"
        !            28: #include "cycInt.h"
        !            29: #include "cycles.h"
        !            30: #include "ioMem.h"
        !            31: #include "log.h"
        !            32: #include "m68000.h"
        !            33: #include "memorySnapShot.h"
        !            34: #include "reset.h"
        !            35: #include "str.h"
        !            36: #include "nextMemory.h"
        !            37: #include "video.h"
        !            38: 
        !            39: 
        !            40: #define VERSION_STRING      "0.0.1"   /* Version number of compatible memory snapshots - Always 6 bytes (inc' NULL) */
        !            41: #define VERSION_STRING_SIZE    6      /* Size of above (inc' NULL) */
        !            42: 
        !            43: 
        !            44: #define COMPRESS_MEMORYSNAPSHOT       /* Compress snapshots to reduce disk space used */
        !            45: 
        !            46: #ifdef COMPRESS_MEMORYSNAPSHOT
        !            47: 
        !            48: #include <zlib.h>
        !            49: typedef gzFile MSS_File;
        !            50: 
        !            51: #else
        !            52: 
        !            53: typedef FILE* MSS_File;
        !            54: 
        !            55: #endif
        !            56: 
        !            57: 
        !            58: static MSS_File CaptureFile;
        !            59: static bool bCaptureSave, bCaptureError;
        !            60: 
        !            61: 
        !            62: /*-----------------------------------------------------------------------*/
        !            63: /**
        !            64:  * Open file.
        !            65:  */
        !            66: static MSS_File MemorySnapShot_fopen(const char *pszFileName, const char *pszMode)
        !            67: {
        !            68: #ifdef COMPRESS_MEMORYSNAPSHOT
        !            69:        return gzopen(pszFileName, pszMode);
        !            70: #else
        !            71:        return fopen(pszFileName, pszMode);
        !            72: #endif
        !            73: }
        !            74: 
        !            75: 
        !            76: /*-----------------------------------------------------------------------*/
        !            77: /**
        !            78:  * Close file.
        !            79:  */
        !            80: static void MemorySnapShot_fclose(MSS_File fhndl)
        !            81: {
        !            82: #ifdef COMPRESS_MEMORYSNAPSHOT
        !            83:        gzclose(fhndl);
        !            84: #else
        !            85:        fclose(fhndl);
        !            86: #endif
        !            87: }
        !            88: 
        !            89: 
        !            90: /*-----------------------------------------------------------------------*/
        !            91: /**
        !            92:  * Read from file.
        !            93:  */
        !            94: static int MemorySnapShot_fread(MSS_File fhndl, char *buf, int len)
        !            95: {
        !            96: #ifdef COMPRESS_MEMORYSNAPSHOT
        !            97:        return gzread(fhndl, buf, len);
        !            98: #else
        !            99:        return fread(buf, 1, len, fhndl);
        !           100: #endif
        !           101: }
        !           102: 
        !           103: 
        !           104: /*-----------------------------------------------------------------------*/
        !           105: /**
        !           106:  * Write data to file.
        !           107:  */
        !           108: static int MemorySnapShot_fwrite(MSS_File fhndl, const char *buf, int len)
        !           109: {
        !           110: #ifdef COMPRESS_MEMORYSNAPSHOT
        !           111:        return gzwrite(fhndl, buf, len);
        !           112: #else
        !           113:        return fwrite(buf, 1, len, fhndl);
        !           114: #endif
        !           115: }
        !           116: 
        !           117: 
        !           118: /*-----------------------------------------------------------------------*/
        !           119: /**
        !           120:  * Open/Create snapshot file, and set flag so 'MemorySnapShot_Store' knows
        !           121:  * how to handle data.
        !           122:  */
        !           123: static bool MemorySnapShot_OpenFile(const char *pszFileName, bool bSave)
        !           124: {
        !           125:        char VersionString[VERSION_STRING_SIZE];
        !           126: 
        !           127:        /* Set error */
        !           128:        bCaptureError = false;
        !           129: 
        !           130:        /* Open file, set flag so 'MemorySnapShot_Store' can load to/save from file */
        !           131:        if (bSave)
        !           132:        {
        !           133:                /* Save */
        !           134:                CaptureFile = MemorySnapShot_fopen(pszFileName, "wb");
        !           135:                if (!CaptureFile)
        !           136:                {
        !           137:                        fprintf(stderr, "Failed to open save file '%s': %s\n",
        !           138:                                pszFileName, strerror(errno));
        !           139:                        bCaptureError = true;
        !           140:                        return false;
        !           141:                }
        !           142:                bCaptureSave = true;
        !           143:                /* Store version string */
        !           144:                strcpy(VersionString, VERSION_STRING);
        !           145:                MemorySnapShot_Store(VersionString, 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:                        Log_AlertDlg(LOG_ERROR, "Unable to Restore Memory State.\nFile is "
        !           166:                                               "only compatible with Hatari v%s", VersionString);
        !           167:                        bCaptureError = true;
        !           168:                        return false;
        !           169:                }
        !           170:        }
        !           171: 
        !           172:        /* All OK */
        !           173:        return true;
        !           174: }
        !           175: 
        !           176: 
        !           177: /*-----------------------------------------------------------------------*/
        !           178: /**
        !           179:  * Close snapshot file.
        !           180:  */
        !           181: static void MemorySnapShot_CloseFile(void)
        !           182: {
        !           183:        MemorySnapShot_fclose(CaptureFile);
        !           184: }
        !           185: 
        !           186: 
        !           187: /*-----------------------------------------------------------------------*/
        !           188: /**
        !           189:  * Save/Restore data to/from file.
        !           190:  */
        !           191: void MemorySnapShot_Store(void *pData, int Size)
        !           192: {
        !           193:        long nBytes;
        !           194: 
        !           195:        /* Check no file errors */
        !           196:        if (CaptureFile != NULL)
        !           197:        {
        !           198:                /* Saving or Restoring? */
        !           199:                if (bCaptureSave)
        !           200:                        nBytes = MemorySnapShot_fwrite(CaptureFile, (char *)pData, Size);
        !           201:                else
        !           202:                        nBytes = MemorySnapShot_fread(CaptureFile, (char *)pData, Size);
        !           203: 
        !           204:                /* Did save OK? */
        !           205:                if (nBytes != Size)
        !           206:                        bCaptureError = true;
        !           207:        }
        !           208: }
        !           209: 
        !           210: 
        !           211: /*-----------------------------------------------------------------------*/
        !           212: /**
        !           213:  * Save 'snapshot' of memory/chips/emulation variables
        !           214:  */
        !           215: void MemorySnapShot_Capture(const char *pszFileName, bool bConfirm)
        !           216: {
        !           217:        /* Set to 'saving' */
        !           218:        if (MemorySnapShot_OpenFile(pszFileName, true))
        !           219:        {
        !           220:                /* Capture each files details */
        !           221:                Configuration_MemorySnapShot_Capture(true);
        !           222: //             STMemory_MemorySnapShot_Capture(true);
        !           223:                CycInt_MemorySnapShot_Capture(true);
        !           224:                Cycles_MemorySnapShot_Capture(true);
        !           225:                M68000_MemorySnapShot_Capture(true);
        !           226:                Video_MemorySnapShot_Capture(true);
        !           227:                DebugUI_MemorySnapShot_Capture(pszFileName, true);
        !           228: 
        !           229:                /* And close */
        !           230:                MemorySnapShot_CloseFile();
        !           231:        }
        !           232: 
        !           233:        /* Did error */
        !           234:        if (bCaptureError)
        !           235:                Log_AlertDlg(LOG_ERROR, "Unable to save memory state to file.");
        !           236:        else if (bConfirm)
        !           237:                Log_AlertDlg(LOG_INFO, "Memory state file saved.");
        !           238: }
        !           239: 
        !           240: 
        !           241: /*-----------------------------------------------------------------------*/
        !           242: /**
        !           243:  * Restore 'snapshot' of memory/chips/emulation variables
        !           244:  */
        !           245: void MemorySnapShot_Restore(const char *pszFileName, bool bConfirm)
        !           246: {
        !           247:        /* Set to 'restore' */
        !           248:        if (MemorySnapShot_OpenFile(pszFileName, false))
        !           249:        {
        !           250:                Configuration_MemorySnapShot_Capture(false);
        !           251: 
        !           252:                /* Reset emulator to get things running */
        !           253:                IoMem_UnInit();  IoMem_Init();
        !           254:                Reset_Cold();
        !           255: 
        !           256:                /* Capture each files details */
        !           257: //             STMemory_MemorySnapShot_Capture(false);
        !           258:                CycInt_MemorySnapShot_Capture(false);
        !           259:                Cycles_MemorySnapShot_Capture(false);
        !           260:                M68000_MemorySnapShot_Capture(false);
        !           261:                Video_MemorySnapShot_Capture(false);
        !           262:                DebugUI_MemorySnapShot_Capture(pszFileName, false);
        !           263: 
        !           264:                /* And close */
        !           265:                MemorySnapShot_CloseFile();
        !           266:        }
        !           267: 
        !           268:        /* Did error? */
        !           269:        if (bCaptureError)
        !           270:                Log_AlertDlg(LOG_ERROR, "Unable to restore memory state from file.");
        !           271:        else if (bConfirm)
        !           272:                Log_AlertDlg(LOG_INFO, "Memory state file restored.");
        !           273: }
        !           274: 
        !           275: 
        !           276: /*-----------------------------------------------------------------------*/
        !           277: /*
        !           278:  * Save and restore functions required by the UAE CPU core...
        !           279:  * ... don't use them in normal Hatari code!
        !           280:  */
        !           281: #include <savestate.h>
        !           282: 
        !           283: void save_u32(uae_u32 data)
        !           284: {
        !           285:        MemorySnapShot_Store(&data, 4);
        !           286: }
        !           287: 
        !           288: void save_u16(uae_u16 data)
        !           289: {
        !           290:        MemorySnapShot_Store(&data, 2);
        !           291: }
        !           292: 
        !           293: uae_u32 restore_u32(void)
        !           294: {
        !           295:        uae_u32 data;
        !           296:        MemorySnapShot_Store(&data, 4);
        !           297:        return data;
        !           298: }
        !           299: 
        !           300: uae_u16 restore_u16(void)
        !           301: {
        !           302:        uae_u16 data;
        !           303:        MemorySnapShot_Store(&data, 2);
        !           304:        return data;
        !           305: }

unix.superglobalmegacorp.com

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