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

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

unix.superglobalmegacorp.com

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