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

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"
1.1.1.2   root       37: #include "screen.h"
1.1       root       38: #include "video.h"
1.1.1.2   root       39: #include "statusbar.h"
1.1       root       40: 
                     41: 
                     42: #define VERSION_STRING      "0.0.1"   /* Version number of compatible memory snapshots - Always 6 bytes (inc' NULL) */
                     43: 
                     44: #define COMPRESS_MEMORYSNAPSHOT       /* Compress snapshots to reduce disk space used */
                     45: 
                     46: #ifdef COMPRESS_MEMORYSNAPSHOT
                     47: 
1.1.1.2   root       48: /* Remove possible conflicting mkdir declaration from cpu/sysdeps.h */
                     49: #undef mkdir
1.1       root       50: #include <zlib.h>
                     51: typedef gzFile MSS_File;
                     52: 
                     53: #else
                     54: 
                     55: typedef FILE* MSS_File;
                     56: 
                     57: #endif
                     58: 
                     59: 
                     60: static MSS_File CaptureFile;
                     61: static bool bCaptureSave, bCaptureError;
                     62: 
                     63: 
                     64: /*-----------------------------------------------------------------------*/
                     65: /**
                     66:  * Open file.
                     67:  */
                     68: static MSS_File MemorySnapShot_fopen(const char *pszFileName, const char *pszMode)
                     69: {
                     70: #ifdef COMPRESS_MEMORYSNAPSHOT
                     71:        return gzopen(pszFileName, pszMode);
                     72: #else
                     73:        return fopen(pszFileName, pszMode);
                     74: #endif
                     75: }
                     76: 
                     77: 
                     78: /*-----------------------------------------------------------------------*/
                     79: /**
                     80:  * Close file.
                     81:  */
                     82: static void MemorySnapShot_fclose(MSS_File fhndl)
                     83: {
                     84: #ifdef COMPRESS_MEMORYSNAPSHOT
                     85:        gzclose(fhndl);
                     86: #else
                     87:        fclose(fhndl);
                     88: #endif
                     89: }
                     90: 
                     91: 
                     92: /*-----------------------------------------------------------------------*/
                     93: /**
                     94:  * Read from file.
                     95:  */
                     96: static int MemorySnapShot_fread(MSS_File fhndl, char *buf, int len)
                     97: {
                     98: #ifdef COMPRESS_MEMORYSNAPSHOT
                     99:        return gzread(fhndl, buf, len);
                    100: #else
                    101:        return fread(buf, 1, len, fhndl);
                    102: #endif
                    103: }
                    104: 
                    105: 
                    106: /*-----------------------------------------------------------------------*/
                    107: /**
                    108:  * Write data to file.
                    109:  */
                    110: static int MemorySnapShot_fwrite(MSS_File fhndl, const char *buf, int len)
                    111: {
                    112: #ifdef COMPRESS_MEMORYSNAPSHOT
                    113:        return gzwrite(fhndl, buf, len);
                    114: #else
                    115:        return fwrite(buf, 1, len, fhndl);
                    116: #endif
                    117: }
                    118: 
                    119: 
                    120: /*-----------------------------------------------------------------------*/
                    121: /**
                    122:  * Open/Create snapshot file, and set flag so 'MemorySnapShot_Store' knows
                    123:  * how to handle data.
                    124:  */
                    125: static bool MemorySnapShot_OpenFile(const char *pszFileName, bool bSave)
                    126: {
1.1.1.2   root      127:        char VersionString[] = VERSION_STRING;
1.1       root      128: 
                    129:        /* Set error */
                    130:        bCaptureError = false;
                    131: 
1.1.1.2   root      132:        /* after opening file, set bCaptureSave to indicate whether
                    133:         * 'MemorySnapShot_Store' should load from or save to a file
                    134:         */
1.1       root      135:        if (bSave)
                    136:        {
1.1.1.2   root      137:                if (!File_QueryOverwrite(pszFileName))
                    138:                        return false;
                    139: 
1.1       root      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.2   root      151:                MemorySnapShot_Store(VersionString, sizeof(VersionString));
1.1       root      152:        }
                    153:        else
                    154:        {
                    155:                /* Restore */
                    156:                CaptureFile = MemorySnapShot_fopen(pszFileName, "rb");
                    157:                if (!CaptureFile)
                    158:                {
                    159:                        fprintf(stderr, "Failed to open file '%s': %s\n",
                    160:                                pszFileName, strerror(errno));
                    161:                        bCaptureError = true;
                    162:                        return false;
                    163:                }
                    164:                bCaptureSave = false;
                    165:                /* Restore version string */
1.1.1.2   root      166:                MemorySnapShot_Store(VersionString, sizeof(VersionString));
1.1       root      167:                /* Does match current version? */
                    168:                if (strcasecmp(VersionString, VERSION_STRING))
                    169:                {
                    170:                        /* No, inform user and error */
1.1.1.2   root      171:                        Log_AlertDlg(LOG_ERROR, "Unable to restore Hatari memory state. File\n"
                    172:                                               "is compatible only with Hatari version %s.",
                    173:                                     VersionString);
1.1       root      174:                        bCaptureError = true;
                    175:                        return false;
                    176:                }
                    177:        }
                    178: 
                    179:        /* All OK */
                    180:        return true;
                    181: }
                    182: 
                    183: 
                    184: /*-----------------------------------------------------------------------*/
                    185: /**
                    186:  * Close snapshot file.
                    187:  */
                    188: static void MemorySnapShot_CloseFile(void)
                    189: {
                    190:        MemorySnapShot_fclose(CaptureFile);
                    191: }
                    192: 
                    193: 
                    194: /*-----------------------------------------------------------------------*/
                    195: /**
                    196:  * Save/Restore data to/from file.
                    197:  */
                    198: void MemorySnapShot_Store(void *pData, int Size)
                    199: {
                    200:        long nBytes;
                    201: 
                    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:        }
                    215: }
                    216: 
                    217: 
                    218: /*-----------------------------------------------------------------------*/
                    219: /**
                    220:  * Save 'snapshot' of memory/chips/emulation variables
                    221:  */
                    222: void MemorySnapShot_Capture(const char *pszFileName, bool bConfirm)
                    223: {
                    224:        /* Set to 'saving' */
                    225:        if (MemorySnapShot_OpenFile(pszFileName, true))
                    226:        {
                    227:                /* Capture each files details */
                    228:                Configuration_MemorySnapShot_Capture(true);
                    229: //             STMemory_MemorySnapShot_Capture(true);
                    230:                CycInt_MemorySnapShot_Capture(true);
                    231:                Cycles_MemorySnapShot_Capture(true);
                    232:                M68000_MemorySnapShot_Capture(true);
                    233:                Video_MemorySnapShot_Capture(true);
                    234:                DebugUI_MemorySnapShot_Capture(pszFileName, true);
1.1.1.2   root      235: //             IoMem_MemorySnapShot_Capture(true);
1.1       root      236:                /* And close */
                    237:                MemorySnapShot_CloseFile();
1.1.1.2   root      238:        } else {
                    239:                /* just canceled? */
                    240:                if (!bCaptureError)
                    241:                        return;
1.1       root      242:        }
                    243: 
                    244:        /* Did error */
                    245:        if (bCaptureError)
                    246:                Log_AlertDlg(LOG_ERROR, "Unable to save memory state to file.");
                    247:        else if (bConfirm)
                    248:                Log_AlertDlg(LOG_INFO, "Memory state file saved.");
                    249: }
                    250: 
                    251: 
                    252: /*-----------------------------------------------------------------------*/
                    253: /**
                    254:  * Restore 'snapshot' of memory/chips/emulation variables
                    255:  */
                    256: void MemorySnapShot_Restore(const char *pszFileName, bool bConfirm)
                    257: {
                    258:        /* Set to 'restore' */
                    259:        if (MemorySnapShot_OpenFile(pszFileName, false))
                    260:        {
                    261:                Configuration_MemorySnapShot_Capture(false);
                    262: 
                    263:                /* Reset emulator to get things running */
                    264:                IoMem_UnInit();  IoMem_Init();
                    265:                Reset_Cold();
                    266: 
                    267:                /* Capture each files details */
                    268: //             STMemory_MemorySnapShot_Capture(false);
                    269:                CycInt_MemorySnapShot_Capture(false);
                    270:                Cycles_MemorySnapShot_Capture(false);
                    271:                M68000_MemorySnapShot_Capture(false);
                    272:                Video_MemorySnapShot_Capture(false);
                    273:                DebugUI_MemorySnapShot_Capture(pszFileName, false);
1.1.1.2   root      274: //             IoMem_MemorySnapShot_Capture(false);
1.1       root      275: 
                    276:                /* And close */
                    277:                MemorySnapShot_CloseFile();
1.1.1.2   root      278: 
                    279:                /* changes may affect also info shown in statusbar */
                    280:                Statusbar_UpdateInfo();
1.1       root      281:        }
                    282: 
                    283:        /* Did error? */
                    284:        if (bCaptureError)
                    285:                Log_AlertDlg(LOG_ERROR, "Unable to restore memory state from file.");
                    286:        else if (bConfirm)
                    287:                Log_AlertDlg(LOG_INFO, "Memory state file restored.");
                    288: }
                    289: 
                    290: 
                    291: /*-----------------------------------------------------------------------*/
                    292: /*
                    293:  * Save and restore functions required by the UAE CPU core...
                    294:  * ... don't use them in normal Hatari code!
                    295:  */
                    296: #include <savestate.h>
                    297: 
                    298: void save_u32(uae_u32 data)
                    299: {
                    300:        MemorySnapShot_Store(&data, 4);
                    301: }
                    302: 
                    303: void save_u16(uae_u16 data)
                    304: {
                    305:        MemorySnapShot_Store(&data, 2);
                    306: }
                    307: 
                    308: uae_u32 restore_u32(void)
                    309: {
                    310:        uae_u32 data;
                    311:        MemorySnapShot_Store(&data, 4);
                    312:        return data;
                    313: }
                    314: 
                    315: uae_u16 restore_u16(void)
                    316: {
                    317:        uae_u16 data;
                    318:        MemorySnapShot_Store(&data, 2);
                    319:        return data;
                    320: }

unix.superglobalmegacorp.com

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