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

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

unix.superglobalmegacorp.com

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