]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
ussload moved to separate repository
authorToni Wilen <twilen@winuae.net>
Thu, 30 May 2019 19:09:11 +0000 (22:09 +0300)
committerToni Wilen <twilen@winuae.net>
Thu, 30 May 2019 19:09:11 +0000 (22:09 +0300)
utilities/stateload/asm.S [deleted file]
utilities/stateload/header.h [deleted file]
utilities/stateload/inflate.S [deleted file]
utilities/stateload/main.c [deleted file]
utilities/stateload/makefile [deleted file]
utilities/stateload/mmu.c [deleted file]
utilities/stateload/readme.txt [deleted file]

diff --git a/utilities/stateload/asm.S b/utilities/stateload/asm.S
deleted file mode 100644 (file)
index 2708850..0000000
+++ /dev/null
@@ -1,301 +0,0 @@
-
-CPU_CHUNK = 4
-CIAA_CHUNK = CPU_CHUNK+4
-CIAB_CHUNK = CIAA_CHUNK+4
-CUSTOM_CHUNK = CIAB_CHUNK+4
-AGA_COLORS_CHUNK = CUSTOM_CHUNK+4
-FLOPPY_CHUNK = AGA_COLORS_CHUNK+4
-AUDIO_CHUNK = FLOPPY_CHUNK+4*4
-SPRITE_CHUNK = AUDIO_CHUNK+4*4
-MMU_TABLE = SPRITE_CHUNK+4*8
-
-       .text
-       .globl _runit
-       .globl _killsystem
-       .globl _callinflate
-       .globl _inflate
-       .globl _flushcache
-
-_flushcache:
-       move.l a6,-(sp)
-       move.l 4.w,a6
-       jsr -0x27c(a6) | CacheClearU
-       move.l (sp)+,a6
-       rts
-
-_callinflate:
-       movem.l a4-a5,-(sp)
-       move.l 4+2*4(sp),a4
-       move.l 8+2*4(sp),a5
-       bsr _inflate
-       movem.l (sp)+,a4-a5
-       rts
-
-       | params: new stack 4, uaestate 8, func(uaestate) 12
-_killsystem:
-       move.l 8(sp),a0 | uaestate
-       move.l a6,a1
-       move.l 4.w,a6
-       move.w 0x128(a6),(a0) | AttFlags
-       move.l sp,d1
-       move.l a0,d0
-       move.l a5,a0
-       lea .super(pc),a5
-       jsr -0x1e(a6) | Supervisor
-.super:
-       move.w #0x2700,sr
-       move.l a0,a5
-       move.l a1,a6
-       move.l d0,a0
-
-       | debug trigger
-       move.w #0x1234,0xef0006
-
-       | check if 68060
-       move.l 0x10.w,a1
-       btst #2,1(a0)
-       beq.s .not68060
-       moveq #0,d0
-       movec d0,VBR
-       pea .not68060(pc)
-       move.l (sp)+,0x10.w
-       | movec PCR,d0
-       dc.w 0x4e7a,0x0808
-       | it is 68060
-       bset #7,1(a0)
-.not68060:
-       move.l a1,0x10.w
-
-       | CIA: stop timers, clear interrupts
-       bclr #0,0xbfde00
-       bclr #0,0xbfdf00
-       bclr #0,0xbfee01
-       bclr #0,0xbfef01
-       move.b #0x7f,0xbfdd00
-       move.b #0x7f,0xbfed01
-       tst.b 0xbfdd00
-       tst.b 0xbfed01
-       
-       lea 0xdff000,a0
-       move.w #0x7fff,d0
-       move.w d0,0x96(a0)
-       move.w d0,0x9a(a0)
-       move.w d0,0x9c(a0)
-       move.w d0,0x9e(a0)
-       move.l d1,a0
-       
-       move.l 8(a0),d0
-       bsr.w mmu_enable
-       
-       move.l 4(a0),sp | new temp super stack
-       move.l 8(a0),-(sp) | uaestate
-       move.l 12(a0),a0 | func
-       jsr (a0) | func(uaestate)
-       | never returns
-
-_runit:
-       move.l 4(sp),a4 | get pointer to struct uaestate
-       subq.l #8,sp
-       lea 0xdff000,a6
-       
-| find last line
-       moveq #0,d5
-       lea 0x6(a6),a2
-.wait1:
-       cmp.b #250,(a2)
-       bne.s .wait1
-.wait1a:
-       cmp.b #2,(a2)
-       bne.s .wait1a
-.wait1b:
-       move.w 4(a6),d0
-       btst #0,d0
-       beq.s .wait1c
-       move.b (a2),d0
-       cmp.b d0,d5
-       bcc.s .wait1b
-       move.b d0,d5
-       bra.s .wait1b
-.wait1c:
-       cmp.b #160,(a2)
-       bne.s .wait1c
-
-       | last line - 15
-       sub.b #15,d5
-.wait3:
-       cmp.b (a2),d5
-       bne.s .wait3
-
-       | debug trigger
-       move.w #0x1234,0xef0004
-
-       move.l CUSTOM_CHUNK(a4),a0
-       move.w 4+0x96(a0),d0 | DMACON
-       and.w #15,d0
-       or.w #0x8200,d0
-       | enable audio DMA
-       move.w d0,0x96(a6)
-
-       | wait few lines, enough time for audio channels to enter normal 2/3 states
-       addq.b #4,d5
-.wait4:
-       cmp.b (a2),d5
-       bne.s .wait4
-       | restore latched AUDxLEN and AUDxPT
-       move.l a4,(sp)
-       bsr _set_audio_final
-
-       | restore possible side-effect causing
-       | custom bits as late as possible
-
-       move.l CIAA_CHUNK(a4),(sp)
-       clr.l 4(sp)
-       bsr _set_cia_final
-       move.l CIAB_CHUNK(a4),(sp)
-       addq.l #1,4(sp)
-       bsr _set_cia_final
-       move.l CUSTOM_CHUNK(a4),(sp)
-       bsr _set_custom_final
-
-       | restore CPU state
-       move.w (a4),d1
-       move.l CPU_CHUNK(a4),a0
-       move.l 4+4+60+4+2+2+4(a0),SP
-       move.l 4+4+60+4+2+2(a0),a1 | USP
-       move.l a1,USP
-       cmp.l #68020,(a0)
-       bcs.s .cpu68010
-       btst #1,d1
-       beq.s .cpu68010
-       lea 4+4+60+4+2+2+4+4+2+4+4+4+4(a0),a1
-       | CAAR is 68020/030 only
-       move.l (a1)+,d0
-       btst #3,d1
-       bne.s .cpu68040
-       | movec d0,CAAR
-       dc.w 0x4e7b,0x0802
-.cpu68040:
-       move.l (a1)+,d0
-       movec d0,CACR
-       | MSP is 68020-68040 only
-       move.l (a1)+,d0
-       btst #7,d1
-       bne.s .cpu68010
-       movec d0,MSP
-.cpu68010:
-       cmp.l #68010,(a0)
-       bcs.s .cpu68000
-       btst #0,d1
-       beq.s .cpu68000 
-       lea 4+4+60+4+2+2+4+4+2+4(a0),a1
-       move.l (a1)+,d0
-       movec d0,DFC
-       move.l (a1)+,d0
-       movec d0,SFC
-       move.l (a1)+,d0
-       movec d0,VBR
-.cpu68000:
-       btst #0,d1
-       beq.s .nocpu68010
-       btst #1,d1
-       beq.s .nocpu68020
-       btst #0,3(a4) | nocache?
-       beq.s .nocpu68020
-       moveq #0,d0
-       movec d0,CACR
-.nocpu68020:
-       move.w #0x0020,-(sp) | Format 0, Trap #0
-.nocpu68010:
-
-       move.l CIAA_CHUNK(a4),a1
-       move.b 15(a1),d6
-       swap d6
-       move.b 14(a1),d6
-       move.l CIAB_CHUNK(a4),a1
-       move.b 15(a1),d7
-       swap d7
-       move.b 14(a1),d7
-
-       move.l 4+4+60(a0),-(sp) | PC
-       move.w 4+4+60+4+2+2+4+4(a0),-(sp) | SR
-       movem.l 4+4(a0),d0-d5
-       movem.l 4+4+8*4+4+4(a0),a2-a6
-       add.w #4+4+6*4,a0
-
-       | debug trigger
-       move.w #0x1234,0xef0000
-
-       lea 0xbfde00,a1
-
-       | wait last line
-.wait2:
-       tst.b 0xdff006
-       bne.s .wait2
-
-       | start timers
-       move.b d6,0xbfee01-0xbfde00(a1)
-       swap d6
-       move.b d6,0xbfef01-0xbfde00(a1)
-       move.b d7,(a1)
-       swap d7
-       move.b d7,0x100(a1)
-       
-       movem.l (a0),d6-d7/a0-a1
-       
-       rte | GO! GO! GO!
-
-mmu_enable:
-       movem.l d0-d2/a0-a2,-(sp)
-       move.l d0,a2
-
-       | debug trigger
-       move.w #0x1234,0xef0008
-
-       move.l MMU_TABLE(a2),d2
-       beq.s .mmuend
-
-       move.w (a2),d1
-       btst #3,d1
-       beq.s .no68040
-
-       | 68040/060
-       movec d2,urp
-       movec d2,srp
-       cpusha dc
-       cinva dc
-       pflusha
-       move.l #0x8000,d0
-       movec d0,tc
-       moveq #0,d0
-       movec d0,itt0
-       movec d0,itt1
-       movec d0,dtt0
-       movec d0,dtt1
-       bra.s .mmuend
-
-.no68040:
-       | 68030?
-       btst #2,d1
-       beq.s .mmuend
-
-       sub.w #12,sp
-       move.l #0x00c07760,(sp)
-       | pmove (sp),tc
-       dc.w 0xf017,0x4000
-       move.l #0x80000002,4(sp)
-       move.l d2,8(sp)
-       | pmove 4(sp),crp
-       dc.w 0xf02f,0x4c00,0x0004
-       bset #7,(sp)
-       | pmove (sp),tc
-       dc.w 0xf017,0x4000
-       clr.l (sp)
-       | pmove (sp),tt0
-       dc.w 0xf017,0x0800
-       | pmove (sp),tt1
-       dc.w 0xf017,0x0c00
-       add.w #12,sp
-
-.mmuend:
-       movem.l (sp)+,d0-d2/a0-a2
-       rts
diff --git a/utilities/stateload/header.h b/utilities/stateload/header.h
deleted file mode 100644 (file)
index 5810b0d..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-
-#define TEMP_STACK_SIZE 8000
-
-#define ALLOCATIONS 256
-
-struct Allocation
-{
-       struct MemHeader *mh;
-       UBYTE *addr;
-       ULONG size;
-};
-
-struct MemoryBank
-{
-       UBYTE *addr;
-       ULONG flags;
-       UBYTE *targetaddr;
-       ULONG size;
-       ULONG targetsize;
-       ULONG offset;
-       UBYTE chunk[5];
-};
-
-// CHIP, SLOW, FAST
-#define MEMORY_REGIONS 3
-#define MB_CHIP 0
-#define MB_SLOW 1
-#define MB_FAST 2
-
-#define MAPROM_ACA500 1
-#define MAPROM_ACA500P 2
-#define MAPROM_ACA1221EC 3
-#define MAPROM_ACA12xx 4
-#define MAPROM_GVP 5
-#define MAPROM_BLIZZARD12x0 6
-#define MAPROM_ACA1233N 7
-#define MAPROM_MMU 255
-
-#define FLAGS_NOCACHE 1
-#define FLAGS_FORCEPAL 2
-#define FLAGS_FORCENTSC 4
-
-struct mapromdata
-{
-       UWORD type;
-       ULONG config;
-       ULONG addr;
-       APTR board;
-       ULONG memunavailable;
-};
-
-struct uaestate
-{
-       ULONG flags;
-       UBYTE *cpu_chunk;
-       UBYTE *ciaa_chunk, *ciab_chunk;
-       UBYTE *custom_chunk;
-       UBYTE *aga_colors_chunk;
-       UBYTE *floppy_chunk[4];
-       UBYTE *audio_chunk[4];
-       UBYTE *sprite_chunk[8];
-       ULONG *MMU_Level_A;
-
-       UBYTE *maprom;
-       ULONG mapromsize;
-       ULONG maprom_memlimit;
-       struct mapromdata mrd[2];
-
-       UBYTE *extra_ram;
-       ULONG extra_ram_size;
-       ULONG errors;
-
-       struct MemHeader *mem_allocated[MEMORY_REGIONS];
-       struct MemHeader *extra_mem_head;
-       UBYTE *extra_mem_pointer;
-       struct MemoryBank membanks[MEMORY_REGIONS];
-
-       int num_allocations;
-       struct Allocation allocations[ALLOCATIONS];
-       
-       WORD mmutype;
-       UBYTE *page_ptr;
-       ULONG page_free;
-       
-       UWORD romver, romrev;
-       UBYTE agastate;
-       UBYTE usemaprom;
-       UBYTE debug;
-       UBYTE testmode;
-       UBYTE nowait;
-       UBYTE canusemmu;
-       UBYTE mmuused;
-};
-
-UBYTE *allocate_abs(ULONG size, ULONG addr, struct uaestate *st);
-
-BOOL map_region(struct uaestate *st, void *addr, void *physaddr, ULONG size, BOOL invalid, BOOL writeprotect, BOOL supervisor, UBYTE cachemode);
-BOOL unmap_region(struct uaestate *st, void *addr, ULONG size);
-BOOL init_mmu(struct uaestate *st);
-
diff --git a/utilities/stateload/inflate.S b/utilities/stateload/inflate.S
deleted file mode 100644 (file)
index bdd5a09..0000000
+++ /dev/null
@@ -1,778 +0,0 @@
-
-       .chip 68020
-       .globl _inflate
-       
-
-/*
- * inflate.S
- * 
- * Decompression of DEFLATE streams, as produced by zip/gzip/pkzip and
- * specified in RFC 1951 "DEFLATE Compressed Data Format Specification".
- *
- * Usage: Optionally configure the OPT_xxx options below at build time;
- * at run time 'bsr inflate' with arguments:
- *    a4 = output buffer, a5 = input stream
- *    a6 = *end* of temporary storage area (only if OPT_STORAGE_OFFSTACK)
- * All register values (including arguments) are preserved.
- *
- * Space requirements: 638-930 bytes code; 2044-2940 bytes stack.
- * (NB1. Above ranges are [No Optimisations]-[All Optimisations])
- * (NB2. Stack space can be relocated to a separately-specified storage
- *       area, see OPT_STORAGE_OFFSTACK below)
- *
- * Timings: With all Optimisation Options enabled (see below) this routine
- * will decompress on a basic 7MHz 68000 at ~25kB/s. An AmigaDOS track of
- * data (5.5kB) is processed in ~220ms. This is only fractionally slower than
- * the track can be fetched from disk, hence there is scope for a
- * decompressing loader to keep CPU and disk both at near 100% utilisation.
- * 
- * Written & released by Keir Fraser <keir.xen@gmail.com>
- * 
- * This is free and unencumbered software released into the public domain.
- * See the file COPYING for more details, or visit <http://unlicense.org>.
- */
-
-/* Optimisation Option #1:
- * Avoid long Huffman-tree walks by indexing the first 8 bits of each codeword
- * in a 256-entry lookup table. This shortens all walks by 8 steps and since
- * the most common codes are less than 8 bits, most tree walks are avoided.
- * Also pre-shifts selected symbols in the code->symbol table, ready to be used
- * as indexes into further lookup tables.
- * SPEEDUP: 41% (c.w. no Options); COST: 122 bytes code, 896 bytes stack */
-#ifndef OPT_TABLE_LOOKUP
-#define OPT_TABLE_LOOKUP 1
-#endif
-
-/* Optimisation Option #2:
- * Inline functions in the main decode loop to avoid all BSR/RTS pairs.
- * SPEEDUP: 15% (on top of Option #1); COST: 164 bytes code */
-#ifndef OPT_INLINE_FUNCTIONS
-#define OPT_INLINE_FUNCTIONS 1
-#endif
-
-/* Optimisation Option #3:
- * Unroll the copy loop for <distance,length> tuples by one iteration
- * (so two bytes are copied per iteration).
- * SPEEDUP: ~1% (on top of Options #1 and #2); COST: 6 bytes code */
-#ifndef OPT_UNROLL_COPY_LOOP
-#define OPT_UNROLL_COPY_LOOP 1
-#endif
-
-/* Storage Option:
- * All but 12 bytes of this routine's space requirement can be allocated
- * off stack, in a data area specified in register a6.
- * If this option is set then inflate must be called with a6 pointing at
- * the *end* of the reserved storage area (+2032 or +2928 bytes, depending
- * on whether OPT_TABLE_LOOKUP is enabled).
- * SPEEDUP: none; COST: -2 bytes code (makes code slightly smaller) */
-#ifndef OPT_STORAGE_OFFSTACK
-#define OPT_STORAGE_OFFSTACK 0
-#endif
-
-/* By default all lookup/conversion tables are generated on-the-fly on every
- * call to inflate. In some cases this can be very inefficient.
- * If this option is enabled then two new routines are generated: At start-of-
- * day call 'inflate_gentables' with a6 pointing to the *end* of a 6000-byte
- * block of memory. Then call 'inflate_fromtables' instead of 'inflate', with
- * a6 still pointing to the end of the pre-generated memory block.
- * SPEEDUP: variable; COST: 116 bytes code */
-#ifndef OPT_PREGENERATE_TABLES
-#define OPT_PREGENERATE_TABLES 0
-#endif
-
-/* By default all registers are saved/restored across 'inflate' and
- * 'inflate_fromtables'. This set can be reduced below. Note that if
- * a4 is not saved then it will point at the end of the uncompressed output.
- * If a5 is not saved then it will point at the end of the DEFLATE stream. */
-#ifndef SAVE_RESTORE_REGS
-#define SAVE_RESTORE_REGS d0-d6/a0-a3
-#endif
-
-#if OPT_STORAGE_OFFSTACK
-#define aS a6
-#else
-#define aS sp
-#endif
-
-/* Longest possible code. */
-#define MAX_CODE_LEN   16
-
-/* (Maximum) alphabet sizes. */
-#define nr_codelen_symbols  19
-#define nr_litlen_symbols  288
-#define nr_distance_symbols 32
-
-/* Alphabet-description stream for a static Huffman block (BTYPE=01b). */
-static_huffman_prefix:
-        dc.b 0xff, 0x5b, 0x00, 0x6c, 0x03, 0x36, 0xdb
-        dc.b 0xb6, 0x6d, 0xdb, 0xb6, 0x6d, 0xdb, 0xb6
-        dc.b 0xcd, 0xdb, 0xb6, 0x6d, 0xdb, 0xb6, 0x6d
-        dc.b 0xdb, 0xa8, 0x6d, 0xce, 0x8b, 0x6d, 0x3b
-
-#if OPT_TABLE_LOOKUP
-
-/* Number of bytes required for code-lookup table/tree:
- *  - 256 2-byte entries for the 8-bit lookup table
- *  - Worst-case only 8 symbols decode directly in the table and all the rest
- *    are in a tree hanging off one table entry. This tree requires
- *    (nr_symbols-8)-1 internal 4-byte nodes. */
-#define LOOKUP_BYTES(nr_syms) (256*2+((nr_syms)-9)*4)
-
-        /* a0 = len[], a1 = nodes[], d0 = nr_symbols */
-        /* d1 = symbol beyond which all symbols get <<2 */
-        /* a2-a3 are scratched */
-build_code:
-        movem.l d0-d7,-(aS)
-
-        /* Allocate space for bl_count[]/next_code[] array on stack. */
-        moveq   #(MAX_CODE_LEN+1)/2,d1
-        moveq   #0,d2
-1:      move.l  d2,-(aS)
-        dbf     d1,1b
-
-        /* Count occurrences of each code length into bl_count[] array. */
-        subq.w  #1,d0
-        move.w  d0,d1
-        move.l  a0,a2           /* a2 = &len[0] */
-1:      move.b  (a2)+,d2        /* d2 = len[i] */
-#if MC68020
-        addq.w  #1,(aS,d2.w*2)
-#else
-        add.b   d2,d2
-        addq.w  #1,(aS,d2.w)    /* bl_count[len[i]]++ */
-#endif
-        dbf     d1,1b
-
-        /* Calculate next_code[] start values for each code length. */
-        move.l  aS,a2           /* a2 = bl_count[] / next_code[] */
-        moveq   #MAX_CODE_LEN-1,d1
-        moveq   #0,d2           /* d2 = code */
-        move.w  d2,(aS)         /* bl_count[0] = 0, ignore zero-length codes */
-1:      add.w   (a2),d2
-        add.w   d2,d2           /* code = (code + bl_count[i-1]) << 1 */
-        move.w  d2,(a2)+        /* next_code[i] = code */
-        dbf     d1,1b
-
-        /* Create the Huffman-code lookup tree */
-        move.w  d0,d1
-        moveq   #127,d4         /* d4 = next_node = 127 */
-        move.l  a0,a2           /* a2 = &len[0] */
-1:      moveq   #0,d5
-        move.b  (a2)+,d5        /* d5 = len[i] / *len++ */
-        jeq     4f
-        subq.w  #1,d5
-        move.w  d5,d6
-#if MC68020
-        move.w  (aS,d6.w*2),d3
-        addq.w  #1,(aS,d6.w*2)
-#else
-        add.w   d6,d6
-        move.w  (aS,d6.w),d3    /* d3 = code = next_code[len[i]]++ */
-        addq.w  #1,(aS,d6.w)
-        move.w  d5,d6
-#endif
-
-        moveq   #0,d2
-9:      lsr.w   #1,d3
-        roxl.w  #1,d2
-        dbf     d6,9b           /* d5 = codelen-1; d2 = reversed code */
-        move.b  d2,d3
-        add.w   d3,d3           /* d3 = table offset */
-        move.w  d0,d6
-        sub.w   d1,d6           /* d6 = symbol */
-        cmp.w   (((MAX_CODE_LEN+1)/2)+1)*4+6(aS),d6 /* symbol > saved d1.w? */
-        jls     9f
-        lsl.w   #2,d6           /* symbol <<= 2 if so */
-9:      cmp.b   #9-1,d5
-        jcc     codelen_gt_8
-
-codelen_le_8: /* codelen <= 8: leaf in table entry(s) */
-        lsl.w   #3,d6
-        or.b    d5,d6           /* d6 = (symbol<<3) | (codelen-1) */
-        moveq   #0,d2
-        addq.b  #2,d5
-        bset    d5,d2           /* d2 = 1<<(codelen+1) [table step] */
-        move.w  d2,d7
-        neg.w   d7
-        and.w   #511,d7
-        or.w    d7,d3           /* d3 = last table offset */
-9:      move.w  d6,(a1,d3.w)
-        sub.w   d2,d3
-        jcc     9b
-        jra     4f
-
-codelen_gt_8: /* codelen > 8: requires a tree walk */
-        lsr.w   #8,d2
-        subq.b  #8,d5           /* Skip the first 8 bits of code */
-        lea     (a1,d3.w),a3    /* pnode = table entry */
-
-2:      /* Walk through *pnode. */
-        move.w  (a3),d7         /* d3 = *pnode */
-        jne     3f
-        /* Link missing: Create a new internal node */
-        addq.w  #1,d4
-        move.w  d4,d7
-        bset    #15,d7
-        move.w  d7,(a3)         /* *pnode = ++next_node | INTERNAL */
-3:      /* Take left or right branch depending on next code bit */
-        lsr.b   #1,d2
-        addx.w  d7,d7
-#if MC68020
-        lea     (a1,d7.w*2),a3
-#else
-        add.w   d7,d7
-        lea     (a1,d7.w),a3    /* pnode = next_bit ? &node->r : &node->l */
-#endif
-3:      dbf     d5,2b
-
-        /* Insert the current symbol as a new leaf node */
-        move.w  d6,(a3)         /* *pnode = sym */
-4:      dbf     d1,1b
-
-        lea     (((MAX_CODE_LEN+1)/2)+1)*4(aS),aS
-        movem.l (aS)+,d0-d7
-        rts
-
-        /* d5-d6/a5 = stream, a0 = tree */
-        /* d0.w = result, d1.l = scratch */
-.macro STREAM_NEXT_SYMBOL
-        moveq   #0,d0   /* 4 */
-        moveq   #7,d1   /* 4 */
-        cmp.b   d1,d6   /* 4 */
-        jhi     99f     /* 10 */
-        /* Less than 8 bits cached; grab another byte from the stream */
-        move.b  (a5)+,d0 /* [8] */
-        lsl.w   d6,d0   /* [~14] */
-        or.w    d0,d5   /* [4] */ /* s->cur |= *p++ << s->nr */
-        addq.b  #8,d6   /* [4] */ /* s->nr += 8 */
-        moveq   #0,d0   /* [4] */
-99:     /* Use next input byte as index into code lookup table */
-        move.b  d5,d0   /* 4 */
-#if MC68020
-        move.w  (a0,d0.w*2),d0
-#else
-        add.w   d0,d0   /* 4 */
-        move.w  (a0,d0.w),d0 /* 14 */
-#endif
-        jpl     99f     /* 10 (taken) */
-        /* Code is longer than 8 bits: do the remainder via a tree walk */
-        lsr.w   #8,d5
-        subq.b  #8,d6           /* consume 8 bits from the stream */
-98:     /* stream_next_bits(1), inlined & optimised */
-        subq.b  #1,d6           /* 4 cy */
-        jcc     97f             /* 10 cy (taken) */
-        move.b  (a5)+,d5        /* [8 cy] */
-        moveq   #7,d6           /* [4 cy] */
-97:     lsr.w   #1,d5           /* 8 cy */
-        addx.w  d0,d0           /* 4 cy */
-#if MC68020
-        move.w  (a0,d0.w*2),d0
-#else
-        add.w   d0,d0           /* 4 cy */
-        move.w  (a0,d0.w),d0    /* 14 cy */
-#endif
-        jmi     98b             /* 10 cy (taken); loop on INTERNAL flag */
-        jra     98f             /* TOTAL LOOP CYCLES ~= 54 */
-99:     /* Symbol found directly: consume bits and return symbol */
-        and.b   d0,d1   /* 4 */
-        addq.b  #1,d1   /* 4 */
-        lsr.w   d1,d5   /* ~16 */ /* consume bits from the stream */
-        sub.b   d1,d6   /* 4 */
-        lsr.w   #3,d0   /* 12 */  /* d0 = symbol */
-98:                     /* ~94 CYCLES TOTAL [+ 34] */
-.endm
-
-#else /* !OPT_TABLE_LOOKUP */
-
-/* Number of bytes required for code-lookup tree:
- *  - Every binary tree with N leaves has N-1 internal nodes.
- *  - Internal nodes require 4 bytes each. Leaves are free. */
-#define LOOKUP_BYTES(nr_syms) (((nr_syms)-1)*4)
-
-        /* a0 = len[], a1 = nodes[], d0 = nr_symbols */
-        /* a2-a3 are scratched */
-build_code:
-        movem.l d0-d5,-(aS)
-
-        /* Allocate space for bl_count[]/next_code[] array on stack. */
-        moveq   #(MAX_CODE_LEN+1)/2,d1
-        moveq   #0,d2
-1:      move.l  d2,-(aS)
-        dbf     d1,1b
-
-        /* Count occurrences of each code length into bl_count[] array. */
-        subq.w  #1,d0
-        move.w  d0,d1
-        move.l  a0,a2           /* a2 = &len[0] */
-1:      move.b  (a2)+,d2        /* d2 = len[i] */
-        add.b   d2,d2
-        addq.w  #1,(aS,d2.w)    /* bl_count[len[i]]++ */
-        dbf     d1,1b
-
-        /* Calculate next_code[] start values for each code length. */
-        move.l  aS,a2           /* a2 = bl_count[] / next_code[] */
-        moveq   #MAX_CODE_LEN-1,d1
-        moveq   #0,d2           /* d2 = code */
-        move.w  d2,(aS)         /* bl_count[0] = 0, ignore zero-length codes */
-1:      add.w   (a2),d2
-        add.w   d2,d2           /* code = (code + bl_count[i-1]) << 1 */
-        move.w  d2,(a2)+        /* next_code[i] = code */
-        dbf     d1,1b
-
-        /* Create the Huffman-code lookup tree */
-        move.w  d0,d1
-        moveq   #0,d4           /* d4 = next_node */
-        move.l  a0,a2           /* a2 = &len[0] */
-1:      moveq   #0,d5
-        move.b  (a2)+,d5        /* d5 = len[i] / *len++ */
-        jeq     4f
-        subq.w  #1,d5
-        add.w   d5,d5
-        move.w  (aS,d5.w),d3    /* d3 = code = next_code[len[i]]++ */
-        addq.w  #1,(aS,d5.w)
-        lsr.w   #1,d5
-        /* Walk down the tree, creating nodes as necessary */
-        moveq   #0,d2           /* d2 = 0 (root node) */
-        jra     3f
-
-2:      /* Walk through *pnode. */
-        move.w  (a3),d2         /* d2 = *pnode */
-        jne     3f
-        /* Link missing: Create a new internal node */
-        addq.w  #1,d4
-        move.w  d4,d2
-        bset    #15,d2
-        move.w  d2,(a3)         /* *pnode = ++next_node | INTERNAL */
-3:      /* Take left or right branch depending on next code bit */
-        lsl.w   #2,d2
-        btst    d5,d3
-        jeq     3f
-        addq.w  #2,d2
-3:      lea     (a1,d2.w),a3    /* pnode = next_bit ? &node->r : &node->l */
-        dbf     d5,2b
-
-        /* Insert the current symbol as a new leaf node */
-        move.w  d0,d2
-        sub.w   d1,d2
-        move.w  d2,(a3)         /* *pnode = sym */
-4:      dbf     d1,1b
-
-        lea     (((MAX_CODE_LEN+1)/2)+1)*4(aS),aS
-        movem.l (aS)+,d0-d5
-        rts
-
-        /* d5-d6/a5 = stream, a0 = tree */
-        /* d0.w = result */
-.macro STREAM_NEXT_SYMBOL
-        moveq   #0,d0
-99:     /* stream_next_bits(1), inlined & optimised */
-        subq.b  #1,d6           /* 4 cy */
-        jcc     98f             /* 10 cy (taken) */
-        move.b  (a5)+,d5        /* [8 cy] */
-        moveq   #7,d6           /* [4 cy] */
-98:     lsr.w   #1,d5           /* 8 cy */
-        addx.w  d0,d0           /* 4 cy */
-        add.w   d0,d0           /* 4 cy */
-        move.w  (a0,d0.w),d0    /* 14 cy */
-        jmi     99b             /* 10 cy (taken); loop on INTERNAL flag set */
-                                /* TOTAL LOOP CYCLES ~= 54 */
-.endm
-
-#endif
-
-        /* d1.b = nr, d5-d6/a5 = stream [fetched_bits/nr_fetched_bits/inp] */
-        /* d0.w = result */
-.macro  STREAM_NEXT_BITS
-99:     moveq   #0,d0
-        cmp.b   d1,d6
-        jcc     99f             /* while (s->nr < nr) */
-        move.b  (a5)+,d0
-        lsl.l   d6,d0
-        or.l    d0,d5           /* s->cur |= *p++ << s->nr */
-        addq.b  #8,d6           /* s->nr += 8 */
-        jra     99b
-99:     bset    d1,d0
-        subq.w  #1,d0           /* d0 = (1<<nr)-1 */
-        and.w   d5,d0           /* d0 = s->cur & ((1<<nr)-1) */
-        lsr.l   d1,d5           /* s->cur >>= nr */
-        sub.b   d1,d6           /* s->nr -= nr */
-.endm
-
-#if OPT_INLINE_FUNCTIONS
-#define INLINE_stream_next_bits   STREAM_NEXT_BITS
-#define INLINE_stream_next_symbol STREAM_NEXT_SYMBOL
-#else
-#define INLINE_stream_next_bits   jbsr stream_next_bits
-#define INLINE_stream_next_symbol jbsr stream_next_symbol
-#endif
-
-stream_next_bits:
-        STREAM_NEXT_BITS
-        rts
-
-        /* d5-d6/a5 = stream, a4 = output */
-        /* d0-d1 are scratched */
-uncompressed_block:
-#if OPT_TABLE_LOOKUP
-        /* Push whole bytes back into input stream. */
-        lsr.w   #3,d6
-        sub.w   d6,a5
-#else
-        /* No need to push bytes back into input stream because stream_next_
-         * {bits,symbol} will never leave more than 7 bits cached. */
-#endif
-        /* Snap input stream up to byte boundary. */
-        moveq   #0,d5
-        moveq   #0,d6
-        /* Read block header and copy LEN bytes. */
-        moveq   #16,d1
-        jbsr    stream_next_bits /* LEN */
-        addq.w  #2,a5           /* skip NLEN */
-        subq.w  #1,d0           /* d0.w = len-1 (for dbf) */
-1:      move.b  (a5)+,(a4)+
-        dbf     d0,1b
-        rts
-
-#define o_hdist /*0*/
-#define o_hlit  2
-#define o_lens  (o_hlit+2)
-#define o_codelen_tree (o_lens+nr_litlen_symbols+nr_distance_symbols)
-#if OPT_TABLE_LOOKUP
-/* Lit/len and codelen lookup structures share space. */
-#define o_litlen_tree o_codelen_tree
-#else
-#define o_litlen_tree (o_codelen_tree+LOOKUP_BYTES(nr_codelen_symbols))
-#endif
-#define o_dist_tree (o_litlen_tree+LOOKUP_BYTES(nr_litlen_symbols))
-#define o_stream (o_dist_tree+LOOKUP_BYTES(nr_distance_symbols))
-#define o_frame (o_stream+3*4)
-#if OPT_STORAGE_OFFSTACK
-#define o_mode (o_frame)
-#else
-/* Allow for BSR return address from decoder */
-#define o_mode (o_frame+4)
-#endif
-#define o_dist_extra (o_mode+4)
-#define o_length_extra (o_dist_extra+30*4)
-
-        /* d5-d6/a5 = stream, a4 = output */
-        /* d0-d4,a0-a3 are scratched */
-static_huffman:
-        movem.l d5-d6/a5,-(aS)
-        moveq   #0,d5
-        moveq   #0,d6
-        lea     static_huffman_prefix(pc),a5
-        move.w  #o_stream/4-2,d0
-        jra     1f
-
-        /* d5-d6/a5 = stream, a4 = output */
-        /* d0-d4,a0-a3 are scratched */
-dynamic_huffman:
-        /* Allocate stack space for len[] and node[] arrays */
-        move.w  #o_frame/4-2,d0
-1:      moveq   #0,d1
-1:      move.l  d1,-(aS)
-        dbf     d0,1b
-        /* HLIT = stream_next_bits(5) + 257 */
-        moveq   #5,d1
-        jbsr    stream_next_bits
-        add.w   #257,d0
-        move.w  d0,-(aS)
-        /* HDIST = stream_next_bits(5) + 1 */
-        moveq   #5,d1
-        jbsr    stream_next_bits
-        addq.w  #1,d0
-        move.w  d0,-(aS)
-        /* HCLEN = stream_next_bits(4) + 4 */
-        moveq   #4,d1
-        jbsr    stream_next_bits
-        addq.w  #4-1,d0         /* -1 for dbf */
-        /* Initialise len[] array with code-length symbol code lengths */
-        lea     codelen_order(pc),a1
-        lea     o_lens(aS),a0   /* a0 = len[] */
-        moveq   #0,d2
-        move.w  d0,d3
-1:      moveq   #3,d1
-        jbsr    stream_next_bits
-        move.b  (a1)+,d2
-        move.b  d0,(a0,d2.w)    /* len[codelen_order[i++]] = next_bits(3) */
-        dbf     d3,1b
-        /* Build the codelen_tree */
-        lea     o_codelen_tree(aS),a1
-        moveq   #nr_codelen_symbols,d0
-#if OPT_TABLE_LOOKUP
-        moveq   #127,d1         /* don't left-shift any symbols */
-#endif
-        jbsr    build_code      /* build_code(codelen_tree) */
-        /* Read the literal/length & distance code lengths */
-        move.w  o_hlit(aS),d2
-        add.w   o_hdist(aS),d2
-        subq.w  #1,d2           /* d2 = hlit+hdist-1 */
-        move.l  a0,a2           /* a2 = len[] */
-        move.l  a1,a0           /* a0 = a1 = codelen_tree */
-1:      INLINE_stream_next_symbol
-        cmp.b   #16,d0
-        jcs     c_lit
-        jeq     c_16
-        cmp.b   #17,d0
-        jeq     c_17
-c_18:   /* 18: Repeat zero N times */
-        moveq   #7,d1
-        jbsr    stream_next_bits
-        addq.w  #11-3,d0
-        jra     2f
-c_17:   /* 17: repeat zero N times */
-        moveq   #3,d1
-        jbsr    stream_next_bits
-2:      moveq   #0,d1
-        jra     3f
-c_16:   /* 16: repeat previous N times */
-        moveq   #2,d1
-        jbsr    stream_next_bits
-        move.b  -1(a2),d1
-3:      addq.w  #3-1,d0
-        sub.w   d0,d2
-4:      move.b  d1,(a2)+
-        dbf     d0,4b
-        jra     5f
-c_lit:  /* 0-16: Literal symbol */
-        move.b  d0,(a2)+
-5:      dbf     d2,1b
-        /* Build the lit/len and distance trees */
-#if OPT_TABLE_LOOKUP
-        /* Clear the codelen tree (shared space with lit/len tree).
-         * NB. a0 = a1 = codelen_tree = litlen_tree */
-        moveq   #0,d0
-        move.w  #LOOKUP_BYTES(nr_codelen_symbols)/4-1,d1
-1:      move.l  d0,(a0)+
-        dbf     d1,1b
-        /* litlen_tree (= codelen_tree) is already in a1, and now zeroed. */
-#else
-        lea     o_litlen_tree(aS),a1
-#endif
-        lea     o_lens(aS),a0
-        move.w  o_hlit(aS),d0
-#if OPT_TABLE_LOOKUP
-        move.w  #256,d1
-        move.w  d1,d4           /* left-shift symbols >127 (i.e., lengths) */
-#endif
-        jbsr    build_code      /* build_code(litlen_tree) */
-        add.w   d0,a0
-        lea     o_dist_tree(aS),a1
-        move.w  o_hdist(aS),d0
-#if OPT_TABLE_LOOKUP
-        moveq   #0,d1           /* left-shift all symbols (i.e., distances) */
-#endif
-        jbsr    build_code      /* build_code(dist_tree) */
-        /* Reinstate the main stream if we used the static prefix */
-        tst.l   o_stream+8(aS)
-        jeq     decode_loop
-        movem.l o_stream(aS),d5-d6/a5
-        /* Now decode the compressed data stream up to EOB */
-decode_loop:
-        lea     o_litlen_tree(aS),a0
-        /* START OF HOT LOOP */
-2:      INLINE_stream_next_symbol /* litlen_sym */
-#if OPT_TABLE_LOOKUP
-        cmp.w   d4,d0    /*  4 cy (d4.w = 256) */
-#else
-        cmp.w   #256,d0  /*  8 cy */
-#endif
-        jcc     2f       /*  8 cy */
-        /* 0-255: Byte literal */
-        move.b  d0,(a4)+ /*  8 cy */
-        jra     2b       /* 10 cy */
-        /* END OF HOT LOOP -- 30 + ~108 + [34] = ~160 CYCLES */
-9:      /* 256: End-of-block: we're done */
-        lea     o_frame(aS),aS
-        rts
-2:      jeq     9b
-        /* 257+: <length,distance> pair */
-#if !OPT_TABLE_LOOKUP /* Already shifted in case of OPT_TABLE_LOOKUP */
-        lsl.w   #2,d0
-#endif
-        lea     o_length_extra-257*4(aS),a2
-        add.w   d0,a2
-        move.w  (a2)+,d1
-        INLINE_stream_next_bits
-        add.w   (a2),d0
-        move.w  d0,d3           /* d3 = cplen */
-        lea     o_dist_tree(aS),a0
-        INLINE_stream_next_symbol /* dist_sym */
-#if !OPT_TABLE_LOOKUP /* Already shifted in case of OPT_TABLE_LOOKUP */
-        lsl.w   #2,d0
-#endif
-        lea     o_dist_extra(aS),a2
-        add.w   d0,a2
-        move.w  (a2)+,d1
-        INLINE_stream_next_bits
-        add.w   (a2),d0         /* d0 = cpdst */
-        move.l  a4,a0
-        sub.w   d0,a0           /* a0 = outp - cpdst */
-#if OPT_UNROLL_COPY_LOOP
-        lsr.w   #1,d3
-        jcs     4f
-        subq.w  #1,d3
-3:      move.b  (a0)+,(a4)+
-4:      move.b  (a0)+,(a4)+
-#else
-        subq.w  #1,d3
-3:      move.b  (a0)+,(a4)+
-#endif
-        dbf     d3,3b
-        jra     decode_loop
-
-#if !OPT_INLINE_FUNCTIONS
-stream_next_symbol:
-        STREAM_NEXT_SYMBOL
-        rts
-#endif
-
-        /* Build a base/extra-bits table on the stack.
-         * d0 = #pairs-1, d2 = max_value, d4 = log_2(extrabits_repeat) */
-build_base_extrabits:
-#if !OPT_STORAGE_OFFSTACK
-        move.l  (sp)+,a0
-#endif
-1:      move.w  d0,d3
-        lsr.w   d4,d3
-        subq.w  #1,d3
-        jcc     2f
-        moveq   #0,d3
-2:      moveq   #0,d1
-        bset    d3,d1    /* d1 = 1 << extrabits */
-        sub.w   d1,d2    /* d2 = base */
-        move.w  d2,-(aS)
-        move.w  d3,-(aS)
-        dbf     d0,1b
-#if !OPT_STORAGE_OFFSTACK
-        jmp     (a0)
-#else
-        rts
-#endif
-
-dispatch: /* Decoder dispatch table. */
-        dc.b uncompressed_block - uncompressed_block
-        dc.b static_huffman - uncompressed_block
-        dc.b dynamic_huffman - uncompressed_block
-
-codelen_order: /* Order of code lengths for the code length alphabet. */
-        dc.b 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
-
-        /* a4 = output, a5 = input, all regs preserved
-         * a6 = *end* of storage area (only if OPT_STORAGE_OFFSTACK) */
-_inflate:
-        movem.l SAVE_RESTORE_REGS,-(aS)
-
-        /* Build the <length> base/extra-bits table */
-        move.l  #258,d2
-        move.l  d2,-(aS)
-        addq.w  #1,d2
-        moveq   #27,d0
-        moveq   #2,d4
-        jbsr    build_base_extrabits
-
-        /* Build the <distance> base/extra-bits table */
-        move.w  #32769,d2
-        moveq   #29,d0
-        moveq   #1,d4
-        jbsr    build_base_extrabits
-
-        /* Initialise the stream */
-        moveq   #0,d5           /* d5 = stream: fetched data */
-        moveq   #0,d6           /* d6 = stream: nr fetched bits */
-
-1:      /* Process a block: Grab the BTYPE|BFINAL 3-bit code */
-        moveq   #3,d1
-        jbsr    stream_next_bits
-        move.l  d0,-(aS)
-        /* Dispatch to the correct decoder for this block */
-        lsr.b   #1,d0
-        move.b  dispatch(pc,d0.w),d0
-        lea     uncompressed_block(pc),a0
-        jsr     (a0,d0.w)
-        /* Keep going until we see BFINAL=1 */
-        move.l  (aS)+,d0
-        lsr.b   #1,d0
-        jcc     1b
-
-        /* Pop the base/extra-bits lookup tables */
-        lea     (30+29)*4(aS),aS
-
-        movem.l (aS)+,SAVE_RESTORE_REGS
-        rts
-
-#if OPT_PREGENERATE_TABLES
-pregen_static_huffman:
-        lea     -o_frame(aS),aS         /* frame pre-generated; skip over it */
-        move.w  #256,d4
-        jra     decode_loop
-pregen_dynamic_huffman:
-        move.l  (aS),d0
-        lea     -3000(aS),aS            /* move to dynamic-huffman frame */
-        move.l  d0,(aS)                 /* copy o_mode into it */
-        jbsr    dynamic_huffman
-        lea     3000(aS),aS
-        rts
-
-        /* Pre-generate conversion tables for Inflate. */
-        /* a6 = Pointer to end of 6000-byte block of memory to contain
-         * pre-generated tables. All registers preserved. */
-inflate_gentables:
-        movem.l a5-a6,-(sp)
-        lea     pregen_dummy_block(pc),a5
-        jbsr    inflate                 /* static block */
-        lea     -3000(aS),aS
-        lea     pregen_dummy_block(pc),a5
-        jbsr    inflate                 /* dynamic block */
-        movem.l (sp)+,a5-a6
-        rts
-
-        /* Inflate, using pre-generated tables. */
-        /* a4 = output, a5 = input, all regs preserved
-         * a6 = *end* of 6000-byte pre-generated storage area */
-inflate_fromtables:
-        movem.l SAVE_RESTORE_REGS,-(aS)
-
-        /* Skip the pre-generated base/extra-bits lookup tables */
-        lea     -(30+29)*4(aS),aS
-
-        /* Initialise the stream */
-        moveq   #0,d5           /* d5 = stream: fetched data */
-        moveq   #0,d6           /* d6 = stream: nr fetched bits */
-
-1:      /* Process a block: Grab the BTYPE|BFINAL 3-bit code */
-        moveq   #3,d1
-        jbsr    stream_next_bits
-        move.l  d0,-(aS)
-        /* Dispatch to the correct decoder for this block */
-        and.b   #0xfe,d0
-        move.w  pregen_dispatch(pc,d0.w),d0
-        lea     uncompressed_block(pc),a0
-        jsr     (a0,d0.w)
-        /* Keep going until we see BFINAL=1 */
-        move.l  (aS)+,d0
-        lsr.b   #1,d0
-        jcc     1b
-
-        /* Pop the base/extra-bits lookup tables */
-        lea     (30+29)*4(aS),aS
-
-        movem.l (aS)+,SAVE_RESTORE_REGS
-        rts
-
-pregen_dispatch:
-        dc.w uncompressed_block - uncompressed_block
-        dc.w pregen_static_huffman - uncompressed_block
-        dc.w pregen_dynamic_huffman - uncompressed_block
-pregen_dummy_block: /* A single static block containing EOB symbol only */
-        dc.b    0x03,0x00
-#endif /* OPT_PREGENERATE_TABLES */
-
-#undef o_hdist
-#undef o_hlit
-#undef o_lens
-#undef o_codelen_tree
-#undef o_litlen_tree
-#undef o_dist_tree
-#undef o_frame
diff --git a/utilities/stateload/main.c b/utilities/stateload/main.c
deleted file mode 100644 (file)
index 84cd3a0..0000000
+++ /dev/null
@@ -1,1657 +0,0 @@
-
-/* Real hardware UAE state file loader */
-/* Copyright 2019 Toni Wilen */
-
-#define VER "2.0 BETA #1"
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <exec/types.h>
-#include <exec/execbase.h>
-#include <proto/exec.h>
-#include <proto/graphics.h>
-#include <proto/dos.h>
-#include <proto/expansion.h>
-#include <graphics/gfxbase.h>
-#include <dos/dosextens.h>
-#include <hardware/cia.h>
-#include <hardware/custom.h>
-
-#include "header.h"
-
-extern struct GfxBase *GfxBase;
-extern struct DosLibrary *DosBase;
-
-static const UBYTE *const version = "$VER: ussload " VER " (" REVDATE ")";
-
-static const char *const chunknames[] =
-{
-       "ASF ",
-       "CPU ", "CHIP", "AGAC",
-       "CIAA", "CIAB", "ROM ",
-       "DSK0", "DSK1", "DSK2", "DSK3",
-       "AUD0", "AUD1", "AUD2", "AUD3",
-       "END ",
-       NULL
-};
-static const char *const memchunknames[] =
-{
-       "CRAM", "BRAM", "FRAM",
-       NULL
-};
-static const char *const unsupportedchunknames[] =
-{
-       "FRA2", "FRA3", "FRA4",
-       "ZRA2", "ZRA3", "ZRA4",
-       "ZCRM", "PRAM",
-       "A3K1", "A3K2",
-       "BORO", "P96 ",
-       "FSYC",
-       NULL
-};
-
-static ULONG getlong(UBYTE *chunk, int offset)
-{
-       ULONG v;
-       
-       chunk += offset;
-       v = (chunk[0] << 24) | (chunk[1] << 16) | (chunk[2] << 8) | (chunk[3] << 0);
-       return v;
-}
-static ULONG getword(UBYTE *chunk, int offset)
-{
-       ULONG v;
-       
-       chunk += offset;
-       v = (chunk[0] << 8) | (chunk[1] << 0);
-       return v;
-}
-
-static void set_agacolor(UBYTE *p)
-{
-       volatile struct Custom *c = (volatile struct Custom*)0xdff000;
-
-       int aga = (c->vposr & 0x0f00) == 0x0300;
-       if (!aga)
-               return;
-       
-       for (int i = 0; i < 8; i++) {
-               for (int k = 0; k < 2; k++) {
-                       c->bplcon3 = (i << 13) | (k ? (1 << 9) : 0);
-                       for (int j = 0; j < 32; j++) {
-                               ULONG c32 = getlong(p, (j + i * 32) * 4);
-                               if (!k)
-                                       c32 >>= 4;
-                               // R1R2G1G2B1B2 -> R2G2B2
-                               UWORD col = ((c32 & 0x00000f) << 0) | ((c32 & 0x000f00) >> 4) | ((c32 & 0x0f0000) >> 8);
-                               if (!k && (c32 & 0x80000000))
-                                       col |= 0x8000; // genlock transparency bit
-                               c->color[j] = col;
-                       }                       
-               }
-       }
-       c->bplcon3 = 0x0c00;
-}
-
-static void wait_lines(WORD lines)
-{
-       volatile struct Custom *c = (volatile struct Custom*)0xdff000;
-
-       UWORD line = c->vhposr & 0xff00;
-       while (lines-- > 0) {
-               for (;;) {
-                       UWORD line2 = c->vhposr & 0xff00;
-                       if (line == line2)
-                               continue;
-                       line = line2;
-                       break;
-               }
-       }
-}
-
-static void step_floppy(void)
-{
-       volatile struct CIA *ciab = (volatile struct CIA*)0xbfd000;
-       ciab->ciaprb &= ~CIAF_DSKSTEP;
-       // delay
-       ciab->ciaprb &= ~CIAF_DSKSTEP;
-       ciab->ciaprb |= CIAF_DSKSTEP;
-       wait_lines(200);
-}
-
-static void reset_floppy(struct uaestate *st)
-{
-       volatile struct CIA *ciab = (volatile struct CIA*)0xbfd000;
-
-       // all drives motor off
-       ciab->ciaprb = 0xff;
-       // select all
-       ciab->ciaprb &= ~(15 << 3);
-       // deselect all
-       ciab->ciaprb |= 15 << 3;
-}
-
-static void set_floppy(UBYTE *p, ULONG num)
-{
-       ULONG id = getlong(p, 0);
-       UBYTE state = p[4];
-       UBYTE track = p[5];
-
-       // drive disabled?
-       if (state & 2)
-               return;
-       // invalid track?
-       if (track >= 80)
-               return;
-
-       volatile struct CIA *ciaa = (volatile struct CIA*)0xbfe001;
-       volatile struct CIA *ciab = (volatile struct CIA*)0xbfd000;
-
-       ciab->ciaprb = 0xff;
-       
-       // motor on?
-       if (state & 1) {
-               ciab->ciaprb &= ~CIAF_DSKMOTOR;
-       }
-       // select drive
-       ciab->ciaprb &= ~(CIAF_DSKSEL0 << num);
-
-       wait_lines(100);
-       int seekcnt = 80;
-       while (seekcnt-- > 0) {
-               if (!(ciaa->ciapra & CIAF_DSKTRACK0))
-                       break;
-               step_floppy();
-       }
-       wait_lines(100);
-       if (seekcnt <= 0) {
-               // no track0 after 80 steps: drive missing or not responding
-               ciab->ciaprb |= CIAF_DSKMOTOR;
-               ciab->ciaprb |= CIAF_DSKSEL0 << num;
-               return;
-       }
-       
-       ciab->ciaprb &= ~CIAF_DSKDIREC;
-       wait_lines(800);
-       for (UBYTE i = 0; i < track; i++) {
-               step_floppy();
-       }
-
-       ciab->ciaprb |= CIAF_DSKSEL0 << num;
-}
-
-// current AUDxLEN and AUDxPT
-static void set_audio(UBYTE *p, ULONG num)
-{
-       volatile struct Custom *c = (volatile struct Custom*)0xdff000;
-       ULONG l;
-       c->aud[num].ac_vol = p[1]; // AUDxVOL
-       c->aud[num].ac_per = getword(p, 1 + 1 + 1 + 1 + 2 + 2 + 2); // AUDxPER
-       c->aud[num].ac_len = getword(p, 1 + 1 + 1 + 1 + 2); // AUDxLEN
-       l = getword(p, 1 + 1 + 1 + 1 + 2 + 2 + 2 + 2 + 2 + 2) << 16; // AUDxLCH
-       l |= getword(p, 1 + 1 + 1 + 1 + 2 + 2 + 2 + 2 + 2 + 2 + 2); // AUDxLCL
-       c->aud[num].ac_ptr = (UWORD*)l;
-}
-
-// latched AUDxLEN and AUDxPT
-void set_audio_final(struct uaestate *st)
-{
-       volatile struct Custom *c = (volatile struct Custom*)0xdff000;
-       for (UWORD num = 0; num < 4; num++) {
-               UBYTE *p = st->audio_chunk[num];
-               ULONG l;
-               c->aud[num].ac_len = getword(p, 1 + 1 + 1 + 1); // AUDxLEN
-               l = getword(p, 1 + 1 + 1 + 1 + 2 + 2 + 2 + 2) << 16; // AUDxLCH
-               l |= getword(p, 1 + 1 + 1 + 1 + 2 + 2 + 2 + 2 + 2); // AUDxLCL
-               c->aud[num].ac_ptr = (UWORD*)l;
-       }
-}
-
-static void set_sprite(UBYTE *p, ULONG num)
-{
-       volatile struct Custom *c = (volatile struct Custom*)0xdff000;
-       ULONG l;
-       
-       l = getword(p, 0) << 16; // SPRxPTH
-       l |= getword(p, 2); // SPRxPTL
-       c->sprpt[num] = (APTR)l;
-       c->spr[num].pos = getword(p, 2 + 2); // SPRxPOS
-       c->spr[num].ctl = getword(p, 2 + 2 + 2); // SPRxCTL
-}
-
-static void set_custom(struct uaestate *st)
-{
-       volatile UWORD *c = (volatile UWORD*)0xdff000;
-       UBYTE *p = st->custom_chunk;
-       p += 4;
-       for (WORD i = 0; i < 0x1fe; i += 2, c++) {
-
-               // sprites
-               if (i >= 0x120 && i < 0x180)
-                       continue;
-                       
-               // audio
-               if (i >= 0xa0 && i < 0xe0)
-                       continue;
-
-               // skip blitter start, DMACON, INTENA, registers
-               // that are write strobed, unused registers,
-               // read-only registers.
-               switch(i)
-               {
-                       case 0x00:
-                       case 0x02:
-                       case 0x04:
-                       case 0x06:
-                       case 0x08:
-                       case 0x10:
-                       case 0x16:
-                       case 0x18:
-                       case 0x1a:
-                       case 0x1c:
-                       case 0x1e:
-                       case 0x24: // DSKLEN
-                       case 0x26:
-                       case 0x28:
-                       case 0x2a: // VPOSW
-                       case 0x2c: // VHPOSW
-                       case 0x30:
-                       case 0x38:
-                       case 0x3a:
-                       case 0x3c:
-                       case 0x3e:
-                       case 0x58:
-                       case 0x5a:
-                       case 0x5e:
-                       case 0x68:
-                       case 0x6a:
-                       case 0x6c:
-                       case 0x6e:
-                       case 0x76:
-                       case 0x78:
-                       case 0x7a:
-                       case 0x7c:
-                       case 0x88:
-                       case 0x8a:
-                       case 0x8c:                      
-                       case 0x96: // DMACON
-                       case 0x9a: // INTENA
-                       case 0x9c: // INTREQ
-                       p += 2;
-                       continue;
-               }
-
-               // skip programmed sync registers except BEAMCON0
-               // skip unused registers
-               if (i >= 0x1c0 && i < 0x1fc && i != 0x1e4 && i != 0x1dc) {
-                       p += 2;
-                       continue;
-               }
-
-               UWORD v = getword(p, 0);
-               p += 2;
-
-               // diwhigh
-               if (i == 0x1e4) { 
-                       // diwhigh_written not set? skip.
-                       if (!(v & 0x8000))
-                               continue;
-                       v &= ~0x8000;
-               }
-
-               // BEAMCON0: PAL/NTSC only
-               if (i == 0x1dc) {
-                       if (st->flags & FLAGS_FORCEPAL)
-                               v = 0x20;
-                       else if (st->flags & FLAGS_FORCENTSC)
-                               v = 0x00;
-                       v &= 0x20;
-               }
-
-               // ADKCON
-               if (i == 0x9e) {
-                       v |= 0x8000;
-               }
-
-               *c = v;
-       }
-}
-
-void set_custom_final(UBYTE *p)
-{
-       volatile struct Custom *c = (volatile struct Custom*)0xdff000;
-       c->intena = 0x7fff;
-       c->intreq = 0x7fff;
-       c->vposw = (getword(p, 4 + 0x04) & 0x8000) | (c->vposr & 7); // set LOF
-       c->dmacon = getword(p, 4 + 0x96) | 0x8000;
-       c->intena = getword(p, 4 + 0x9a) | 0x8000;
-       c->intreq = getword(p, 4 + 0x9c) | 0x8000;
-}
-
-static void set_cia(UBYTE *p, ULONG num)
-{
-       volatile struct CIA *cia = (volatile struct CIA*)(num ? 0xbfd000 : 0xbfe001);
-       volatile struct Custom *c = (volatile struct Custom*)0xdff000;
-
-       cia->ciacra &= ~(CIACRAF_START | CIACRAF_RUNMODE);
-       cia->ciacrb &= ~(CIACRBF_START | CIACRBF_RUNMODE);
-       volatile UBYTE dummy = cia->ciaicr;
-       cia->ciaicr = 0x7f;
-       c->intreq = 0x7fff;
-       
-       p[14] &= ~CIACRAF_LOAD;
-       p[15] &= ~CIACRAF_LOAD;
-       
-       UBYTE flags = p[16 + 1 + 2 * 2 + 3 + 3];
-       
-       cia->ciapra = p[0];
-       cia->ciaprb = p[1];
-       cia->ciaddra = p[2];
-       cia->ciaddrb = p[3];
-       
-       // load timers
-       cia->ciatalo = p[4];
-       cia->ciatahi = p[5];
-       cia->ciatblo = p[6];
-       cia->ciatbhi = p[7];
-       cia->ciacra |= CIACRAF_LOAD;
-       cia->ciacrb |= CIACRBF_LOAD;
-       // load timer latches
-       cia->ciatalo = p[16 + 1];
-       cia->ciatahi = p[16 + 2];
-       cia->ciatblo = p[16 + 3];
-       cia->ciatbhi = p[16 + 4];
-       
-       // load alarm
-       UBYTE *alarm = &p[16 + 1 + 2 * 2 + 3];
-       cia->ciacrb |= CIACRBF_ALARM;
-       if (flags & 2) {
-               // leave latched
-               cia->ciatodlow = alarm[0];      
-               cia->ciatodmid = alarm[1];
-               cia->ciatodhi = alarm[2];
-       } else {
-               cia->ciatodhi = alarm[2];
-               cia->ciatodmid = alarm[1];
-               cia->ciatodlow = alarm[0];
-       }
-       cia->ciacrb &= ~CIACRBF_ALARM;
-
-       // load tod
-       UBYTE *tod = &p[8];
-       if (flags & 1) {
-               // leave latched
-               cia->ciatodlow = tod[0];
-               cia->ciatodmid = tod[1];
-               cia->ciatodhi = tod[2];
-       } else {
-               cia->ciatodhi = tod[2];
-               cia->ciatodmid = tod[1];
-               cia->ciatodlow = tod[0];
-       }
-}
-
-void set_cia_final(UBYTE *p, ULONG num)
-{
-       volatile struct CIA *cia = (volatile struct CIA*)(num ? 0xbfd000 : 0xbfe001);
-       volatile UBYTE dummy = cia->ciaicr;
-       cia->ciaicr = p[16] | CIAICRF_SETCLR;   
-}
-
-static void free_allocations(struct uaestate *st)
-{
-       for (int i = st->num_allocations - 1; i >= 0; i--) {
-               struct Allocation *a = &st->allocations[i];
-               if (a->mh) {
-                       Deallocate(a->mh, a->addr, a->size);            
-               } else {
-                       FreeMem(a->addr, a->size);
-               }
-       }
-}
-
-static struct Allocation *add_allocation(void *addr, ULONG size, struct uaestate *st)
-{
-       if (st->num_allocations >= ALLOCATIONS) {
-               printf("ERROR: Too many allocations!\n");
-               return NULL;
-       }
-       struct Allocation *a = &st->allocations[st->num_allocations++];
-       a->addr = addr;
-       a->size = size;
-       return a;
-}
-
-static ULONG mmu_remap(ULONG addr, ULONG size, BOOL wp, struct uaestate *st)
-{
-       if (!st->canusemmu)
-               return 0;
-       void *phys = AllocMem(size + 4095, MEMF_FAST);
-       if (!phys) {
-               printf("MMU: Error allocating remap space for %08lx-%08lx.\n", addr, addr + size - 1);
-               return 0;
-       }
-       Forbid();
-       FreeMem(phys, size + 4095);
-       ULONG alignedphys = (((ULONG)phys) + 4095) & ~4095;
-       phys = AllocAbs(size, (void*)alignedphys);
-       Permit();
-       if (!phys)
-               return 0;
-       if (!map_region(st, (void*)addr, phys, size, FALSE, wp, FALSE, 0)) {
-               FreeMem(phys, size);
-               return 0;
-       }
-       add_allocation(phys, size, st);
-       st->mmuused++;
-       return alignedphys;
-}
-
-UBYTE *allocate_abs(ULONG size, ULONG addr, struct uaestate *st)
-{
-               UBYTE *b = AllocAbs(size, (APTR)addr);
-               if (b) {
-                       add_allocation(b, size, st);
-                       return b;
-               }
-               return NULL;
-}
-
-static UBYTE *extra_allocate(ULONG size, struct uaestate *st)
-{
-       UBYTE *b;
-       
-       for (;;) {
-               b = AllocAbs(size, st->extra_mem_pointer);
-               if (b) {
-                       add_allocation(b, size, st);
-                       st->extra_mem_pointer += (size + 7) & ~7;
-                       return b;
-               }
-               st->extra_mem_pointer += 8;
-               if (st->extra_mem_pointer + size >= st->extra_ram + st->extra_ram_size)
-                       return NULL;
-       }
-}
-
-// allocate from extra mem
-static UBYTE *tempmem_allocate(ULONG size, struct uaestate *st)
-{
-       UBYTE *b = NULL;
-       if (st->extra_mem_head) {
-               b = Allocate(st->extra_mem_head, size);
-               if (b) {
-                       struct Allocation *a = add_allocation(b, size, st);
-                       if (a)
-                               a->mh = st->extra_mem_head;
-               }
-       }
-       if (!b) {
-               b = extra_allocate(size, st);
-       }
-       return b;
-}
-
-// allocate from statefile reserved bank index
-static UBYTE *tempmem_allocate_reserved(ULONG size, WORD index, struct uaestate *st)
-{
-       struct MemoryBank *mb = &st->membanks[index];
-       if (!mb->targetsize)
-               return NULL;
-       UBYTE *addr = mb->targetaddr;
-       for (;;) {
-               addr += 32768;
-               if (addr - mb->targetaddr + size >= mb->targetsize)
-                       return NULL;
-               UBYTE *b = AllocAbs(size, addr);
-               if (b) {
-                       add_allocation(b, size, st);
-                       return b;
-               }
-       }
-}
-
-static void copyrom(ULONG addr, struct uaestate *st)
-{
-       ULONG *dst = (ULONG*)addr;
-       ULONG *src = (ULONG*)st->maprom;
-       UWORD cnt = st->mapromsize / 16;
-       for (UWORD i = 0; i < cnt; i++) {
-               *dst++ = *src++;
-               *dst++ = *src++;
-               *dst++ = *src++;
-               *dst++ = *src++;
-       }
-       if (st->mapromsize == 262144) {
-               src = (ULONG*)st->maprom;
-               for (UWORD i = 0; i < cnt; i++) {
-                       *dst++ = *src++;
-                       *dst++ = *src++;
-                       *dst++ = *src++;
-                       *dst++ = *src++;
-               }
-       }
-}
-
-static void set_maprom(struct uaestate *st)
-{
-       struct mapromdata *mrd = &st->mrd[1];
-       if (mrd->type == MAPROM_ACA500 || mrd->type == MAPROM_ACA500P) {
-               volatile UBYTE *base = (volatile UBYTE*)mrd->board;
-               base[0x3000] = 0;
-               base[0x7000] = 0;
-               base[0xf000] = 0;
-               base[0xb000] = 0;
-               base[0x23000] = 0;
-               copyrom(mrd->addr, st);
-               base[0x23000] = 0xff;
-               base[0x3000] = 0;
-       }
-       mrd = &st->mrd[0];
-       if (mrd->type == MAPROM_ACA1221EC) {
-               volatile UBYTE *base = (volatile UBYTE*)mrd->board;
-               base[0x1000] = 0x05;
-               base[0x1001] = 0x00;
-               base[0x2000] = 0x00;
-               base[0x1000] = 0x03;
-               base[0x1001] = 0x01;
-               base[0x2000] = 0x00;            
-               copyrom(0x600000, st);
-               copyrom(0x780000, st);
-               base[0x1000] = 0x03;
-               base[0x1001] = 0x00;
-               base[0x2000] = 0x00;
-               base[0x1000] = 0x05;
-               base[0x1001] = 0x01;
-               base[0x2000] = 0x00;
-       }
-       if (mrd->type == MAPROM_ACA12xx) {
-               ULONG mapromaddr = mrd->addr;
-               volatile UWORD *base = (volatile UWORD*)mrd->board;
-               base[0 / 2] = 0xffff;
-               base[4 / 2] = 0x0000;
-               base[8 / 2] = 0xffff;
-               base[12 / 2] = 0xffff;
-               base[0x18 / 2] = 0x0000; // maprom off
-               copyrom(mapromaddr, st);
-               copyrom(mapromaddr + 524288, st);
-               base[0x18 / 2] = 0xffff; // maprom on
-               volatile UWORD dummy = base[0];
-       }
-       if (mrd->type == MAPROM_ACA1233N) {
-               volatile UWORD *base = (volatile UWORD*)mrd->board;
-               ULONG mapromaddr = mrd->addr;
-               volatile UWORD dummy = base[0];
-               base[0x00 / 2] = 0xffff; // s unlock 0
-               base[0x02 / 2] = 0xffff; // s unlock 1
-               base[0x20 / 2] = 0xffff; // c unlock 0
-               base[0x04 / 2] = 0xffff; // s unlock 2
-               base[0x22 / 2] = 0xffff; // c unlock 1
-               base[0x06 / 2] = 0xffff; // s unlock 3
-               // maprom off
-               base[0x28 / 2] = 0xffff;
-               if (mrd->config) {
-                       // maprom overlay on
-                       for(int i = 0; i < 6; i++)
-                               base[0x1c / 2] = 0xffff;
-                       base[0x1a / 2] = 0xffff;
-               }
-               copyrom(mapromaddr, st);
-               copyrom(mapromaddr + 524288, st);
-               if (mrd->config) {
-                       // maprom overlay off
-                       base[0x3a / 2] = 0xffff;
-               }
-               // maprom on
-               base[0x08 / 2] = 0xffff;
-       }
-       if (mrd->type == MAPROM_GVP) {
-               copyrom(mrd->addr, st);
-               volatile UWORD *base = (volatile UWORD*)mrd->board;
-               *base = (UWORD)mrd->config;
-       }
-       if (mrd->type == MAPROM_BLIZZARD12x0) {
-               copyrom(mrd->addr, st);
-               volatile UBYTE *base = (volatile UBYTE*)mrd->board;
-               *base = (UBYTE)mrd->config;
-       }
-       if (mrd->type == MAPROM_MMU) {
-               copyrom(mrd->addr, st);
-       }
-}
-
-static BOOL has_maprom_blizzard(struct uaestate *st)
-{
-       struct mapromdata *mrd = &st->mrd[0];
-       struct ConfigDev *cd;
-       // 1230MKIV/1240/1260
-       cd  = (struct ConfigDev*)FindConfigDev(0, 8512, 17);
-       if (cd) {
-               mrd->type = MAPROM_BLIZZARD12x0;
-               mrd->addr = 0x4ff80000;
-       }
-       // 1230MKIII
-       cd  = (struct ConfigDev*)FindConfigDev(0, 8512, 13);
-       if (cd) {
-               mrd->type = MAPROM_BLIZZARD12x0;
-               mrd->addr = 0x1ef80000;
-       }
-       // 1230MKI/II
-       cd  = (struct ConfigDev*)FindConfigDev(0, 8512, 11);
-       if (cd) {
-               mrd->type = MAPROM_BLIZZARD12x0;
-               mrd->addr = 0x0ff80000;
-       }
-       mrd->board = (APTR)0x80ffff00;
-       mrd->config = 0x42;
-       if (st->debug && mrd->type)
-               printf("Blizzard12x0 MapROM %08lx\n", mrd->addr);
-       return mrd->type != 0;
-}
-
-
-static const ULONG gvp_a530[] =
-{
-       0x00a00000, 14,
-       0x00600000, 10,
-       0x00400000, 12,
-       0x00300000, 8,
-       0
-};
-static const ULONG gvp_gforce030[] =
-{
-       0x02000000, 10,
-       0x01c00000, 12,
-       0x01800000, 8,
-       0x01400000, 6,
-       0x00a00000, 2,
-       0x00600000, 4,
-       0
-};
-static const ULONG gvp_gforce2k_040[] =
-{
-       0x05000000, 8,
-       0x04000000, 12,
-       0x03000000, 10,
-       0x02000000, 14,
-       0x01c00000, 10,
-       0x01800000, 12,
-       0
-};
-#if 0
-static const ULONG gvp_gforce3k_040[] =
-{
-       0x08800000, 0xC0000000,
-       0x08400000, 0x80000000,
-       0
-};
-#endif
-
-static BOOL has_maprom_gvp(struct uaestate *st)
-{
-               struct mapromdata *mrd = &st->mrd[0];
-               struct ConfigDev *cd = (struct ConfigDev*)FindConfigDev(0, 2017, 11);
-               if (!cd)
-                       return FALSE;
-               UBYTE v = *((volatile UBYTE*)cd->cd_BoardAddr + 0x8001);
-               if (st->debug)
-                       printf("GVP ID=%02x\n", v);
-               const ULONG *gvpmaprom = NULL;
-               switch(v & 0xf8)
-               {
-                       case 0x20:
-                       case 0x30:
-                               gvpmaprom = gvp_gforce2k_040;
-                               break;
-                       case 0x60:
-                       case 0x70:
-                       case 0xe0:
-                       case 0xf0:
-                               gvpmaprom = gvp_gforce030;
-                               break;
-                       case 0xc0:
-                       case 0xd0:
-                               gvpmaprom = gvp_a530;
-                       break;
-                       case 0x40:
-                               break;
-               }
-               if (!gvpmaprom)
-                       return FALSE;
-               Forbid();
-               struct MemHeader *mh = (struct MemHeader*)SysBase->MemList.lh_Head;
-               while (mh->mh_Node.ln_Succ && !mrd->type) {
-                       ULONG mend = ((((ULONG)mh->mh_Upper) + 0xffff) & 0xffff0000);
-                       for (int i = 0; gvpmaprom[i]; i += 2) {
-                               if (gvpmaprom[i] == mend) {
-                                       mrd->type = MAPROM_GVP;
-                                       mrd->addr = mend - 524288;
-                                       mrd->config = gvpmaprom[i + 1];
-                                       mrd->board = cd->cd_BoardAddr + 0x68;
-                                       // ignore return value, maprom may be already enabled
-                                       allocate_abs(524288, mrd->addr, st);
-                                       break;
-                               }
-                       }
-                       mh = (struct MemHeader*)mh->mh_Node.ln_Succ;
-               }
-               Permit();
-               if (st->debug)
-                       printf("GVP Map ROM=%08lx\n", mrd->addr);
-               return mrd->type != 0;
-}
-
-static BOOL has_maprom_aca(struct uaestate *st)
-{
-       if (OpenResource("aca.resource")) {
-               struct mapromdata *mrd2 = &st->mrd[1];
-               // ACA500(+)
-               volatile UBYTE *base = (volatile UBYTE*)0xb00000;
-               Disable();
-               base[0x3000] = 0;
-               base[0x7000] = 0;
-               base[0xf000] = 0;
-               base[0xb000] = 0;
-               UBYTE id = 0;
-               if (base[0x13000] & 0x80)
-                       id |= 0x08;
-               if (base[0x17000] & 0x80)
-                       id |= 0x04;
-               if (base[0x1b000] & 0x80)
-                       id |= 0x02;
-               if (base[0x1f000] & 0x80)
-                       id |= 0x01;
-               if (id == 7) {
-                       mrd2->type = MAPROM_ACA500;
-                       mrd2->addr = 0x980000;
-               } else if (id == 8 || id == 9) {
-                       mrd2->type = MAPROM_ACA500P;
-                       mrd2->addr = 0xa00000;
-               }
-               mrd2->board = (APTR)base;
-               base[0x3000] = 0;
-               Enable();
-               if (st->debug)
-                       printf("ACA500/ACA500plus ID=%02x\n", id);
-       }
-       struct mapromdata *mrd = &st->mrd[0];
-       if (FindConfigDev(0, 0x1212, 33) || FindConfigDev(0, 0x1212, 68)) {
-               // ACA1233n 68030
-               mrd->type = MAPROM_ACA1233N;
-               mrd->addr = 0x47f00000;
-               mrd->board = (APTR)0x47e8f000;
-               mrd->config = 0;
-       } else if (FindConfigDev(0, 0x1212, 32) || FindConfigDev(0, 0x1212, 72)) {
-               // ACA1233n 68EC020
-               if ((ULONG)has_maprom_aca >= 0x200000) {
-                       mrd->type = MAPROM_ACA1233N;
-                       mrd->addr = 0x100000;
-                       mrd->board = (APTR)0xb8f000;
-                       mrd->config = 1;
-                       st->maprom_memlimit |= 1 << MB_CHIP;
-               }
-       } else if (FindConfigDev(0, 0x1212, 0x16)) {
-               // ACA1221EC
-               mrd->type = MAPROM_ACA1221EC;
-               mrd->addr = 0x780000;
-               mrd->board = (APTR)0xe90000;
-               // we can't use 0x200000 because it goes away when setting up maprom..
-               mrd->memunavailable = 0x00200000;
-       } else if (TypeOfMem((APTR)0x0bd80000)) { // at least 62M
-               // This test should be better..
-               // perhaps it is ACA12xx
-               Disable();
-               volatile UWORD *base = (volatile UWORD*)0xb8f000;
-               volatile UWORD dummy = base[0];
-               // unlock
-               base[0 / 2] = 0xffff;
-               base[4 / 2] = 0x0000;
-               base[8 / 2] = 0xffff;
-               base[12 / 2] = 0xffff;
-               UBYTE id = 0;
-               volatile UWORD *idbits = base + 4 / 2;
-               for (UWORD i = 0; i < 5; i++) {
-                       id <<= 1;
-                       if (idbits[0] & 1)
-                               id |= 1;
-                       idbits += 4 / 2;
-               }
-               UWORD mrtest = 0;
-               if (id != 0 && id != 31) {
-                       // test that maprom bit sticks
-                       UWORD oldmr = base[0x18 / 2];
-                       base[0x18 / 2] = 0xffff;
-                       dummy = base[0];
-                       mrtest = (base[0x18 / 2] & 0x8000) != 0;
-                       base[0 / 2] = 0xffff;
-                       base[4 / 2] = 0x0000;
-                       base[8 / 2] = 0xffff;
-                       base[12 / 2] = 0xffff;
-                       base[0x18 / 2] = oldmr;
-               }
-               dummy = base[0];
-               Enable();
-               if (st->debug)
-                       printf("ACA12xx ID=%02x. MapROM=%d\n", id, mrtest);
-               ULONG mraddr = 0;
-               if (mrtest) {
-                       if (TypeOfMem((APTR)0x0bf00000)) {
-                               if (!TypeOfMem((APTR)0x0fe80000)) {
-                                       mrd->type = MAPROM_ACA12xx;
-                                       mrd->addr = 0x0ff00000;
-                               }
-                       } else {
-                                       mrd->type = MAPROM_ACA12xx;
-                                       mrd->addr = 0x0bf00000;
-                       }
-               }
-               mrd->board = (APTR)base;
-       }
-       return st->mrd[0].type != 0;
-}
-
-static BOOL has_maprom_mmu(struct uaestate *st)
-{
-       if (!st->canusemmu)
-               return FALSE;
-       struct mapromdata *mrd = &st->mrd[0];
-       unmap_region(st, (void*)0xf80000, 524288);
-       mrd->addr = mmu_remap(0xf80000, 524288, FALSE, st);
-       if (mrd->addr) {
-               mrd->type = MAPROM_MMU;
-               return TRUE;
-       }
-       return FALSE;
-}
-
-static BOOL has_maprom(struct uaestate *st)
-{
-       if (!st->usemaprom)
-               return -1;
-       for (;;) {
-               if (has_maprom_mmu(st))
-                       break;
-               if (has_maprom_aca(st))
-                       break;
-               if (has_maprom_gvp(st))
-                       break;
-               if (!has_maprom_blizzard(st))
-                       break;
-               return FALSE;
-       }
-       if (st->debug) {
-               for (int i = 0; i < 2; i++) {
-                       struct mapromdata *mrd = &st->mrd[i];
-                       if (mrd->type)
-                               printf("MAPROM type %d. Addr=%08lx Board=%08lx Cfg=%08lx.\n", mrd->type, mrd->addr, mrd->board, mrd->config);
-               }
-       }
-       return st->mrd[0].type != 0 || st->mrd[1].type != 0;
-}
-
-static void load_rom(struct uaestate *st)
-{
-       UBYTE rompath[100], rompath2[100];
-       UBYTE *p;
-       
-       if (!st->mrd[0].type && !st->mrd[1].type)
-               return;
-       
-       sprintf(rompath, "DEVS:kickstarts/kick%d%03d.%s", st->romver, st->romrev, st->agastate ? "a1200" : "a500");
-       p = rompath;
-       FILE *f = fopen(rompath, "rb");
-       if (!f) {
-               sprintf(rompath2, "kick%d%03d.%s", st->romver, st->romrev, st->agastate ? "a1200" : "a500");
-               f = fopen(rompath2, "rb");
-               if (!f) {
-                       printf("Couldn't open ROM image '%s'\n", rompath);
-                       return;
-               }
-               p = rompath2;
-       }
-       fseek(f, 0, SEEK_END);
-       st->mapromsize = ftell(f);
-       fseek(f, 0, SEEK_SET);
-       if (!st->maprom && !(st->maprom_memlimit & (1 << MB_CHIP)))
-               st->maprom = tempmem_allocate_reserved(st->mapromsize, MB_CHIP, st);
-       if (!st->maprom && !(st->maprom_memlimit & (1 << MB_SLOW)))
-               st->maprom = tempmem_allocate_reserved(st->mapromsize, MB_SLOW, st);
-       if (!st->maprom)
-               st->maprom = tempmem_allocate(st->mapromsize, st);
-       if (!st->maprom) {
-               printf("Couldn't allocate %luk for ROM image '%s'.\n", st->mapromsize >> 10, p);
-               fclose(f);
-               return;
-       }
-       if (st->debug)
-               printf("MapROM temp %08lx\n", st->maprom);
-       if (fread(st->maprom, 1, st->mapromsize, f) != st->mapromsize) {
-               printf("Read error while reading map rom image '%s'\n", p);
-               fclose(f);
-               return;
-       }
-       fclose(f);
-       printf("ROM '%s' (%luk) loaded .\n", rompath, st->mapromsize >> 10);
-}
-
-static void load_memory(FILE *f, WORD index, struct uaestate *st)
-{
-       struct MemoryBank *mb = &st->membanks[index];
-       ULONG oldoffset = ftell(f);
-       ULONG chunksize = mb->size + 12;
-       fseek(f, mb->offset, SEEK_SET);
-       if (st->debug)
-               printf("Memory '%s', size %luk, offset %lu. Target %08lx.\n", mb->chunk, chunksize >> 10, mb->offset, mb->targetaddr);
-       // if Chip RAM and free space in another statefile block? Put it there because chip ram is decompressed first.
-       if (index == MB_CHIP) {
-               mb->addr = tempmem_allocate_reserved(chunksize, MB_SLOW, st);
-               if (!mb->addr)
-                       mb->addr = tempmem_allocate_reserved(chunksize, MB_FAST, st);
-       } else if (index == MB_SLOW) {
-               mb->addr = tempmem_allocate_reserved(chunksize, MB_FAST, st);
-       }
-       if (!mb->addr)
-               mb->addr = tempmem_allocate(chunksize, st);
-       if (mb->addr) {
-               if (st->debug)
-                       printf(" - Address %08lx - %08lx.\n", mb->addr, mb->addr + chunksize - 1);
-               if (fread(mb->addr, 1, chunksize, f) != chunksize) {
-                       printf("ERROR: Read error (Chunk '%s', %lu bytes)\n", mb->chunk, chunksize);
-                       st->errors++;
-               }               
-       } else {
-               printf("ERROR: Out of memory (Chunk '%s', %lu bytes).\n", mb->chunk, chunksize);
-               st->errors++;
-       }
-       fseek(f, oldoffset, SEEK_SET);
-}
-
-static int read_chunk_head(FILE *f, UBYTE *cnamep, ULONG *sizep, ULONG *flagsp)
-{
-       ULONG size = 0, flags = 0;
-       UBYTE cname[5];
-
-       *flagsp = 0;
-       *sizep = 0;
-       cnamep[0] = 0;
-       if (fread(cname, 1, 4, f) != 4) {
-               return 0;
-       }
-       cname[4] = 0;
-       strcpy(cnamep, cname);
-
-       if (fread(&size, 1, 4, f) != 4) {
-               cnamep[0] = 0;
-               return 0;
-       }
-
-       if (fread(&flags, 1, 4, f) == 0) {
-               return 1;
-       }
-
-       if (size < 8)
-               return 1;
-
-       if (size < 12) {
-               size = 0;
-               flags = 0;
-       } else {
-               size -= 12;
-       }
-       *sizep = size;
-       *flagsp = flags;
-       return 1;
-}
-
-static UBYTE *load_chunk(FILE *f, UBYTE *cname, ULONG size, struct uaestate *st)
-{
-       UBYTE *b = NULL;
-       int acate = 0;
-       
-       //printf("Allocating %lu bytes for '%s'.\n", size, cname);
-
-       b = tempmem_allocate(size, st);
-       
-       //printf("Reading chunk '%s', %lu bytes to address %08x\.n", cname, size, b);
-       
-       if (!b) {
-               printf("ERROR: Not enough memory (Chunk '%s', %ul bytes required).\n", cname, size);
-               return NULL;
-       }
-       
-       if (fread(b, 1, size, f) != size) {
-               printf("ERROR: Read error  (Chunk '%s', %lu bytes).\n", cname, size);
-               return NULL;
-       }
-       
-       fseek(f, 4 - (size & 3), SEEK_CUR);
-               
-       return b;
-}
-
-static UBYTE *read_chunk(FILE *f, UBYTE *cname, ULONG *sizep, ULONG *flagsp, struct uaestate *st)
-{
-       ULONG size, orgsize, flags;
-
-       if (!read_chunk_head(f, cname, &size, &flags))
-               return NULL;
-       orgsize = size;
-       *flagsp = flags;
-
-       if (size == 0)
-               return NULL;
-
-       ULONG maxsize = 0x7fffffff;
-
-       for (int i = 0; unsupportedchunknames[i]; i++) {
-               if (!strcmp(cname, unsupportedchunknames[i])) {
-                       printf("ERROR: Unsupported chunk '%s', %lu bytes, flags %08x.\n", cname, size, flags);
-                       st->errors++;
-                       return NULL;
-               }
-       }
-
-       int found = 0;
-       for (int i = 0; chunknames[i]; i++) {
-               if (!strcmp(cname, chunknames[i])) {
-                       found = 1;
-                       if (st->debug)
-                               printf("Reading chunk '%s', %lu bytes, flags %08x.\n", cname, size, flags);
-                       break;
-               }
-       }
-       if (!found) {
-               // read only header if memory chunk
-               for (int i = 0; memchunknames[i]; i++) {
-                       if (!strcmp(cname, memchunknames[i])) {
-                               found = 1;
-                               maxsize = 16;
-                               if (st->debug)
-                                       printf("Checking memory chunk '%s', %lu bytes, flags %08x.\n", cname, size, flags);
-                               break;
-                       }       
-               }
-       }
-       
-       if (!found) {
-               //printf("Skipped chunk '%s', %ld bytes, flags %08x\n", cname, size, flags);
-               fseek(f, size, SEEK_CUR);
-               if (size)
-                       fseek(f, 4 - (size & 3), SEEK_CUR);
-               return NULL;
-       }
-
-       *sizep = size;
-       if (size > maxsize)
-               size = maxsize; 
-       UBYTE *chunk = malloc(size);
-       if (!chunk) {
-               printf("ERROR: Not enough memory (Chunk '%s', %lu bytes).\n", cname, size);
-               return NULL;
-       }
-       if (fread(chunk, 1, size, f) != size) {
-               printf("ERROR: Read error (Chunk '%s', %lu bytes)..\n", cname, size);
-               free(chunk);
-               return NULL;
-       }
-       if (orgsize > size) {
-               fseek(f, orgsize - size, SEEK_CUR);
-       }
-       fseek(f, 4 - (orgsize & 3), SEEK_CUR);
-       return chunk;   
-}
-
-static void find_extra_ram(struct uaestate *st)
-{
-       Forbid();
-       struct MemHeader *mh = (struct MemHeader*)SysBase->MemList.lh_Head;
-       while (mh->mh_Node.ln_Succ) {
-               ULONG mstart = ((ULONG)mh->mh_Lower) & 0xffff0000;
-               ULONG msize = ((((ULONG)mh->mh_Upper) + 0xffff) & 0xffff0000) - mstart;
-               int i;
-               for (i = 0; i < MEMORY_REGIONS; i++) {
-                       if (st->mem_allocated[i] == mh)
-                               break;
-               }
-               if (i == MEMORY_REGIONS && (mstart != st->mrd[0].memunavailable && mstart != st->mrd[1].memunavailable)) {
-                       if (msize > st->extra_ram_size) {
-                               st->extra_ram = (UBYTE*)mstart;
-                               st->extra_ram_size = msize;
-                               st->extra_mem_head = mh;
-                       }       
-               }
-               mh = (struct MemHeader*)mh->mh_Node.ln_Succ;
-       }
-       Permit();
-}
-
-static ULONG check_ram(UBYTE *ramname, UBYTE *cname, UBYTE *chunk, WORD index, ULONG addr, ULONG offset, ULONG chunksize, ULONG flags, struct uaestate *st)
-{
-       ULONG size;
-       if (flags & 1) // compressed
-               size = getlong(chunk, 0);
-       else
-               size = chunksize;
-       if (st->debug)
-               printf("Statefile RAM: Address %08x, size %luk.\n", addr, size >> 10);
-       int found = 0;
-       ULONG mstart, msize;
-       Forbid();
-       struct MemHeader *mh = (struct MemHeader*)SysBase->MemList.lh_Head;
-       while (mh->mh_Node.ln_Succ) {
-               mstart = ((ULONG)mh->mh_Lower) & 0xffff0000;
-               msize = ((((ULONG)mh->mh_Upper) + 0xffff) & 0xffff0000) - mstart;
-               if (mstart == addr) {
-                       if (msize >= size)
-                               found = 1;
-                       else
-                               found = -1;
-                       break;
-               }
-               mh = (struct MemHeader*)mh->mh_Node.ln_Succ;
-       }
-       Permit();
-       if (!found) {
-               // use MMU to create this address space if available
-               if (mmu_remap(addr, size, FALSE, st)) {
-                       msize = size;
-                       mstart = addr;
-                       mh = NULL;
-                       found = 1;
-               } else {
-                       printf("ERROR: Required RAM address space %08x-%08x unavailable.\n", addr, addr + size - 1);
-                       st->errors++;
-                       return 0;
-               }
-       }
-       st->mem_allocated[index] = mh;
-       struct MemoryBank *mb = &st->membanks[index];
-       mb->size = chunksize;
-       mb->offset = offset;
-       mb->targetaddr = (UBYTE*)addr;
-       mb->targetsize = msize;
-       mb->flags = flags;
-       strcpy(mb->chunk, cname);
-       if (st->debug)
-               printf("- Detected memory at %08x, total size %luk. Offset %ld.\n", mstart, msize >> 10, offset);
-       if (found > 0) {
-               if (st->debug)
-                       printf("- Memory is usable (%luk required, %luk unused).\n", size >> 10, (msize - size) >> 10);
-               ULONG extrasize = msize - size;
-               if (extrasize >= 524288) {
-                       if ((mstart >= 0x00200000 && st->extra_ram < (UBYTE*)0x00200000) || extrasize > st->extra_ram_size) {
-                               st->extra_ram = (UBYTE*)(mstart + size);
-                               st->extra_ram_size = extrasize;
-                       }
-               }
-               return 1;
-       }
-       // if too small RAM area and not chip ram: mmu remap the missing part.
-       if (st->canusemmu) {
-               ULONG mmu_start = mstart + msize;
-               ULONG mmu_size = size - msize;
-               if (mmu_remap(mmu_start, mmu_size, FALSE, st)) {
-                       printf("- MMU remapped missing address space %08x-%08x\n", mmu_start, mmu_start + mmu_size - 1);
-                       if (mstart == 0) {
-                               printf("- WARNING: Part of Chip RAM remapped, custom chipset can't access it!!\n");
-                       }
-                       return 1;
-               }
-       }
-       printf("ERROR: Not enough %s RAM available. %luk required.\n", ramname, size >> 10);
-       st->errors++;
-       return 0;
-}
-
-static void floppy_info(int num, UBYTE *p)
-{
-       UBYTE state = p[4];
-       UBYTE track = p[5];
-       if (state & 2) // disabled
-               return;
-       UBYTE *path = &p[4 + 1 + 1 + 1 + 1 + 4 + 4];
-       printf("DF%d: Track %d ", num, track);
-       if (path[0])
-               printf("'%s'.\n", path);
-       else
-               printf("<empty>\n");
-}
-
-static void check_rom(UBYTE *p, struct uaestate *st)
-{
-       UWORD ver = getword(p, 4 + 4 + 4);
-       UWORD rev = getword(p, 4 + 4 + 4 + 2);
-       
-       UWORD *rom = (UWORD*)0xf80000;
-       UWORD rver = rom[12 / 2];
-       UWORD rrev = rom[14 / 2];
-       
-       ULONG start = getlong(p, 0);
-       ULONG len = getlong(p, 4);
-       if (start == 0xf80000 && len == 262144)
-               start = 0xfc0000;
-       ULONG crc32 = getlong(p, 4 + 4 + 4 + 4);
-       
-       UBYTE *path = &p[4 + 4 + 4 + 4 + 4];
-       while (*path++);
-       
-       int mismatch = ver != rver || rev != rrev;
-       if (mismatch)
-               printf("- WARNING: ROM version mismatch: %d.%d. System ROM: %d.%d\n", ver, rev, rver, rrev);
-       if (st->debug)
-               printf("ROM %08lx-%08lx %d.%d (CRC=%08x).\n", start, start + len - 1, ver, rev, crc32);
-       if (mismatch) {
-               if (st->debug)
-                       printf("- '%s'\n", path);
-               st->romver = ver;
-               st->romrev = rev;
-               WORD mr = has_maprom(st);
-               if (mr == 0) {
-                       if (st->debug)
-                               printf("Map ROM support not detected\n");
-               } else if (mr > 0) {
-                       printf("- Map ROM hardware detected.\n");
-               }
-       }
-}
-
-static int parse_pass_2(FILE *f, struct uaestate *st)
-{
-       for (int i = 0; i < MEMORY_REGIONS; i++) {
-               struct MemoryBank *mb = &st->membanks[i];
-               if (mb->size) {
-                       load_memory(f, i, st);
-               }
-       }
-       if (st->romver) {
-               load_rom(st);
-       }
-       
-       for (;;) {
-               ULONG size, flags;
-               UBYTE cname [5];
-               
-               if (!read_chunk_head(f, cname, &size, &flags)) {
-                       return -1;
-               }
-               
-               if (!strcmp(cname, "END "))
-                       break;
-
-               if (!strcmp(cname, "CPU ")) {
-                       st->cpu_chunk = load_chunk(f, cname, size, st);
-               } else if (!strcmp(cname, "CHIP")) {
-                       st->custom_chunk = load_chunk(f, cname, size, st);
-               } else if (!strcmp(cname, "AGAC")) {
-                       st->aga_colors_chunk = load_chunk(f, cname, size, st);
-               } else if (!strcmp(cname, "CIAA")) {
-                       st->ciaa_chunk = load_chunk(f, cname, size, st);
-               } else if (!strcmp(cname, "CIAB")) {
-                       st->ciab_chunk = load_chunk(f, cname, size, st);
-               } else if (!strcmp(cname, "DSK0")) {
-                       st->floppy_chunk[0] = load_chunk(f, cname, size, st);
-                       floppy_info(0, st->floppy_chunk[0]);
-               } else if (!strcmp(cname, "DSK1")) {
-                       st->floppy_chunk[1] = load_chunk(f, cname, size, st);
-                       floppy_info(1, st->floppy_chunk[1]);
-               } else if (!strcmp(cname, "DSK2")) {
-                       st->floppy_chunk[2] = load_chunk(f, cname, size, st);
-                       floppy_info(2, st->floppy_chunk[2]);
-               } else if (!strcmp(cname, "DSK3")) {
-                       st->floppy_chunk[3] = load_chunk(f, cname, size, st);
-                       floppy_info(3, st->floppy_chunk[3]);
-               } else if (!strcmp(cname, "AUD0")) {
-                       st->audio_chunk[0] = load_chunk(f, cname, size, st);
-               } else if (!strcmp(cname, "AUD1")) {
-                       st->audio_chunk[1] = load_chunk(f, cname, size, st);
-               } else if (!strcmp(cname, "AUD2")) {
-                       st->audio_chunk[2] = load_chunk(f, cname, size, st);
-               } else if (!strcmp(cname, "AUD3")) {
-                       st->audio_chunk[3] = load_chunk(f, cname, size, st);
-               } else {
-                       fseek(f, size, SEEK_CUR);
-                       fseek(f, 4 - (size & 3), SEEK_CUR);
-               }
-       }
-
-       return st->errors;
-}
-
-static int parse_pass_1(FILE *f, struct uaestate *st)
-{
-       int first = 1;
-       UBYTE *b = NULL;
-
-       for (;;) {
-               ULONG offset = ftell(f);
-               ULONG size, flags;
-               UBYTE cname[5];
-               b = read_chunk(f, cname, &size, &flags, st);
-               if (!strcmp(cname, "END "))
-                       break;
-               if (!b) {
-                       if (!cname[0])
-                               return -1;
-                       continue;
-               }
-
-               if (first) {
-                       if (strcmp(cname, "ASF ")) {
-                               printf("ERROR: Not UAE statefile.\n");
-                               return -1;
-                       }
-                       first = 0;
-                       continue;
-               }
-
-               if (!strcmp(cname, "CPU ")) {
-                       ULONG smodel = 68000;
-                       for (int i = 0; i < 4; i++) {
-                               if (SysBase->AttnFlags & (1 << i))
-                                       smodel += 10;
-                       }
-                       if (SysBase->AttnFlags & 0x80)
-                               smodel = 68060;
-                       ULONG model = getlong(b, 0);
-                       printf("CPU: %lu.\n", model);
-                       if (smodel != model) {
-                               printf("- WARNING: %lu CPU statefile but system has %lu CPU.\n", model, smodel);
-                       }
-                       if (model > 68030) {
-                               printf("- ERROR: Only 68000/68010/68020/68030 statefiles are supported.\n");
-                               st->errors++;
-                       }
-               } else if (!strcmp(cname, "CHIP")) {
-                       UWORD vposr = getword(b, 4 + 4); // VPOSR
-                       volatile struct Custom *c = (volatile struct Custom*)0xdff000;
-                       UWORD svposr = c->vposr;
-                       int aga = (vposr & 0x0f00) == 0x0300;
-                       int ecs = (vposr & 0x2000) == 0x2000;
-                       int ntsc = (vposr & 0x1000) == 0x1000;
-                       int saga = (svposr & 0x0f00) == 0x0300;
-                       int secs = (svposr & 0x2000) == 0x2000;
-                       int sntsc = (svposr & 0x1000) == 0x1000;
-                       printf("Chipset: %s %s (0x%04X).\n", aga ? "AGA" : (ecs ? "ECS" : "OCS"), ntsc ? "NTSC" : "PAL", vposr);
-                       if (aga && !saga) {
-                               printf("- WARNING: AGA statefile but system is OCS/ECS.\n");
-                       }
-                       if (saga && !aga) {
-                               printf("- WARNING: OCS/ECS statefile but system is AGA.\n");
-                       }
-                       if (!sntsc && !secs && ntsc) {
-                               printf("- WARNING: NTSC statefile but system is OCS PAL.\n");
-                       }
-                       if (sntsc && !secs && !ntsc) {
-                               printf("- WARNING: PAL statefile but system is OCS NTSC.\n");
-                       }
-                       st->agastate = aga;
-               } else if (!strcmp(cname, "CRAM")) {
-                       check_ram("Chip", cname, b, MB_CHIP, 0x000000, offset, size, flags, st);
-               } else if (!strcmp(cname, "BRAM")) {
-                       check_ram("Slow", cname, b, MB_SLOW, 0xc00000, offset, size, flags, st);
-               } else if (!strcmp(cname, "FRAM")) {
-                       check_ram("Fast", cname, b, MB_FAST, 0x200000, offset, size, flags, st);
-               } else if (!strcmp(cname, "ROM ")) {
-                       check_rom(b, st);
-               }
-
-               free(b);
-               b = NULL;
-       }
-       
-       if (!st->errors) {
-               find_extra_ram(st);
-               if (!st->extra_ram) {
-                       printf("ERROR: At least 512k RAM not used by statefile required.\n");
-                       st->errors++;
-               } else {
-                       if (st->debug)
-                               printf("%luk extra RAM at %08x.\n", st->extra_ram_size >> 10, st->extra_ram);
-                       st->extra_mem_pointer = st->extra_ram;
-                       st->errors = 0;
-               }
-       } else {
-               printf("ERROR: Incompatible hardware configuration.\n");
-               st->errors++;
-       }
-
-       free(b);
-       
-       return st->errors;
-}
-
-extern void runit(void*);
-extern void callinflate(UBYTE*, UBYTE*);
-extern void flushcache(void);
-
-static void handlerambank(struct MemoryBank *mb, struct uaestate *st)
-{
-       UBYTE *sa = mb->addr + 12; /* skip chunk header */
-       if (mb->flags & 1) {
-               // skip decompressed size and zlib header
-               callinflate(mb->targetaddr, sa + 4 + 2);
-       } else {
-               ULONG *s = (ULONG*)sa;
-               ULONG *d = (ULONG*)mb->targetaddr;
-               for (int i = 0; i < mb->size / 4; i++) {
-                       *d++ = *s++;
-               }               
-       }
-}
-
-// Interrupts are off, supervisor state
-static void processstate(struct uaestate *st)
-{
-       volatile struct Custom *c = (volatile struct Custom*)0xdff000;
-
-       reset_floppy(st);
-
-       if (st->maprom && (st->mrd[0].type || st->mrd[1].type)) {
-               c->color[0] = 0x404;
-               set_maprom(st);
-       }
-       
-       for (int i = 0; i < MEMORY_REGIONS; i++) {
-               if (i == MB_CHIP)
-                       c->color[0] = 0x400;
-               if (i == MB_SLOW)
-                       c->color[0] = 0x040;
-               if (i == MB_FAST)
-                       c->color[0] = 0x004;
-               struct MemoryBank *mb = &st->membanks[i];
-               if (mb->addr) {
-                       handlerambank(mb, st);
-               }
-       }
-       
-       c->color[0] = 0x440;
-               
-       // must be before set_cia
-       for (int i = 0; i < 4; i++) {
-               set_floppy(st->floppy_chunk[i], i);
-       }
-
-       c->color[0] = 0x444;
-
-       set_agacolor(st->aga_colors_chunk);
-       set_custom(st);
-       for (int i = 0; i < 4; i++) {
-               set_audio(st->audio_chunk[i], i);
-       }
-       for (int i = 0; i < 8; i++) {
-               set_sprite(st->sprite_chunk[i], i);
-       }
-       set_cia(st->ciaa_chunk, 0);
-       set_cia(st->ciab_chunk, 1);
-
-       runit(st);
-}
-
-static void take_over(struct uaestate *st)
-{
-       // Copy stack, variables and code to safe location
-
-       UBYTE *tempsp = tempmem_allocate(TEMP_STACK_SIZE, st);
-       if (!tempsp) {
-               printf("Out of memory for temp stack (%lu bytes).\n", TEMP_STACK_SIZE);
-               return;
-       }
-
-       struct uaestate *tempst = (struct uaestate*)tempmem_allocate(sizeof(struct uaestate), st);
-       if (!tempst) {
-               printf("Out of memory for temp state variables (%lu bytes).\n", sizeof(struct uaestate));
-               return; 
-       }
-       memcpy(tempst, st, sizeof(struct uaestate));
-
-       struct Process *me = (struct Process*)FindTask(0);
-       struct CommandLineInterface *cli = (struct CommandLineInterface*)((((ULONG)me->pr_CLI) << 2));
-       if (!cli) {
-               printf("CLI == NULL?\n");
-               return;
-       }
-       ULONG *module = (ULONG*)(cli->cli_Module << 2);
-       ULONG hunksize = module[-1] << 2;
-       UBYTE *newcode = tempmem_allocate(hunksize, st);
-       if (!newcode) {
-               printf("Out of memory for temp code (%lu bytes).\n", hunksize);
-               return;
-       }
-       memcpy(newcode, module, hunksize);
-       
-       // ugly relocation hack but jumps to other module (from asm.S) are always absolute..
-       // TODO: process the executable after linking
-       UWORD *cp = (UWORD*)newcode;
-       for (int i = 0; i < hunksize / 2; i++) {
-               // JSR/JMP xxxxxxxx.L?
-               if (*cp == 0x4eb9 || *cp == 0x4ef9) {
-                       ULONG *ap = (ULONG*)(cp + 1);
-                       ULONG *app = (ULONG*)(*ap);
-                       void *addr = (void*)app;
-                       if (addr == runit || addr == callinflate) {
-                               *ap = (ULONG)addr - (ULONG)module + (ULONG)newcode;
-                               //printf("Relocated %08x: %08x -> %08x\n", cp, addr, *ap);
-                       }
-               }
-               cp++;
-       }
-       
-       if (st->testmode) {
-               printf("Test mode finished. Exiting.\n");
-               return;
-       }
-       
-       if (!st->nowait) {
-               if (st->debug) {
-                       printf("Code=%08lx Stack=%08lx Data=%08lx. Press RETURN!\n", newcode, tempsp, tempst);
-               } else {
-                       printf("Change floppy disk(s) now if needed. Press RETURN to start.\n");
-               }
-               UBYTE b;
-               fread(&b, 1, 1, stdin);
-               Delay(100); // So that key release gets processed by AmigaOS
-       }
-       
-       if (SysBase->LibNode.lib_Version >= 37) {
-               flushcache();
-       }
-
-       if (GfxBase->LibNode.lib_Version >= 37) {
-               LoadView(NULL);
-               WaitTOF();
-               WaitTOF();      
-       }
-       
-       OwnBlitter();
-       WaitBlit();
-       
-       // No turning back!
-       extern void *killsystem(UBYTE*, struct uaestate*, ULONG);
-       killsystem(tempsp + TEMP_STACK_SIZE, tempst, (ULONG)processstate - (ULONG)module + (ULONG)newcode);
-}
-
-int main(int argc, char *argv[])
-{
-       FILE *f;
-       UBYTE *b;
-       ULONG size;
-       UBYTE cname[5];
-       struct uaestate *st;
-       
-       printf("ussload v" VER " (" REVDATE " " REVTIME ")\n");
-       if (argc < 2) {
-               printf("Syntax: ussload <statefile.uss> (parameters)\n");
-               printf("- nowait = don't wait for return key.\n");
-               printf("- debug = enable debug output.\n");
-               printf("- test = test mode.\n");
-               printf("- nomaprom = do not use map rom.\n");
-               printf("- nommu = do not use MMU (68030/68040/68060).\n");
-               printf("- nocache = disable caches before starting (68020+)\n");
-               printf("- pal/ntsc = set PAL or NTSC mode (ECS/AGA only)\n");
-               return 0;
-       }
-       
-       f = fopen(argv[1], "rb");
-       if (!f) {
-               printf("Couldn't open '%s'\n", argv[1]);
-               return 0;
-       }
-
-       st = calloc(sizeof(struct uaestate), 1);
-       if (!st) {
-               printf("Out of memory.\n");
-               return 0;
-       }
-       st->usemaprom = 1;
-       st->canusemmu = 1;
-       for(int i = 2; i < argc; i++) {
-               if (!stricmp(argv[i], "debug"))
-                       st->debug = 1;
-               if (!stricmp(argv[i], "test"))
-                       st->testmode = 1;
-               if (!stricmp(argv[i], "nowait"))
-                       st->nowait = 1;
-               if (!stricmp(argv[i], "nomaprom"))
-                       st->usemaprom = 0;
-               if (!stricmp(argv[i], "nommu"))
-                       st->canusemmu = 0;
-               if (!stricmp(argv[i], "nocache"))
-                       st->flags |= FLAGS_NOCACHE;
-               if (!stricmp(argv[i], "pal"))
-                       st->flags |= FLAGS_FORCEPAL;
-               if (!stricmp(argv[i], "ntsc"))
-                       st->flags |= FLAGS_FORCENTSC;
-       }
-
-       if (!(SysBase->AttnFlags & AFF_68030))
-               st->canusemmu = 0;
-
-       if (st->canusemmu) {
-               if (!init_mmu(st)) {
-                       printf("ERROR: MMU page table allocation failed.\n");
-                       st->canusemmu = 0;
-               }
-       }
-
-       if (!parse_pass_1(f, st)) {
-               fseek(f, 0, SEEK_SET);
-               if (!parse_pass_2(f, st)) {
-                       take_over(st);                  
-               } else {
-                       printf("Pass #2 failed.\n");
-               }
-       } else {
-               printf("Pass #1 failed.\n");
-       }
-       
-       free(st);
-       
-       fclose(f);
-
-       free_allocations(st);
-
-       return 0;
-}
diff --git a/utilities/stateload/makefile b/utilities/stateload/makefile
deleted file mode 100644 (file)
index f6a65e7..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-
-NOWDATE := "\"$(shell date "+%-d.%-m.%Y")\""
-NOWTIME := "\"$(shell date "+%T")\""
-
-CC=/opt/amiga/bin/m68k-amigaos-gcc
-AS=/opt/amiga/bin/m68k-amigaos-as
-
-CFLAGS = -mcrt=nix13 -Os -m68000 -fomit-frame-pointer -msmall-code -DREVDATE=$(NOWDATE) -DREVTIME=$(NOWTIME)
-LINK_CFLAGS = -mcrt=nix13 -s
-
-OBJS = main.o asm.o inflate.o mmu.o
-
-all: $(OBJS)
-       $(CC) $(LINK_CFLAGS) -o ussload $^
-
-main.o: main.c
-       $(CC) $(CFLAGS) -I. -c -o $@ main.c
-
-mmu.o: mmu.c
-       $(CC) $(CFLAGS) -I. -c -o $@ mmu.c
-
-asm.o: asm.S
-       $(AS) -m68040  -o $@ asm.S
-
-inflate.o: inflate.S
-       $(CC) $(CFLAGS) -I. -c -o $@ inflate.S
diff --git a/utilities/stateload/mmu.c b/utilities/stateload/mmu.c
deleted file mode 100644 (file)
index 0fa2474..0000000
+++ /dev/null
@@ -1,206 +0,0 @@
-
-/* I made this originally for AROS m68k */
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <exec/types.h>
-#include <exec/memory.h>
-#include <exec/execbase.h>
-#include <proto/exec.h>
-
-#include "header.h"
-
-#define MMU030 1
-#define MMU040 2
-#define MMU060 3
-
-#define CM_WRITETHROUGH 0
-#define CM_COPYBACK 1
-#define CM_SERIALIZED 2
-#define CM_NONCACHEABLE 3
-
-#define LEVELA_SIZE 7
-#define LEVELB_SIZE 7
-#define LEVELC_SIZE 6
-#define PAGE_SIZE 12 // = 1 << 12 = 4096
-
-/* Macros that hopefully make MMU magic a bit easier to understand.. */
-
-#define LEVELA_VAL(x) ((((ULONG)(x)) >> (32 - (LEVELA_SIZE                                                     ))) & ((1 << LEVELA_SIZE) - 1))
-#define LEVELB_VAL(x) ((((ULONG)(x)) >> (32 - (LEVELA_SIZE + LEVELB_SIZE                         ))) & ((1 << LEVELB_SIZE) - 1))
-#define LEVELC_VAL(x) ((((ULONG)(x)) >> (32 - (LEVELA_SIZE + LEVELB_SIZE + LEVELC_SIZE))) & ((1 << LEVELC_SIZE) - 1))
-
-#define LEVELA(root, x) (root[LEVELA_VAL(x)])
-#define LEVELB(a, x) (((ULONG*)(((ULONG)a) & ~((1 << (LEVELB_SIZE + 2)) - 1)))[LEVELB_VAL(x)])
-#define LEVELC(b, x) (((ULONG*)(((ULONG)b) & ~((1 << (LEVELC_SIZE + 2)) - 1)))[LEVELC_VAL(x)])
-
-#define INVALID_DESCRIPTOR 0xDEAD0000
-#define ISINVALID(x) ((((ULONG)x) & 3) == 0)
-
-static BOOL map_region2(struct uaestate *st, void *addr, void *physaddr, ULONG size, BOOL invalid, BOOL writeprotect, BOOL supervisor, UBYTE cachemode);
-
-
-static void map_pagetable(struct uaestate *st, void *addr, ULONG size)
-{
-       /* 68040+ MMU tables should be serialized */
-       map_region2(st, addr, NULL, size, FALSE, FALSE, FALSE, CM_SERIALIZED);
-}
-
-/* Allocate MMU descriptor page, it needs to be (1 << bits) * sizeof(ULONG) aligned */
-static ULONG alloc_descriptor(struct uaestate *st, UBYTE bits, UBYTE level)
-{
-       ULONG *desc, dout;
-       ULONG size = sizeof(ULONG) * (1 << bits);
-       ULONG ps = 1 << PAGE_SIZE;
-       UWORD i;
-
-       while (st->page_free >= size && (((ULONG)st->page_ptr) & (size - 1))) {
-               st->page_ptr += 0x100;
-               st->page_free -= 0x100;
-       }
-       while (st->page_free < size) {
-               /* allocate in aligned blocks of PAGE_SIZE */
-               UBYTE *mem, *newmem, *pagemem;
-
-               // by design fail if no FAST RAM available
-               mem = AllocMem(2 * ps, MEMF_FAST);
-               if (!mem)
-                               return 0;
-               Forbid();
-               FreeMem(mem, 2 * ps);
-               newmem = (UBYTE*)((((ULONG)mem) + ps - 1) & ~(ps - 1));
-               pagemem = allocate_abs(ps, (ULONG)newmem, st);
-               Permit();
-               if (!pagemem)
-                               return 0;
-               st->page_ptr = pagemem;
-               st->page_free = ps;
-               if (level > 0 && st->mmutype >= MMU040)
-                       map_pagetable(st, pagemem, ps);
-       }
-       desc = (ULONG*)st->page_ptr;
-       for (i = 0; i < (1 << bits); i++)
-               desc[i] = INVALID_DESCRIPTOR;
-       dout = (ULONG)desc;
-       if (st->mmutype == MMU030)
-               dout |= 2; /* Valid 4 byte descriptor */
-       else
-               dout |= 3; /* Resident descriptor */
-       st->page_ptr += size;
-       st->page_free -= size;
-       return dout;
-}      
-               
-static BOOL map_region2(struct uaestate *st, void *addr, void *physaddr, ULONG size, BOOL invalid, BOOL writeprotect, BOOL supervisor, UBYTE cachemode)
-{
-       ULONG desca, descb, descc, pagedescriptor;
-       ULONG page_size = 1 << PAGE_SIZE;
-       ULONG page_mask = page_size - 1;
-
-       if ((size & page_mask) || (((ULONG)addr) & page_mask) || (((ULONG)physaddr) & page_mask))
-                       return FALSE;
-       if (physaddr == NULL)
-                       physaddr = addr;
-
-       while (size) {
-               desca = LEVELA(st->MMU_Level_A, addr);
-               if (ISINVALID(desca))
-                               desca = LEVELA(st->MMU_Level_A, addr) = alloc_descriptor(st, LEVELB_SIZE, 1);
-               if (ISINVALID(desca))
-                               return FALSE;
-               descb = LEVELB(desca, addr);
-               if (ISINVALID(descb))
-                               descb = LEVELB(desca, addr) = alloc_descriptor(st, LEVELC_SIZE, 2);
-               if (ISINVALID(descb))
-                               return FALSE;
-               descc = LEVELC(descb, addr);
-
-               if (invalid) {
-                       pagedescriptor = INVALID_DESCRIPTOR;
-    } else {
-                       pagedescriptor = ((ULONG)physaddr) & ~page_mask;
-                       BOOL wasinvalid = ISINVALID(descc);
-                       if (st->mmutype == MMU030) {
-                               pagedescriptor |= 1; // page descriptor
-                               if (writeprotect || (!wasinvalid && (descc & 4)))
-                                       pagedescriptor |= 4; // write-protected
-                               /* 68030 can only enable or disable caching */
-                               if (cachemode >= CM_SERIALIZED || (!wasinvalid && (descc & (1 << 6))))
-                                       pagedescriptor |= 1 << 6;
-                       } else {
-                               pagedescriptor |= 3; // resident page
-                               if (writeprotect || (!wasinvalid && (descc & 4)))
-                                       pagedescriptor |= 4; // write-protected
-                               if (supervisor || (!wasinvalid && (descc & (1 << 7))))
-                                       pagedescriptor |= 1 << 7;
-                               // do not override non-cached
-                               if (wasinvalid || cachemode > ((descc >> 5) & 3))
-                                       pagedescriptor |= cachemode << 5;
-                               else
-                                       pagedescriptor |= ((descc >> 5) & 3) << 5;
-                               if (addr != 0 || size != page_size)
-                                       pagedescriptor |= 1 << 10; // global if not zero page
-                       }
-               }
-
-               LEVELC(descb, addr) = pagedescriptor;
-               size -= page_size;
-               addr += page_size;
-               physaddr += page_size;
-       }
-       return TRUE;
-}
-
-BOOL map_region(struct uaestate *st, void *addr, void *physaddr, ULONG size, BOOL invalid, BOOL writeprotect, BOOL supervisor, UBYTE cachemode)
-{
-       if (addr != physaddr)
-               printf("MMU: Remap %08lx-%08lx -> %08lx (I=%d,WP=%d,S=%d)\n", addr, addr + size - 1, physaddr, invalid, writeprotect, supervisor);
-       if (!map_region2(st, addr, physaddr, size, invalid, writeprotect, supervisor, cachemode)) {
-               printf("MMU: Remap error\n");
-               return FALSE;
-       }
-       return TRUE;
-}
-
-BOOL unmap_region(struct uaestate *st, void *addr, ULONG size)
-{
-       printf("MMU: Unmapped %08lx-%08lx\n", addr, addr + size - 1);
-       return map_region2(st, addr, NULL, size, TRUE, FALSE, FALSE, 0);
-}
-
-BOOL init_mmu(struct uaestate *st)
-{
-       st->MMU_Level_A = (ULONG*)(alloc_descriptor(st, LEVELA_SIZE, 0) & ~3);
-       if (!st->MMU_Level_A)
-               return FALSE;
-               st->mmutype = MMU030;
-       if (SysBase->AttnFlags & AFF_68040)     
-               st->mmutype = MMU040;
-       if (st->mmutype >= MMU040)
-               map_pagetable(st, st->MMU_Level_A, 1 << PAGE_SIZE);
-               
-       // Create default 1:1 mapping
-       
-       // memory
-       Forbid();
-       struct MemHeader *mh = (struct MemHeader*)SysBase->MemList.lh_Head;
-       while (mh->mh_Node.ln_Succ) {
-               ULONG mstart = ((ULONG)mh->mh_Lower) & 0xffff0000;
-               ULONG msize = ((((ULONG)mh->mh_Upper) + 0xffff) & 0xffff0000) - mstart;
-               map_region(st, (void*)mstart, (void*)mstart, msize, FALSE, FALSE, FALSE, CM_WRITETHROUGH);
-               mh = (struct MemHeader*)mh->mh_Node.ln_Succ;
-       }
-       Permit();
-       // io
-       map_region(st, (void*)0xa00000, (void*)0xa00000, 0xc00000 - 0xa00000, FALSE, FALSE, FALSE, CM_NONCACHEABLE);
-       map_region(st, (void*)0xd80000, (void*)0xd80000, 0xe00000 - 0xd80000, FALSE, FALSE, FALSE, CM_NONCACHEABLE);
-       map_region(st, (void*)0xe80000, (void*)0xe80000, 0x080000, FALSE, FALSE, FALSE, CM_NONCACHEABLE);
-       // rom
-       map_region(st, (void*)0xe00000, (void*)0xe00000, 0x080000, FALSE, FALSE, FALSE, 0);
-       map_region(st, (void*)0xf80000, (void*)0xf80000, 0x080000, FALSE, FALSE, FALSE, 0);
-               
-       return TRUE;
-}
diff --git a/utilities/stateload/readme.txt b/utilities/stateload/readme.txt
deleted file mode 100644 (file)
index 50ec56b..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-
-ussload is UAE state save file (*.uss) loader designed for real hardware.
-
-v1.1:
-
-- GVP MapROM support added. GVP A530 and most A2000 and A3000 GVP boards.
-- Blizzard 1230 MKI/II/III/IV, 1240, 1260 MapROM support added.
-- Switch off all floppy drive motors before memory decompression.
-- Fixed crash if 68020 or 68030 statefile was loaded and CPU was
-  68040 or 68060.
-- Fixed uncompressed statefile support.
-- Compatibility improved.
-
-
-Supported state file hardware configurations:
-
-Common OCS/ECS 68000 A500 configurations. Chip RAM, "Slow" RAM and
-Fast RAM supported.
-Basic A1200 68020 configuration. "Slow" RAM and Fast RAM is also
-supported.
-
-Information:
-
-- Compatible with KS 1.2 and newer.
-- CPU should match state file config but 68020 to 68030 most likely works,
-  68000 to 68020 or 68030 depends on program, 68020 to 68000 rarely works.
-- RAM config must match (can be larger than required) and system must
-  have at least 512k more RAM than state file requires.
-- Both compressed and uncompressed state files are supported.
-- HD compatible (state file is completely loaded before system take over)
-- KS ROM does not need to match if loaded program has already completely
-  taken over the system or supported Map ROM hardware is available.
-- All state files should be supported, at least since UAE 0.8.22.
-- State file restore can for example fail if state file was saved when
-  blitter was active or program was executing self-modifying code.
-
-Minimum RAM config examples:
-
-512k Chip RAM state file: hardware must have 1M Chip or 512k Chip+512k
-"Slow" RAM or 512k Chip+512k real Fast.
-512k+512k state file: hardware must have 1M+512k or 512k+1M or
-512k+512k+512k real Fast.
-
-Note that uncompressed state files require at least 1M contiguous extra
-RAM because all state file RAM address spaces need to fit in RAM before
-system take over.
-A1200 chip ram only state files usually require at least 1M Fast ram.
-
-Map ROM hardware support:
-
-Currently ACA500, ACA500plus, ACA1221, ACA1221EC and most ACA123x
-variants Map ROM hardware is supported.
-If state file ROM is not same as hardware ROM, ROM image is automatically
-loaded from DEVS:Kickstarts and enabled if found.
-Check WHDLoad documentation for DEVS:Kickstarts files and naming.
-If A1200 KS 3.0 ROM is missing: manually copy correct ROM to
-DEVS:Kickstarts and name it kick39106.a1200.
-
-Command line parameters:
-
-- nowait = don't wait for return key.
-- debug = show debug information.
-- test = parse and load state file, exit before system take over.
-- nomaprom = do not use Map ROM.
-- nocache = disable caches before starting loaded program (68020+ only)
-- pal = force PAL mode (ECS/AGA only)
-- ntsc = force NTSC mode (ECS/AGA only)
-
-Background colors:
-
-- purple = Map ROM copy.
-- red = decompressing/copying Chip Ram state.
-- green = decompressing/copying "Slow" RAM (0x00c00000) state.
-- blue = decompressing/copying Fast RAM (0x00200000) state.
-- yellow = configuring floppy drives (seek rw head, motor state).
-
-Source: https://github.com/tonioni/WinUAE/tree/master/utilities/stateload