Annotation of uae/src/savestate.c, revision 1.1.1.6

1.1       root        1:  /*
                      2:   * UAE - The Un*x Amiga Emulator
                      3:   *
                      4:   * Save/restore emulator state
                      5:   *
                      6:   * (c) 1999-2001 Toni Wilen
                      7:   *
                      8:   * see below for ASF-structure
                      9:   */
                     10: 
                     11:  /* Features:
                     12:   *
                     13:   * - full CPU state (68000/68010/68020, no FPU)
                     14:   * - full CIA-A and CIA-B state (with all internal registers)
                     15:   * - saves all custom registers and audio internal state but not all registers are restored yet.
                     16:   * - only Chip-ram and Bogo-ram are saved and restored.
                     17:   * - disk drive type, imagefile, track and motor state
                     18:   * - Kickstart ROM version, address and size is saved. This data is not used during restore yet.
                     19:   */
                     20: 
                     21:  /* Notes:
                     22:   *
                     23:   * - blitter state is not saved, blitter is forced to finish immediately if it
                     24:   *   was active
                     25:   * - disk DMA state is completely saved (I hope so..)
                     26:   * - does not ask for statefile name and description. Currently uses DF0's disk
                     27:   *   image name (".adf" is replaced with ".asf")
                     28:   * - only Amiga state is restored, harddisk support, autoconfig, expansion boards etc..
                     29:   *   are not saved/restored (and probably never will).
                     30:   * - use this for saving games that can't be saved to disk
                     31:   */
                     32: 
                     33:  /* Usage :
                     34:   *
                     35:   * save:
1.1.1.4   root       36:   *
1.1       root       37:   * set savestate_state = STATE_DOSAVE, savestate_filename = "..."
                     38:   *
                     39:   * restore:
1.1.1.4   root       40:   *
1.1       root       41:   * set savestate_state = STATE_DORESTORE, savestate_filename = "..."
                     42:   *
                     43:   */
                     44: 
                     45: #include "sysconfig.h"
                     46: #include "sysdeps.h"
                     47: 
                     48: #include "options.h"
                     49: #include "memory.h"
1.1.1.6 ! root       50: #include "zfile.h"
1.1       root       51: #include "savestate.h"
1.1.1.6 ! root       52: #include "gui.h"
1.1       root       53: 
                     54: int savestate_state;
                     55: 
                     56: char *savestate_filename;
1.1.1.6 ! root       57: struct zfile *savestate_file;
1.1       root       58: 
                     59: /* functions for reading/writing bytes, shorts and longs in big-endian
                     60:  * format independent of host machine's endianess */
                     61: 
                     62: void save_u32_func (uae_u8 **dstp, uae_u32 v)
                     63: {
                     64:     uae_u8 *dst = *dstp;
                     65:     *dst++ = (uae_u8)(v >> 24);
                     66:     *dst++ = (uae_u8)(v >> 16);
                     67:     *dst++ = (uae_u8)(v >> 8);
                     68:     *dst++ = (uae_u8)(v >> 0);
                     69:     *dstp = dst;
                     70: }
1.1.1.6 ! root       71: void save_u64_func (uae_u8 **dstp, uae_u64 v)
        !            72: {
        !            73:     save_u32_func (dstp, (uae_u32)(v >> 32));
        !            74:     save_u32_func (dstp, (uae_u32)v);
        !            75: }
1.1       root       76: void save_u16_func (uae_u8 **dstp, uae_u16 v)
                     77: {
                     78:     uae_u8 *dst = *dstp;
                     79:     *dst++ = (uae_u8)(v >> 8);
                     80:     *dst++ = (uae_u8)(v >> 0);
                     81:     *dstp = dst;
                     82: }
                     83: void save_u8_func (uae_u8 **dstp, uae_u8 v)
                     84: {
                     85:     uae_u8 *dst = *dstp;
                     86:     *dst++ = v;
                     87:     *dstp = dst;
                     88: }
1.1.1.5   root       89: void save_string_func (uae_u8 **dstp, const char *from)
1.1       root       90: {
                     91:     uae_u8 *dst = *dstp;
1.1.1.6 ! root       92:     while (*from)
1.1       root       93:        *dst++ = *from++;
                     94:     *dst++ = 0;
                     95:     *dstp = dst;
                     96: }
                     97: 
1.1.1.5   root       98: uae_u32 restore_u32_func (const uae_u8 **dstp)
1.1       root       99: {
                    100:     uae_u32 v;
1.1.1.5   root      101:     const uae_u8 *dst = *dstp;
1.1       root      102:     v = (dst[0] << 24) | (dst[1] << 16) | (dst[2] << 8) | (dst[3]);
                    103:     *dstp = dst + 4;
                    104:     return v;
                    105: }
1.1.1.6 ! root      106: uae_u64 restore_u64_func (const uae_u8 **dstp)
        !           107: {
        !           108:     uae_u64 v;
        !           109: 
        !           110:     v = restore_u32_func (dstp);
        !           111:     v <<= 32;
        !           112:     v |= restore_u32_func (dstp);
        !           113:     return v;
        !           114: }
1.1.1.5   root      115: uae_u16 restore_u16_func (const uae_u8 **dstp)
1.1       root      116: {
                    117:     uae_u16 v;
1.1.1.5   root      118:     const uae_u8 *dst = *dstp;
1.1       root      119:     v=(dst[0] << 8) | (dst[1]);
                    120:     *dstp = dst + 2;
                    121:     return v;
                    122: }
1.1.1.5   root      123: uae_u8 restore_u8_func (const uae_u8 **dstp)
1.1       root      124: {
                    125:     uae_u8 v;
1.1.1.5   root      126:     const uae_u8 *dst = *dstp;
1.1       root      127:     v = dst[0];
                    128:     *dstp = dst + 1;
                    129:     return v;
                    130: }
1.1.1.5   root      131: char *restore_string_func (const uae_u8 **dstp)
1.1       root      132: {
                    133:     int len;
                    134:     uae_u8 v;
1.1.1.5   root      135:     const uae_u8 *dst = *dstp;
1.1       root      136:     char *top, *to;
1.1.1.5   root      137:     len = strlen ((const char *)dst) + 1;
1.1       root      138:     top = to = malloc (len);
                    139:     do {
                    140:        v = *dst++;
                    141:        *top++ = v;
1.1.1.6 ! root      142:     } while (v);
1.1       root      143:     *dstp = dst;
1.1.1.4   root      144:     return to;
1.1       root      145: }
                    146: 
                    147: /* read and write IFF-style hunks */
                    148: 
1.1.1.6 ! root      149: static void save_chunk (struct zfile *f, uae_u8 *chunk, long len, const char *name)
1.1       root      150: {
                    151:     uae_u8 tmp[4], *dst;
                    152:     uae_u8 zero[4]= { 0, 0, 0, 0 };
                    153: 
                    154:     if (!chunk)
                    155:        return;
                    156: 
                    157:     /* chunk name */
1.1.1.6 ! root      158:     zfile_fwrite (name, 1, 4, f);
1.1       root      159:     /* chunk size */
                    160:     dst = &tmp[0];
                    161:     save_u32 (len + 4 + 4 + 4);
1.1.1.6 ! root      162:     zfile_fwrite (&tmp[0], 1, 4, f);
1.1       root      163:     /* chunk flags */
                    164:     dst = &tmp[0];
                    165:     save_u32 (0);
1.1.1.6 ! root      166:     zfile_fwrite (&tmp[0], 1, 4, f);
1.1       root      167:     /* chunk data */
1.1.1.6 ! root      168:     zfile_fwrite (chunk, 1, len, f);
1.1       root      169:     /* alignment */
                    170:     len = 4 - (len & 3);
                    171:     if (len)
1.1.1.6 ! root      172:        zfile_fwrite (zero, 1, len, f);
1.1       root      173: }
                    174: 
1.1.1.6 ! root      175: static uae_u8 *restore_chunk (struct zfile *f, char *name, long *len, long *filepos)
1.1       root      176: {
1.1.1.5   root      177:     uae_u8 tmp[4], dummy[4], *mem;
                    178:     const uae_u8 *src;
1.1       root      179:     uae_u32 flags;
                    180:     long len2;
                    181: 
                    182:     /* chunk name */
1.1.1.6 ! root      183:     zfile_fread (name, 1, 4, f);
1.1       root      184:     name[4] = 0;
                    185:     /* chunk size */
1.1.1.6 ! root      186:     zfile_fread (tmp, 1, 4, f);
1.1       root      187:     src = tmp;
                    188:     len2 = restore_u32 () - 4 - 4 - 4;
                    189:     if (len2 < 0)
                    190:        len2 = 0;
                    191:     *len = len2;
                    192:     if (len2 == 0)
                    193:        return 0;
                    194: 
                    195:     /* chunk flags */
1.1.1.6 ! root      196:     zfile_fread (tmp, 1, 4, f);
1.1       root      197:     src = tmp;
                    198:     flags = restore_u32 ();
                    199: 
1.1.1.6 ! root      200:     *filepos = zfile_ftell (f) - 4 - 4;
        !           201: 
1.1       root      202:     /* chunk data.  RAM contents will be loaded during the reset phase,
                    203:        no need to malloc multiple megabytes here.  */
                    204:     if (strcmp (name, "CRAM") != 0
                    205:        && strcmp (name, "BRAM") != 0
                    206:        && strcmp (name, "FRAM") != 0
1.1.1.6 ! root      207:        && strcmp (name, "ZRAM") != 0
        !           208:        && strcmp (name, "A3K1") != 0
        !           209:        && strcmp (name, "A3K2") != 0)
1.1       root      210:     {
                    211:        mem = malloc (len2);
1.1.1.6 ! root      212:        zfile_fread (mem, 1, len2, f);
1.1       root      213:     } else {
                    214:        mem = 0;
1.1.1.6 ! root      215:        zfile_fseek (f, len2, SEEK_CUR);
1.1       root      216:     }
                    217: 
                    218:     /* alignment */
                    219:     len2 = 4 - (len2 & 3);
                    220:     if (len2)
1.1.1.6 ! root      221:        zfile_fread (dummy, 1, len2, f);
1.1       root      222:     return mem;
                    223: }
                    224: 
1.1.1.5   root      225: void restore_ram (size_t filepos, uae_u8 *memory)
1.1.1.4   root      226: {
                    227:     uae_u8 tmp[8];
                    228:     uae_u8 *src = tmp;
1.1.1.6 ! root      229:     int size, fullsize;
1.1.1.4   root      230:     uae_u32 flags;
                    231: 
                    232:     zfile_fseek (savestate_file, filepos, SEEK_SET);
                    233:     zfile_fread (tmp, 1, sizeof(tmp), savestate_file);
1.1.1.6 ! root      234:     size = restore_u32 ();
        !           235:     flags = restore_u32 ();
1.1.1.4   root      236:     size -= 4 + 4 + 4;
1.1.1.6 ! root      237:     zfile_fread (memory, 1, size, savestate_file);
1.1.1.4   root      238: }
                    239: 
1.1.1.5   root      240: static void restore_header (const uae_u8 *src)
1.1       root      241: {
                    242:     char *emuname, *emuversion, *description;
                    243: 
1.1.1.6 ! root      244:     restore_u32 ();
1.1       root      245:     emuname = restore_string ();
                    246:     emuversion = restore_string ();
                    247:     description = restore_string ();
                    248:     write_log ("Saved with: '%s %s', description: '%s'\n",
1.1.1.5   root      249:        emuname, emuversion, description);
1.1       root      250:     free (description);
                    251:     free (emuversion);
                    252:     free (emuname);
                    253: }
                    254: 
                    255: /* restore all subsystems */
                    256: 
1.1.1.5   root      257: void restore_state (const char *filename)
1.1       root      258: {
1.1.1.6 ! root      259:     struct zfile *f;
        !           260:     const uae_u8 *chunk, *end;
1.1       root      261:     char name[5];
                    262:     long len;
                    263:     long filepos;
                    264: 
                    265:     chunk = 0;
1.1.1.6 ! root      266:     f = zfile_open (filename, "rb");
1.1       root      267:     if (!f)
                    268:        goto error;
                    269: 
                    270:     chunk = restore_chunk (f, name, &len, &filepos);
                    271:     if (!chunk || memcmp (name, "ASF ", 4)) {
                    272:        write_log ("%s is not an AmigaStateFile\n",filename);
                    273:        goto error;
                    274:     }
                    275:     savestate_file = f;
                    276:     restore_header (chunk);
                    277:     free (chunk);
1.1.1.4   root      278:     changed_prefs.bogomem_size = 0;
                    279:     changed_prefs.chipmem_size = 0;
                    280:     changed_prefs.fastmem_size = 0;
1.1.1.6 ! root      281:     changed_prefs.gfxmem_size = 0;
        !           282:     changed_prefs.z3fastmem_size = 0;
        !           283:     changed_prefs.mbresmem_low_size = 0;
        !           284:     changed_prefs.mbresmem_high_size = 0;
1.1       root      285:     savestate_state = STATE_RESTORE;
                    286:     for (;;) {
                    287:        chunk = restore_chunk (f, name, &len, &filepos);
                    288:        write_log ("Chunk '%s' size %d\n", name, len);
                    289:        if (!strcmp (name, "END "))
                    290:            break;
                    291:        if (!strcmp (name, "CRAM")) {
                    292:            restore_cram (len, filepos);
                    293:            continue;
1.1.1.6 ! root      294:        } else if (!strcmp (name, "BRAM")) {
1.1       root      295:            restore_bram (len, filepos);
                    296:            continue;
1.1.1.6 ! root      297:        } else if (!strcmp (name, "A3K1")) {
        !           298:            restore_a3000lram (len, filepos);
        !           299:            continue;
        !           300:        } else if (!strcmp (name, "A3K2")) {
        !           301:            restore_a3000hram (len, filepos);
        !           302:            continue;
1.1       root      303:        } else if (!strcmp (name, "FRAM")) {
                    304:            restore_fram (len, filepos);
                    305:            continue;
                    306:        } else if (!strcmp (name, "ZRAM")) {
                    307:            restore_zram (len, filepos);
                    308:            continue;
                    309:        }
                    310: 
                    311:        if (!strcmp (name, "CPU "))
                    312:            end = restore_cpu (chunk);
                    313:        else if (!strcmp (name, "AGAC"))
                    314:            end = restore_custom_agacolors (chunk);
                    315:        else if (!strcmp (name, "SPR0"))
1.1.1.4   root      316:            end = restore_custom_sprite (0, chunk);
1.1       root      317:        else if (!strcmp (name, "SPR1"))
1.1.1.4   root      318:            end = restore_custom_sprite (1, chunk);
1.1       root      319:        else if (!strcmp (name, "SPR2"))
1.1.1.4   root      320:            end = restore_custom_sprite (2, chunk);
1.1       root      321:        else if (!strcmp (name, "SPR3"))
1.1.1.4   root      322:            end = restore_custom_sprite (3, chunk);
1.1       root      323:        else if (!strcmp (name, "SPR4"))
1.1.1.4   root      324:            end = restore_custom_sprite (4, chunk);
1.1       root      325:        else if (!strcmp (name, "SPR5"))
1.1.1.4   root      326:            end = restore_custom_sprite (5, chunk);
1.1       root      327:        else if (!strcmp (name, "SPR6"))
1.1.1.4   root      328:            end = restore_custom_sprite (6, chunk);
1.1       root      329:        else if (!strcmp (name, "SPR7"))
1.1.1.4   root      330:            end = restore_custom_sprite (7, chunk);
1.1       root      331:        else if (!strcmp (name, "CIAA"))
                    332:            end = restore_cia (0, chunk);
                    333:        else if (!strcmp (name, "CIAB"))
                    334:            end = restore_cia (1, chunk);
                    335:        else if (!strcmp (name, "CHIP"))
                    336:            end = restore_custom (chunk);
                    337:        else if (!strcmp (name, "AUD0"))
1.1.1.4   root      338:            end = restore_audio (0, chunk);
1.1       root      339:        else if (!strcmp (name, "AUD1"))
1.1.1.4   root      340:            end = restore_audio (1, chunk);
1.1       root      341:        else if (!strcmp (name, "AUD2"))
1.1.1.4   root      342:            end = restore_audio (2, chunk);
1.1       root      343:        else if (!strcmp (name, "AUD3"))
1.1.1.4   root      344:            end = restore_audio (3, chunk);
1.1       root      345: #if 0
                    346:        else if (!strcmp (name, "BLIT"))
                    347:            end = restore_custom_blitter (chunk);
                    348: #endif
                    349:        else if (!strcmp (name, "DISK"))
                    350:            end = restore_floppy (chunk);
                    351:        else if (!strcmp (name, "DSK0"))
                    352:            end = restore_disk (0, chunk);
                    353:        else if (!strcmp (name, "DSK1"))
                    354:            end = restore_disk (1, chunk);
                    355:        else if (!strcmp (name, "DSK2"))
                    356:            end = restore_disk (2, chunk);
                    357:        else if (!strcmp (name, "DSK3"))
                    358:            end = restore_disk (3, chunk);
                    359:        else if (!strcmp (name, "EXPA"))
                    360:            end = restore_expansion (chunk);
                    361:        else if (!strcmp (name, "ROM "))
                    362:            end = restore_rom (chunk);
                    363:        else
                    364:            write_log ("unknown chunk '%s' size %d bytes\n", name, len);
                    365:        if (len != end - chunk)
                    366:            write_log ("Chunk '%s' total size %d bytes but read %d bytes!\n",
                    367:                       name, len, end - chunk);
                    368:        free (chunk);
                    369:     }
1.1.1.6 ! root      370:     gui_update ();
1.1       root      371:     return;
                    372: 
                    373:     error:
                    374:     savestate_state = 0;
                    375:     savestate_file = 0;
                    376:     if (chunk)
                    377:        free (chunk);
                    378:     if (f)
1.1.1.6 ! root      379:        zfile_fclose (f);
1.1       root      380: }
                    381: 
                    382: void savestate_restore_finish (void)
                    383: {
                    384:     if (savestate_state != STATE_RESTORE)
                    385:        return;
1.1.1.6 ! root      386:     zfile_fclose (savestate_file);
1.1       root      387:     savestate_file = 0;
                    388:     savestate_state = 0;
                    389: }
                    390: 
                    391: /* Save all subsystems  */
                    392: 
1.1.1.5   root      393: void save_state (const char *filename, const char *description)
1.1       root      394: {
                    395:     uae_u8 header[1000];
                    396:     char tmp[100];
                    397:     uae_u8 *dst;
1.1.1.6 ! root      398:     struct zfile *f;
1.1       root      399:     int len,i;
                    400:     char name[5];
                    401: 
1.1.1.6 ! root      402:     f = zfile_open (filename, "wb");
1.1       root      403:     if (!f)
                    404:        return;
                    405: 
                    406:     dst = header;
                    407:     save_u32 (0);
1.1.1.5   root      408:     save_string ("UAE");
                    409:     save_string (PACKAGE_VERSION);
1.1       root      410:     save_string (description);
                    411:     save_chunk (f, header, dst-header, "ASF ");
                    412: 
1.1.1.4   root      413:     dst = save_cpu (&len, 0);
1.1       root      414:     save_chunk (f, dst, len, "CPU ");
                    415:     free (dst);
                    416: 
1.1.1.6 ! root      417:     strcpy (name, "DSKx");
1.1       root      418:     for (i = 0; i < 4; i++) {
1.1.1.4   root      419:        dst = save_disk (i, &len, 0);
1.1       root      420:        if (dst) {
                    421:            name[3] = i + '0';
                    422:            save_chunk (f, dst, len, name);
                    423:            free (dst);
                    424:        }
                    425:     }
1.1.1.4   root      426:     dst = save_floppy (&len, 0);
1.1       root      427:     save_chunk (f, dst, len, "DISK");
                    428:     free (dst);
                    429: 
1.1.1.3   root      430:     dst = save_custom (&len, 0, 0);
1.1       root      431:     save_chunk (f, dst, len, "CHIP");
                    432:     free (dst);
                    433: 
                    434: #if 0
                    435:     dst = save_custom_blitter (&len);
                    436:     save_chunk (f, dst, len, "BLIT");
                    437:     free (dst);
                    438: #endif
                    439: 
1.1.1.4   root      440:     dst = save_custom_agacolors (&len, 0);
1.1       root      441:     save_chunk (f, dst, len, "AGAC");
                    442:     free (dst);
                    443: 
                    444:     strcpy (name, "SPRx");
                    445:     for (i = 0; i < 8; i++) {
1.1.1.4   root      446:        dst = save_custom_sprite (i, &len);
1.1       root      447:        name[3] = i + '0';
                    448:        save_chunk (f, dst, len, name);
                    449:        free (dst);
                    450:     }
                    451: 
                    452:     strcpy (name, "AUDx");
                    453:     for (i = 0; i < 4; i++) {
1.1.1.4   root      454:        dst = save_audio (i, &len);
1.1       root      455:        name[3] = i + '0';
                    456:        save_chunk (f, dst, len, name);
                    457:        free (dst);
                    458:     }
                    459: 
1.1.1.4   root      460:     dst = save_cia (0, &len, 0);
1.1       root      461:     save_chunk (f, dst, len, "CIAA");
                    462:     free (dst);
                    463: 
1.1.1.4   root      464:     dst = save_cia (1, &len, 0);
1.1       root      465:     save_chunk (f, dst, len, "CIAB");
                    466:     free (dst);
                    467: 
1.1.1.4   root      468:     dst = save_expansion (&len, 0);
1.1       root      469:     save_chunk (f, dst, len, "EXPA");
                    470:     dst = save_cram (&len);
                    471:     save_chunk (f, dst, len, "CRAM");
                    472:     dst = save_bram (&len);
                    473:     save_chunk (f, dst, len, "BRAM");
1.1.1.6 ! root      474:     dst = save_a3000lram (&len);
        !           475:     save_chunk (f, dst, len, "A3K1");
        !           476:     dst = save_a3000hram (&len);
        !           477:     save_chunk (f, dst, len, "A3K2");
1.1       root      478:     dst = save_fram (&len);
                    479:     save_chunk (f, dst, len, "FRAM");
                    480:     dst = save_zram (&len);
                    481:     save_chunk (f, dst, len, "ZRAM");
                    482: 
1.1.1.4   root      483:     dst = save_rom (1, &len, 0);
1.1       root      484:     do {
                    485:        if (!dst)
                    486:            break;
                    487:        save_chunk (f, dst, len, "ROM ");
                    488:        free (dst);
1.1.1.4   root      489:     } while ((dst = save_rom (0, &len, 0)));
1.1       root      490: 
1.1.1.6 ! root      491:     zfile_fwrite ("END ", 1, 4, f);
        !           492:     zfile_fwrite ("\0\0\0\08", 1, 4, f);
1.1       root      493:     write_log ("Save of '%s' complete\n", filename);
1.1.1.6 ! root      494:     zfile_fclose (f);
1.1       root      495: }
                    496: 
                    497: /*
                    498: 
                    499: My (Toni Wilen <[email protected]>)
                    500: proposal for Amiga-emulators' state-save format
                    501: 
                    502: Feel free to comment...
                    503: 
                    504: This is very similar to IFF-fileformat
                    505: Every hunk must end to 4 byte boundary,
                    506: fill with zero bytes if needed
                    507: 
                    508: version 0.7
                    509: 
                    510: HUNK HEADER (beginning of every hunk)
                    511: 
1.1.1.4   root      512:        hunk name (4 ascii-characters)
                    513:        hunk size (including header)
                    514:        hunk flags
1.1       root      515: 
1.1.1.4   root      516:        bit 0 = chunk contents are compressed with zlib (maybe RAM chunks only?)
1.1       root      517: 
                    518: HEADER
                    519: 
1.1.1.4   root      520:        "ASF " (AmigaStateFile)
                    521: 
1.1       root      522:        statefile version
1.1.1.4   root      523:        emulator name ("uae", "fellow" etc..)
                    524:        emulator version string (example: "0.8.15")
                    525:        free user writable comment string
1.1       root      526: 
                    527: CPU
                    528: 
1.1.1.4   root      529:         "CPU "
1.1       root      530: 
1.1.1.4   root      531:        CPU model               4 (68000,68010 etc..)
                    532:        CPU typeflags           bit 0=EC-model or not
                    533:        D0-D7                   8*4=32
                    534:        A0-A6                   7*4=32
                    535:        PC                      4
                    536:        prefetch address        4
                    537:        prefetch data           4
                    538:        USP                     4
                    539:        ISP                     4
                    540:        SR/CCR                  2
                    541:        flags                   4 (bit 0=CPU was HALTed)
                    542: 
                    543:        CPU specific registers
                    544: 
                    545:        68000: SR/CCR is last saved register
                    546:        68010: save also DFC,SFC and VBR
                    547:        68020: all 68010 registers and CAAR,CACR and MSP
                    548:        etc..
                    549: 
                    550:        DFC                     4 (010+)
                    551:        SFC                     4 (010+)
                    552:        VBR                     4 (010+)
                    553: 
                    554:        CAAR                    4 (020-030)
                    555:        CACR                    4 (020+)
                    556:        MSP                     4 (020+)
1.1       root      557: 
                    558: MMU (when and if MMU is supported in future..)
                    559: 
1.1.1.4   root      560:        MMU model               4 (68851,68030,68040)
                    561: 
                    562:        // 68040 fields
1.1       root      563: 
1.1.1.4   root      564:        ITT0                    4
                    565:        ITT1                    4
                    566:        DTT0                    4
                    567:        DTT1                    4
                    568:        URP                     4
                    569:        SRP                     4
                    570:        MMUSR                   4
                    571:        TC                      2
1.1       root      572: 
                    573: 
                    574: FPU (only if used)
                    575: 
                    576:        "FPU "
                    577: 
1.1.1.4   root      578:        FPU model               4 (68881 or 68882)
                    579:        FPU typeflags           4 (keep zero)
1.1       root      580: 
1.1.1.4   root      581:        FP0-FP7                 4+2 (80 bits)
                    582:        FPCR                    4
                    583:        FPSR                    4
                    584:        FPIAR                   4
1.1       root      585: 
                    586: CUSTOM CHIPS
                    587: 
1.1.1.4   root      588:        "CHIP"
1.1       root      589: 
1.1.1.4   root      590:        chipset flags   4      OCS=0,ECSAGNUS=1,ECSDENISE=2,AGA=4
                    591:                               ECSAGNUS and ECSDENISE can be combined
1.1       root      592: 
1.1.1.4   root      593:        DFF000-DFF1FF   352    (0x120 - 0x17f and 0x0a0 - 0xdf excluded)
1.1       root      594: 
1.1.1.4   root      595:        sprite registers (0x120 - 0x17f) saved with SPRx chunks
                    596:        audio registers (0x0a0 - 0xdf) saved with AUDx chunks
1.1       root      597: 
                    598: AGA COLORS
                    599: 
1.1.1.4   root      600:        "AGAC"
1.1       root      601: 
1.1.1.4   root      602:        AGA color               8 banks * 32 registers *
                    603:        registers               LONG (XRGB) = 1024
1.1       root      604: 
                    605: SPRITE
                    606: 
1.1.1.4   root      607:        "SPR0" - "SPR7"
1.1       root      608: 
                    609: 
1.1.1.4   root      610:        SPRxPT                  4
                    611:        SPRxPOS                 2
                    612:        SPRxCTL                 2
                    613:        SPRxDATA                2
                    614:        SPRxDATB                2
                    615:        AGA sprite DATA/DATB    3 * 2 * 2
                    616:        sprite "armed" status   1
1.1       root      617: 
1.1.1.4   root      618:        sprites maybe armed in non-DMA mode
                    619:        use bit 0 only, other bits are reserved
1.1       root      620: 
                    621: 
                    622: AUDIO
1.1.1.4   root      623:        "AUD0" "AUD1" "AUD2" "AUD3"
1.1       root      624: 
1.1.1.4   root      625:        audio state             1
                    626:        machine mode
                    627:        AUDxVOL                 1
1.1       root      628:        irq?                    1
                    629:        data_written?           1
1.1.1.4   root      630:        internal AUDxLEN        2
                    631:        AUDxLEN                 2
1.1       root      632:        internal AUDxPER        2
                    633:        AUDxPER                 2
1.1.1.4   root      634:        internal AUDxLC         4
1.1       root      635:        AUDxLC                  4
                    636:        evtime?                 4
                    637: 
                    638: BLITTER
                    639: 
1.1.1.4   root      640:        "BLIT"
1.1       root      641: 
1.1.1.4   root      642:        internal blitter state
1.1       root      643: 
1.1.1.4   root      644:        blitter running         1
                    645:        anything else?
1.1       root      646: 
                    647: CIA
                    648: 
1.1.1.4   root      649:        "CIAA" and "CIAB"
1.1       root      650: 
1.1.1.4   root      651:        BFE001-BFEF01   16*1 (CIAA)
                    652:        BFD000-BFDF00   16*1 (CIAB)
1.1       root      653: 
1.1.1.4   root      654:        internal registers
1.1       root      655: 
1.1.1.4   root      656:        IRQ mask (ICR)  1 BYTE
                    657:        timer latches   2 timers * 2 BYTES (LO/HI)
                    658:        latched tod     3 BYTES (LO/MED/HI)
                    659:        alarm           3 BYTES (LO/MED/HI)
                    660:        flags           1 BYTE
                    661:                        bit 0=tod latched (read)
                    662:                        bit 1=tod stopped (write)
1.1       root      663:        div10 counter   1 BYTE
                    664: 
                    665: FLOPPY DRIVES
                    666: 
1.1.1.4   root      667:        "DSK0" "DSK1" "DSK2" "DSK3"
1.1       root      668: 
1.1.1.4   root      669:        drive state
1.1       root      670: 
1.1.1.4   root      671:        drive ID-word           4
                    672:        state                   1 (bit 0: motor on, bit 1: drive disabled)
                    673:        rw-head track           1
                    674:        dskready                1
                    675:        id-mode                 1 (ID mode bit number 0-31)
                    676:        floppy information
                    677: 
                    678:        bits from               4
                    679:        beginning of track
                    680:        CRC of disk-image       4 (used during restore to check if image
                    681:                                  is correct)
                    682:        disk-image              null-terminated
                    683:        file name
1.1       root      684: 
                    685: INTERNAL FLOPPY CONTROLLER STATUS
                    686: 
1.1.1.4   root      687:        "DISK"
1.1       root      688: 
1.1.1.4   root      689:        current DMA word        2
                    690:        DMA word bit offset     1
                    691:        WORDSYNC found          1 (no=0,yes=1)
                    692:        hpos of next bit        1
                    693:        DSKLENGTH status        0=off,1=written once,2=written twice
                    694: 
                    695: RAM SPACE
                    696: 
                    697:        "xRAM" (CRAM = chip, BRAM = bogo, FRAM = fast, ZFRAM = Z3)
                    698: 
                    699:        start address           4 ("bank"=chip/slow/fast etc..)
                    700:        of RAM "bank"
                    701:        RAM "bank" size         4
                    702:        RAM flags               4
                    703:        RAM "bank" contents
1.1       root      704: 
                    705: ROM SPACE
                    706: 
1.1.1.4   root      707:        "ROM "
1.1       root      708: 
1.1.1.4   root      709:        ROM start               4
                    710:        address
                    711:        size of ROM             4
                    712:        ROM type                4 KICK=0
                    713:        ROM flags               4
                    714:        ROM version             2
                    715:        ROM revision            2
                    716:        ROM CRC                 4 see below
                    717:        ROM-image               null terminated, see below
                    718:        ID-string
                    719:        ROM contents            (Not mandatory, use hunk size to check if
                    720:                                this hunk contains ROM data or not)
                    721: 
                    722:        Kickstart ROM:
                    723:         ID-string is "Kickstart x.x"
                    724:         ROM version: version in high word and revision in low word
                    725:         Kickstart ROM version and revision can be found from ROM start
                    726:         + 12 (version) and +14 (revision)
1.1       root      727: 
1.1.1.4   root      728:        ROM version and CRC is only meant for emulator to automatically
                    729:        find correct image from its ROM-directory during state restore.
1.1       root      730: 
1.1.1.4   root      731:        Usually saving ROM contents is not good idea.
1.1       root      732: 
                    733: 
                    734: END
1.1.1.4   root      735:        hunk "END " ends, remember hunk size 8!
1.1       root      736: 
                    737: 
                    738: EMULATOR SPECIFIC HUNKS
                    739: 
                    740: Read only if "emulator name" in header is same as used emulator.
                    741: Maybe useful for configuration?
                    742: 
                    743: misc:
                    744: 
                    745: - save only at position 0,0 before triggering VBLANK interrupt
                    746: - all data must be saved in bigendian format
                    747: - should we strip all paths from image file names?
                    748: 
                    749: */

unix.superglobalmegacorp.com

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