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

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);
1.1.1.2 ! root      229: //             TOS_MemorySnapShot_Capture(true);
1.1       root      230: //             STMemory_MemorySnapShot_Capture(true);
1.1.1.2 ! root      231: //             FDC_MemorySnapShot_Capture(true);
        !           232: //             Floppy_MemorySnapShot_Capture(true);
        !           233: //             GemDOS_MemorySnapShot_Capture(true);
        !           234: //             IKBD_MemorySnapShot_Capture(true);
1.1       root      235:                CycInt_MemorySnapShot_Capture(true);
                    236:                Cycles_MemorySnapShot_Capture(true);
                    237:                M68000_MemorySnapShot_Capture(true);
1.1.1.2 ! root      238: //             MFP_MemorySnapShot_Capture(true);
        !           239: //             PSG_MemorySnapShot_Capture(true);
        !           240: //             Sound_MemorySnapShot_Capture(true);
1.1       root      241:                Video_MemorySnapShot_Capture(true);
1.1.1.2 ! root      242: //             Blitter_MemorySnapShot_Capture(true);
        !           243: //             DmaSnd_MemorySnapShot_Capture(true);
        !           244: //             Crossbar_MemorySnapShot_Capture(true);
        !           245: //             VIDEL_MemorySnapShot_Capture(true);
        !           246: //             DSP_MemorySnapShot_Capture(true);
1.1       root      247:                DebugUI_MemorySnapShot_Capture(pszFileName, true);
1.1.1.2 ! root      248: //             IoMem_MemorySnapShot_Capture(true);
1.1       root      249:                /* And close */
                    250:                MemorySnapShot_CloseFile();
1.1.1.2 ! root      251:        } else {
        !           252:                /* just canceled? */
        !           253:                if (!bCaptureError)
        !           254:                        return;
1.1       root      255:        }
                    256: 
                    257:        /* Did error */
                    258:        if (bCaptureError)
                    259:                Log_AlertDlg(LOG_ERROR, "Unable to save memory state to file.");
                    260:        else if (bConfirm)
                    261:                Log_AlertDlg(LOG_INFO, "Memory state file saved.");
                    262: }
                    263: 
                    264: 
                    265: /*-----------------------------------------------------------------------*/
                    266: /**
                    267:  * Restore 'snapshot' of memory/chips/emulation variables
                    268:  */
                    269: void MemorySnapShot_Restore(const char *pszFileName, bool bConfirm)
                    270: {
                    271:        /* Set to 'restore' */
                    272:        if (MemorySnapShot_OpenFile(pszFileName, false))
                    273:        {
                    274:                Configuration_MemorySnapShot_Capture(false);
1.1.1.2 ! root      275: //             TOS_MemorySnapShot_Capture(false);
1.1       root      276: 
                    277:                /* Reset emulator to get things running */
                    278:                IoMem_UnInit();  IoMem_Init();
                    279:                Reset_Cold();
                    280: 
                    281:                /* Capture each files details */
                    282: //             STMemory_MemorySnapShot_Capture(false);
1.1.1.2 ! root      283: //             FDC_MemorySnapShot_Capture(false);
        !           284: //             Floppy_MemorySnapShot_Capture(false);
        !           285: //             GemDOS_MemorySnapShot_Capture(false);
        !           286: //             IKBD_MemorySnapShot_Capture(false);
1.1       root      287:                CycInt_MemorySnapShot_Capture(false);
                    288:                Cycles_MemorySnapShot_Capture(false);
                    289:                M68000_MemorySnapShot_Capture(false);
1.1.1.2 ! root      290: //             MFP_MemorySnapShot_Capture(false);
        !           291: //             PSG_MemorySnapShot_Capture(false);
        !           292: //             Sound_MemorySnapShot_Capture(false);
1.1       root      293:                Video_MemorySnapShot_Capture(false);
1.1.1.2 ! root      294: //             Blitter_MemorySnapShot_Capture(false);
        !           295: //             DmaSnd_MemorySnapShot_Capture(false);
        !           296: //             Crossbar_MemorySnapShot_Capture(false);
        !           297: //             VIDEL_MemorySnapShot_Capture(false);
        !           298: //             DSP_MemorySnapShot_Capture(false);
1.1       root      299:                DebugUI_MemorySnapShot_Capture(pszFileName, false);
1.1.1.2 ! root      300: //             IoMem_MemorySnapShot_Capture(false);
1.1       root      301: 
                    302:                /* And close */
                    303:                MemorySnapShot_CloseFile();
1.1.1.2 ! root      304: 
        !           305:                /* changes may affect also info shown in statusbar */
        !           306:                Statusbar_UpdateInfo();
1.1       root      307:        }
                    308: 
                    309:        /* Did error? */
                    310:        if (bCaptureError)
                    311:                Log_AlertDlg(LOG_ERROR, "Unable to restore memory state from file.");
                    312:        else if (bConfirm)
                    313:                Log_AlertDlg(LOG_INFO, "Memory state file restored.");
                    314: }
                    315: 
                    316: 
                    317: /*-----------------------------------------------------------------------*/
                    318: /*
                    319:  * Save and restore functions required by the UAE CPU core...
                    320:  * ... don't use them in normal Hatari code!
                    321:  */
                    322: #include <savestate.h>
                    323: 
                    324: void save_u32(uae_u32 data)
                    325: {
                    326:        MemorySnapShot_Store(&data, 4);
                    327: }
                    328: 
                    329: void save_u16(uae_u16 data)
                    330: {
                    331:        MemorySnapShot_Store(&data, 2);
                    332: }
                    333: 
                    334: uae_u32 restore_u32(void)
                    335: {
                    336:        uae_u32 data;
                    337:        MemorySnapShot_Store(&data, 4);
                    338:        return data;
                    339: }
                    340: 
                    341: uae_u16 restore_u16(void)
                    342: {
                    343:        uae_u16 data;
                    344:        MemorySnapShot_Store(&data, 2);
                    345:        return data;
                    346: }

unix.superglobalmegacorp.com

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