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

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