]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Summer 2016 big update part 1.
authorToni Wilen <twilen@winuae.net>
Thu, 4 Aug 2016 20:01:28 +0000 (23:01 +0300)
committerToni Wilen <twilen@winuae.net>
Thu, 4 Aug 2016 20:01:28 +0000 (23:01 +0300)
116 files changed:
a2065.cpp
a2091.cpp
akiko.cpp
audio.cpp
autoconf.cpp
blkdev.cpp
blkdev_cdimage.cpp
cd32_fmv.cpp
cdtv.cpp
cdtvcr.cpp
cfgfile.cpp
cia.cpp
consolehook.cpp
cpuboard.cpp
custom.cpp
debug.cpp
devices.cpp
dosbox/db_memory.cpp
drawing.cpp
expansion.cpp
filesys.asm
filesys.cpp
filesys_bootrom.cpp
filesys_helpers.asm [new file with mode: 0644]
gayle.cpp
gfxboard.cpp
hardfile.cpp
idecontrollers.cpp
identify.cpp
include/a2065.h
include/a2091.h
include/audio.h
include/autoconf.h
include/blkdev.h
include/cd32_fmv.h
include/cdtv.h
include/cdtvcr.h
include/cia.h
include/cpuboard.h
include/drawing.h
include/filesys.h
include/fsdb.h
include/gayle.h
include/gfxboard.h
include/gui.h
include/idecontrollers.h
include/inputdevice.h
include/keyboard.h
include/memory.h
include/ncr9x_scsi.h
include/ncr_scsi.h
include/newcpu.h
include/options.h
include/pci.h
include/rommgr.h
include/savestate.h
include/scsi.h
include/sndboard.h
include/specialmonitors.h
include/uae.h
include/x86.h
inputdevice.cpp
inputevents.def
main.cpp
mame/a2410.cpp
memory.cpp
moduleripper.cpp
ncr9x_scsi.cpp
ncr_scsi.cpp
newcpu.cpp
od-win32/ahidsound_dsonly.cpp
od-win32/avioutput.cpp
od-win32/blkdev_win32_ioctl.cpp
od-win32/clipboard_win32.cpp
od-win32/cloanto/RetroPlatformGuestIPC.cpp
od-win32/cloanto/RetroPlatformGuestIPC.h
od-win32/cloanto/RetroPlatformIPC.h
od-win32/cloanto/RetroPlatformIPC_doc_draft.txt
od-win32/dinput.cpp
od-win32/direct3d.cpp
od-win32/fsdb_mywin32.cpp
od-win32/hardfile_win32.cpp
od-win32/keyboard_win32.cpp
od-win32/mman.cpp
od-win32/picasso96_win.cpp
od-win32/picasso96_win.h
od-win32/resources/resource.h
od-win32/resources/winuae.rc
od-win32/rp.cpp
od-win32/rp.h
od-win32/sounddep/sound.cpp
od-win32/sounddep/sound.h
od-win32/statusline_win32.cpp
od-win32/win32.cpp
od-win32/win32.h
od-win32/win32gfx.cpp
od-win32/win32gui.cpp
od-win32/winuae_msvc14/winuae_msvc.vcxproj
od-win32/winuae_msvc15/winuae_msvc.vcxproj
od-win32/writelog.cpp
pci.cpp
qemuvga/es1370.cpp
qemuvga/qemuaudio.h
qemuvga/qemumemory.h
qemuvga/qemuuaeglue.h
rommgr.cpp
savestate.cpp
scsi.cpp
sndboard.cpp
specialmonitors.cpp
statusline.cpp
tabletlibrary.cpp
uaelib.cpp
vm.cpp
x86.cpp
zfile.cpp

index b35f207548fe8ee6690010ec23c522e86c876d81..0ff4f94199667a6a0c92245c1eede6df28d16f65 100644 (file)
--- a/a2065.cpp
+++ b/a2065.cpp
@@ -38,8 +38,8 @@ int a2065_promiscuous = 0;
 #define RAM_SIZE 0x8000
 #define RAM_MASK 0x7fff
 
-static uae_u8 config[256];
-static uae_u8 boardram[RAM_SIZE];
+static uae_u8 config[128];
+static uae_u8 *boardram;
 static volatile uae_u16 csr[4];
 static int rap;
 static int configured;
@@ -141,20 +141,6 @@ static void ew (int addr, uae_u32 value)
        }
 }
 
-void a2065_reset (void)
-{
-       am_initialized = 0;
-       csr[0] = CSR0_STOP;
-       csr[1] = csr[2] = csr[3] = 0;
-       dbyteswap = 0;
-       rap = 0;
-
-       ethernet_close (td, sysdata);
-       xfree (sysdata);
-       sysdata = NULL;
-       td = NULL;
-}
-
 #if DUMPPACKET
 static void dumppacket (const TCHAR *n, uae_u8 *packet, int len)
 {
@@ -790,7 +776,7 @@ static uae_u32 REGPARAM2 a2065_bget (uaecptr addr)
 {
        uae_u32 v;
        addr &= 65535;
-       if (addr < 0x40) {
+       if (addr < sizeof config) {
                v = config[addr];
        } else {
                if (!configured)
@@ -843,7 +829,7 @@ int REGPARAM2 a2065_check(uaecptr a, uae_u32 b)
 static addrbank a2065_bank = {
        a2065_lget, a2065_wget, a2065_bget,
        a2065_lput, a2065_wput, a2065_bput,
-       a2065_xlate, a2065_check, NULL, NULL, _T("A2065 Z2 Ethernet"),
+       a2065_xlate, a2065_check, NULL, _T("*"), _T("A2065 Z2 Ethernet"),
        a2065_lgeti, a2065_wgeti,
        ABFLAG_IO, S_READ, S_WRITE
 };
@@ -884,7 +870,7 @@ static uae_u32 REGPARAM2 a2065_lgeti (uaecptr addr)
        return v;
 }
 
-static addrbank *a2065_config (void)
+static bool a2065_config (struct autoconfig_info *aci)
 {
        memset (config, 0xff, sizeof config);
        ew (0x00, 0xc0 | 0x01);
@@ -902,8 +888,9 @@ static addrbank *a2065_config (void)
                        realmac[1] = 0x80;
                        realmac[2] = 0x10;
                }
-               write_log (_T("A2065: '%s' %02X:%02X:%02X:%02X:%02X:%02X\n"),
-                       td->name, td->mac[0], td->mac[1], td->mac[2], td->mac[3], td->mac[4], td->mac[5]);
+               if (aci->doinit)
+                       write_log (_T("A2065: '%s' %02X:%02X:%02X:%02X:%02X:%02X\n"),
+                               td->name, td->mac[0], td->mac[1], td->mac[2], td->mac[3], td->mac[4], td->mac[5]);
        } else {
                realmac[0] = 0x00;
                realmac[1] = 0x80;
@@ -911,8 +898,9 @@ static addrbank *a2065_config (void)
                realmac[3] = 4;
                realmac[4] = 3;
                realmac[5] = 2;
-               write_log (_T("A2065: Disconnected mode %02X:%02X:%02X:%02X:%02X:%02X\n"),
-                       realmac[0], realmac[1], realmac[2], realmac[3], realmac[4], realmac[5]);
+               if (aci->doinit)
+                       write_log (_T("A2065: Disconnected mode %02X:%02X:%02X:%02X:%02X:%02X\n"),
+                               realmac[0], realmac[1], realmac[2], realmac[3], realmac[4], realmac[5]);
        }
 
        ew (0x18, realmac[2]);
@@ -927,14 +915,15 @@ static addrbank *a2065_config (void)
        fakemac[4] = realmac[4];
        fakemac[5] = realmac[5];
 
-       if (configured) {
-               if (configured != 0xff)
-                       map_banks_z2 (&a2065_bank, configured, 0x10000 >> 16);
-       } else {
-               /* KS autoconfig handles the rest */
-               return &a2065_bank;
-       }
-       return NULL;
+       aci->addrbank = &a2065_bank;
+       aci->label = _T("A2065");
+       memcpy(aci->autoconfig_raw, config, sizeof config);
+       if (!aci->doinit)
+               return true;
+
+       alloc_expansion_bank(&a2065_bank, aci);
+       boardram = a2065_bank.baseaddr + RAM_OFFSET;
+       return true;
 }
 
 uae_u8 *save_a2065 (int *len, uae_u8 *dstptr)
@@ -966,13 +955,29 @@ uae_u8 *restore_a2065 (uae_u8 *src)
 void restore_a2065_finish (void)
 {
        if (configured)
-               a2065_config ();
+               a2065_config(NULL);
 }
 
-addrbank *a2065_init (int devnum)
+bool a2065_init (struct autoconfig_info *aci)
 {
        configured = 0;
-       return a2065_config ();
+       return a2065_config(aci);
+}
+
+void a2065_reset(void)
+{
+       am_initialized = 0;
+       csr[0] = CSR0_STOP;
+       csr[1] = csr[2] = csr[3] = 0;
+       dbyteswap = 0;
+       rap = 0;
+
+       free_expansion_bank(&a2065_bank);
+       boardram = NULL;
+       ethernet_close(td, sysdata);
+       xfree(sysdata);
+       sysdata = NULL;
+       td = NULL;
 }
 
 #endif /* A2065 */
index 45d7abdeb132ac8ed9c81586515fb5990a02fe6c..f7f61272e9a1fd9c449a895b9c98d5dca1e3335a 100644 (file)
--- a/a2091.cpp
+++ b/a2091.cpp
@@ -284,7 +284,10 @@ static void freencrunit(struct wd_state *wd)
                }
        }
        scsi_freenative(wd->scsis, MAX_SCSI_UNITS);
-       xfree (wd->rom);
+       if (wd->bank.baseaddr == wd->rom)
+               free_expansion_bank(&wd->bank);
+       else
+               xfree (wd->rom);
        wd->rom = NULL;
        if (wd->self_ptr)
                *wd->self_ptr = NULL;
@@ -1460,7 +1463,7 @@ void wdscsi_put (struct wd_chip_state *wd, struct wd_state *wds, uae_u8 d)
        }
        if (!wd->wd_used) {
                wd->wd_used = 1;
-               write_log (_T("%s %s in use\n"), wds->bank ? wds->bank->name : _T("built-in"), WD33C93);
+               write_log (_T("%s %s in use\n"), wds->bank.name, WD33C93);
        }
        if (wd->sasr == WD_COMMAND_PHASE) {
 #if WD33C93_DEBUG > 1
@@ -2315,7 +2318,7 @@ static void REGPARAM2 dmac_a2091_wput(struct wd_state *wd, uaecptr addr, uae_u32
        dmac_a2091_write_word(wd, addr, w);
 }
 
-extern addrbank dmaca2091_bank;
+extern const addrbank dmaca2091_bank;
 
 static void REGPARAM2 dmac_a2091_bput(struct wd_state *wd, uaecptr addr, uae_u32 b)
 {
@@ -2323,15 +2326,15 @@ static void REGPARAM2 dmac_a2091_bput(struct wd_state *wd, uaecptr addr, uae_u32
        addr &= 65535;
        if (wd->autoconfig) {
                if (addr == 0x48 && !wd->configured) {
-                       map_banks_z2 (wd->bank, b, 0x10000 >> 16);
+                       map_banks_z2 (&wd->bank, b, 0x10000 >> 16);
                        wd->baseaddress = b << 16;
                        wd->configured = 1;
-                       expamem_next (wd->bank, NULL);
+                       expamem_next (&wd->bank, NULL);
                        return;
                }
                if (addr == 0x4c && !wd->configured) {
                        wd->configured = 1;
-                       expamem_shutup(wd->bank);
+                       expamem_shutup(&wd->bank);
                        return;
                }
                if (!wd->configured)
@@ -2441,10 +2444,10 @@ static void REGPARAM2 dmac_a2091_lput (uaecptr addr, uae_u32 b)
                dmac_a2091_lput(wd, addr, b);
 }
 
-addrbank dmaca2091_bank = {
+static const addrbank dmaca2091_bank = {
        dmac_a2091_lget, dmac_a2091_wget, dmac_a2091_bget,
        dmac_a2091_lput, dmac_a2091_wput, dmac_a2091_bput,
-       dmac_a2091_xlate, dmac_a2091_check, NULL, NULL, _T("A2090/A2091/A590"),
+       dmac_a2091_xlate, dmac_a2091_check, NULL, _T("*"), _T("A2090/A2091/A590"),
        dmac_a2091_lgeti, dmac_a2091_wgeti,
        ABFLAG_IO | ABFLAG_SAFE, S_READ, S_WRITE
 };
@@ -2452,7 +2455,7 @@ addrbank dmaca2091_bank = {
 
 /* GVP Series I and II */
 
-extern addrbank gvp_bank;
+extern const addrbank gvp_bank;
 
 static uae_u32 dmac_gvp_read_byte(struct wd_state *wd, uaecptr addr)
 {
@@ -2836,15 +2839,15 @@ static void REGPARAM2 dmac_gvp_bput(struct wd_state *wd, uaecptr addr, uae_u32 b
        addr &= wd->board_mask;
        if (wd->autoconfig) {
                if (addr == 0x48 && !wd->configured) {
-                       map_banks_z2(wd->bank, b, (wd->board_mask + 1) >> 16);
+                       map_banks_z2(&wd->bank, b, (wd->board_mask + 1) >> 16);
                        wd->baseaddress = b << 16;
                        wd->configured = 1;
-                       expamem_next(wd->bank, NULL);
+                       expamem_next(&wd->bank, NULL);
                        return;
                }
                if (addr == 0x4c && !wd->configured) {
                        wd->configured = 1;
-                       expamem_shutup(wd->bank);
+                       expamem_shutup(&wd->bank);
                        return;
                }
                if (!wd->configured)
@@ -2940,7 +2943,8 @@ static uae_u8 *REGPARAM2 dmac_gvp_xlate(uaecptr addr)
        addr &= 0xffff;
        return wd->rom + addr;
 }
-addrbank gvp_bank = {
+
+static const addrbank gvp_bank = {
        dmac_gvp_lget, dmac_gvp_wget, dmac_gvp_bget,
        dmac_gvp_lput, dmac_gvp_wput, dmac_gvp_bput,
        dmac_gvp_xlate, dmac_gvp_check, NULL, NULL, _T("GVP"),
@@ -3177,7 +3181,7 @@ static void REGPARAM2 mbdmac_bput (uaecptr addr, uae_u32 b)
        mbdmac_write_byte (wd_a3000, addr, b);
 }
 
-addrbank mbdmac_a3000_bank = {
+static addrbank mbdmac_a3000_bank = {
        mbdmac_lget, mbdmac_wget, mbdmac_bget,
        mbdmac_lput, mbdmac_wput, mbdmac_bput,
        default_xlate, default_check, NULL, NULL, _T("A3000 DMAC"),
@@ -3185,15 +3189,15 @@ addrbank mbdmac_a3000_bank = {
        ABFLAG_IO | ABFLAG_SAFE, S_READ, S_WRITE
 };
 
-static void ew (struct wd_state *wd, int addr, uae_u32 value)
+static void ew (uae_u8 *ac, int addr, uae_u32 value)
 {
        addr &= 0xffff;
        if (addr == 00 || addr == 02 || addr == 0x40 || addr == 0x42) {
-               wd->dmacmemory[addr] = (value & 0xf0);
-               wd->dmacmemory[addr + 2] = (value & 0x0f) << 4;
+               ac[addr] = (value & 0xf0);
+               ac[addr + 2] = (value & 0x0f) << 4;
        } else {
-               wd->dmacmemory[addr] = ~(value & 0xf0);
-               wd->dmacmemory[addr + 2] = ~((value & 0x0f) << 4);
+               ac[addr] = ~(value & 0xf0);
+               ac[addr + 2] = ~((value & 0x0f) << 4);
        }
 }
 
@@ -3289,11 +3293,17 @@ void a3000_add_scsi_unit (int ch, struct uaedev_config_info *ci, struct romconfi
        add_scsi_device(&wd->scsis[ch], ch, ci, rc);
 }
 
-void a3000scsi_reset (void)
+bool a3000scsi_init(struct autoconfig_info *aci)
 {
+       aci->addrbank = &expamem_nonautoconfig;
+       aci->start = 0xdd0000;
+       aci->size = 0x10000;
+       if (!aci->doinit) {
+               return true;
+       }
        struct wd_state *wd = wd_a3000;
        if (!wd)
-               return;
+               return false;
        init_wd_scsi (wd);
        wd->enabled = true;
        wd->configured = -1;
@@ -3302,6 +3312,7 @@ void a3000scsi_reset (void)
        map_banks(&mbdmac_a3000_bank, wd->baseaddress >> 16, 1, 0);
        wd_cmd_reset (&wd->wc, false);
        reset_dmac(wd);
+       return true;
 }
 
 void a3000scsi_free (void)
@@ -3409,46 +3420,53 @@ void a2091_reset (void)
        }
 }
 
-addrbank *a2091_init (struct romconfig *rc)
+bool a2091_init (struct autoconfig_info *aci)
 {
-       struct wd_state *wd = getscsi(rc);
+       ew(aci->autoconfig_raw, 0x00, 0xc0 | 0x01 | 0x10 | (expansion_is_next_board_fastram() ? 0x08 : 0x00));
+       /* A590/A2091 hardware id */
+       ew(aci->autoconfig_raw, 0x04, aci->rc->subtype == 0 ? 0x02 : 0x03);
+       /* commodore's manufacturer id */
+       ew (aci->autoconfig_raw, 0x10, 0x02);
+       ew (aci->autoconfig_raw, 0x14, 0x02);
+       /* rom vector */
+       ew (aci->autoconfig_raw, 0x28, CDMAC_ROM_VECTOR >> 8);
+       ew (aci->autoconfig_raw, 0x2c, CDMAC_ROM_VECTOR);
+
+       ew (aci->autoconfig_raw, 0x18, 0x00); /* ser.no. Byte 0 */
+       ew (aci->autoconfig_raw, 0x1c, 0x00); /* ser.no. Byte 1 */
+       ew (aci->autoconfig_raw, 0x20, 0x00); /* ser.no. Byte 2 */
+       ew (aci->autoconfig_raw, 0x24, 0x00); /* ser.no. Byte 3 */
+
+       aci->label = _T("A2091");
+       if (!aci->doinit)
+               return true;
+
+       struct wd_state *wd = getscsi(aci->rc);
        int slotsize;
 
        if (!wd)
-               return &expamem_null;
+               return false;
 
        init_wd_scsi(wd);
 
-       wd->cdmac.old_dmac = rc->subtype == 0;
+       wd->cdmac.old_dmac = aci->rc->subtype == 0;
        wd->configured = 0;
        wd->autoconfig = true;
        wd->board_mask = 65535;
-       wd->bank = &dmaca2091_bank;
-       memset (wd->dmacmemory, 0xff, sizeof wd->dmacmemory);
-       ew(wd, 0x00, 0xc0 | 0x01 | 0x10 | (expansion_is_next_board_fastram() ? 0x08 : 0x00));
-       /* A590/A2091 hardware id */
-       ew(wd, 0x04, wd->cdmac.old_dmac ? 0x02 : 0x03);
-       /* commodore's manufacturer id */
-       ew (wd, 0x10, 0x02);
-       ew (wd, 0x14, 0x02);
-       /* rom vector */
-       ew (wd, 0x28, CDMAC_ROM_VECTOR >> 8);
-       ew (wd, 0x2c, CDMAC_ROM_VECTOR);
+       memcpy(&wd->bank, &dmaca2091_bank, sizeof addrbank);
+       memcpy(wd->dmacmemory, aci->autoconfig_raw, sizeof wd->dmacmemory);
 
-       ew (wd, 0x18, 0x00); /* ser.no. Byte 0 */
-       ew (wd, 0x1c, 0x00); /* ser.no. Byte 1 */
-       ew (wd, 0x20, 0x00); /* ser.no. Byte 2 */
-       ew (wd, 0x24, 0x00); /* ser.no. Byte 3 */
+       alloc_expansion_bank(&wd->bank, aci);
 
        wd->rombankswitcher = 0;
        wd->rombank = 0;
        slotsize = 65536;
-       wd->rom = xcalloc (uae_u8, slotsize);
+       wd->rom = wd->bank.baseaddr;
        memset(wd->rom, 0xff, slotsize);
        wd->rom_size = 16384;
        wd->rom_mask = wd->rom_size - 1;
-       if (!rc->autoboot_disabled) {
-               struct zfile *z = read_device_from_romconfig(rc, ROMTYPE_A2091);
+       if (!aci->rc->autoboot_disabled) {
+               struct zfile *z = read_device_from_romconfig(aci->rc, ROMTYPE_A2091);
                if (z) {
                        wd->rom_size = zfile_size (z);
                        zfile_fread (wd->rom, wd->rom_size, 1, z);
@@ -3466,50 +3484,57 @@ addrbank *a2091_init (struct romconfig *rc)
                        wd->rom_mask = wd->rom_size - 1;
                }
        }
-       return wd->bank;
+       aci->addrbank = &wd->bank;
+       return true;
 }
 
-addrbank *a2090_init (struct romconfig *rc)
+bool a2090_init (struct autoconfig_info *aci)
 {
-       struct wd_state *wd = getscsi(rc);
+       ew(aci->autoconfig_raw, 0x00, 0xc0 | 0x01 | 0x10);
+       /* A590/A2091 hardware id */
+       ew(aci->autoconfig_raw, 0x04, aci->rc->subtype ? 0x02 : 0x01);
+       /* commodore's manufacturer id */
+       ew(aci->autoconfig_raw, 0x10, 0x02);
+       ew(aci->autoconfig_raw, 0x14, 0x02);
+       /* rom vector */
+       ew(aci->autoconfig_raw, 0x28, DMAC_8727_ROM_VECTOR >> 8);
+       ew(aci->autoconfig_raw, 0x2c, DMAC_8727_ROM_VECTOR);
+
+       ew(aci->autoconfig_raw, 0x18, 0x00); /* ser.no. Byte 0 */
+       ew(aci->autoconfig_raw, 0x1c, 0x00); /* ser.no. Byte 1 */
+       ew(aci->autoconfig_raw, 0x20, 0x00); /* ser.no. Byte 2 */
+       ew(aci->autoconfig_raw, 0x24, 0x00); /* ser.no. Byte 3 */
+
+       aci->label = _T("A2090");
+       if (!aci->doinit)
+               return true;
+
+       struct wd_state *wd = getscsi(aci->rc);
        int slotsize;
 
        if (!wd)
-               return &expamem_null;
+               return false;
 
        init_wd_scsi(wd);
 
        wd->configured = 0;
        wd->autoconfig = true;
        wd->board_mask = 65535;
-       wd->bank = &dmaca2091_bank;
-       memset (wd->dmacmemory, 0xff, sizeof wd->dmacmemory);
-       ew (wd, 0x00, 0xc0 | 0x01 | 0x10);
-       /* A590/A2091 hardware id */
-       ew(wd, 0x04, rc->subtype ? 0x02 : 0x01);
-       /* commodore's manufacturer id */
-       ew (wd, 0x10, 0x02);
-       ew (wd, 0x14, 0x02);
-       /* rom vector */
-       ew (wd, 0x28, DMAC_8727_ROM_VECTOR >> 8);
-       ew (wd, 0x2c, DMAC_8727_ROM_VECTOR);
-
-       ew (wd, 0x18, 0x00); /* ser.no. Byte 0 */
-       ew (wd, 0x1c, 0x00); /* ser.no. Byte 1 */
-       ew (wd, 0x20, 0x00); /* ser.no. Byte 2 */
-       ew (wd, 0x24, 0x00); /* ser.no. Byte 3 */
-
+       memcpy(&wd->bank, &dmaca2091_bank, sizeof addrbank);
+       memcpy(wd->dmacmemory, aci->autoconfig_raw, sizeof wd->dmacmemory);
        //ew(wd, 0x30, 0x80); // SCSI only flag
 
+       alloc_expansion_bank(&wd->bank, aci);
+
        wd->rombankswitcher = 0;
        wd->rombank = 0;
        slotsize = 65536;
-       wd->rom = xcalloc (uae_u8, slotsize);
+       wd->rom = wd->bank.baseaddr;
        memset(wd->rom, 0xff, slotsize);
        wd->rom_size = 16384;
        wd->rom_mask = wd->rom_size - 1;
-       if (!rc->autoboot_disabled) {
-               struct zfile *z = read_device_from_romconfig(rc, ROMTYPE_A2090);
+       if (!aci->rc->autoboot_disabled) {
+               struct zfile *z = read_device_from_romconfig(aci->rc, ROMTYPE_A2090);
                if (z) {
                        wd->rom_size = zfile_size (z);
                        zfile_fread (wd->rom, wd->rom_size, 1, z);
@@ -3520,7 +3545,7 @@ addrbank *a2090_init (struct romconfig *rc)
                        wd->rom_mask = wd->rom_size - 1;
                }
        }
-       return wd->bank;
+       return true;
 }
 
 static void gvp_free_device (struct wd_state *wd)
@@ -3570,25 +3595,40 @@ static bool is_gvp_accelerator(void)
        return ISCPUBOARD(BOARD_GVP, -1);
 }
 
-static addrbank *gvp_init(struct romconfig *rc, bool series2, bool accel)
+static bool gvp_init(struct autoconfig_info *aci, bool series2, bool accel)
 {
-       struct wd_state *wd = getscsi(rc);
-       bool isscsi = true;
-       const uae_u8 *ac;
        int romtype;
-
+       const uae_u8 *ac = gvp_scsi_ii_autoconfig;
+       if (!series2) {
+               ac = gvp_scsi_i_autoconfig_1;
+               if (aci->rc->subtype == 1) {
+                       ac = gvp_scsi_i_autoconfig_2;
+               } else if (aci->rc->subtype == 2) {
+                       ac = gvp_scsi_i_autoconfig_3;
+               }
+       }
        if (!accel) {
                romtype = series2 ? ROMTYPE_GVPS2 : ROMTYPE_GVPS1;
+               aci->label = series2 ? _T("GVP SCSI S2") : _T("GVP SCSI S1");
        } else {
                romtype = ROMTYPE_CPUBOARD;
+               aci->label = _T("GVP Acclerator SCSI");
        }
 
+       if (!aci->doinit) {
+               aci->autoconfigp = ac;
+               return true;
+       }
+
+       struct wd_state *wd = getscsi(aci->rc);
+       bool isscsi = true;
+
        if (!wd)
-               return &expamem_null;
+               return false;
 
        init_wd_scsi(wd);
        wd->configured = 0;
-       wd->bank = &gvp_bank;
+       memcpy(&wd->bank, &gvp_bank, sizeof addrbank);
        wd->autoconfig = true;
        wd->rombankswitcher = 0;
        memset(wd->dmacmemory, 0xff, sizeof wd->dmacmemory);
@@ -3601,29 +3641,26 @@ static addrbank *gvp_init(struct romconfig *rc, bool series2, bool accel)
        memset(wd->rom, 0xff, 2 * wd->rom_size);
        wd->rom_mask = 32768 - 1;
        wd->gdmac.s1_subtype = 0;
-       ac = gvp_scsi_ii_autoconfig;
 
-       ac = gvp_scsi_ii_autoconfig;
+       alloc_expansion_bank(&wd->bank, aci);
+
        if (!series2) {
-               ac = gvp_scsi_i_autoconfig_1;
                wd->gdmac.s1_rammask = GVP_SERIES_I_RAM_MASK_1;
                wd->gdmac.s1_ramoffset = GVP_SERIES_I_RAM_OFFSET_1;
-               if (rc->subtype == 1) {
-                       ac = gvp_scsi_i_autoconfig_2;
+               if (aci->rc->subtype == 1) {
                        wd->gdmac.s1_rammask = GVP_SERIES_I_RAM_MASK_2;
                        wd->gdmac.s1_ramoffset = GVP_SERIES_I_RAM_OFFSET_2;
-               } else if (rc->subtype == 2) {
-                       ac = gvp_scsi_i_autoconfig_3;
+               } else if (aci->rc->subtype == 2) {
                        wd->gdmac.s1_rammask = GVP_SERIES_I_RAM_MASK_3;
                        wd->gdmac.s1_ramoffset = GVP_SERIES_I_RAM_OFFSET_3;
                        wd->board_mask = 131071;
                }
-               wd->gdmac.s1_subtype = rc->subtype;
+               wd->gdmac.s1_subtype = aci->rc->subtype;
        }
        xfree(wd->gdmac.buffer);
        wd->gdmac.buffer = xcalloc(uae_u8, 16384);
-       if (!rc->autoboot_disabled) {
-               struct zfile *z = read_device_from_romconfig(rc, ROMTYPE_GVPS2);
+       if (!aci->rc->autoboot_disabled) {
+               struct zfile *z = read_device_from_romconfig(aci->rc, ROMTYPE_GVPS2);
                if (z) {
                        int size = zfile_size(z);
                        if (series2) {
@@ -3687,23 +3724,23 @@ static addrbank *gvp_init(struct romconfig *rc, bool series2, bool accel)
 
        for (int i = 0; i < 16; i++) {
                uae_u8 b = ac[i];
-               ew(wd, i * 4, b);
+               ew(wd->dmacmemory, i * 4, b);
        }
        gvp_reset_device(wd);
-       return wd->bank;
+       return true;
 }
 
-addrbank *gvp_init_s1(struct romconfig *rc)
+bool gvp_init_s1(struct autoconfig_info *aci)
 {
-       return gvp_init(rc, false, false);
+       return gvp_init(aci, false, false);
 }
-addrbank *gvp_init_s2(struct romconfig *rc)
+bool gvp_init_s2(struct autoconfig_info *aci)
 {
-       return gvp_init(rc, true, false);
+       return gvp_init(aci, true, false);
 }
-addrbank *gvp_init_accelerator(struct romconfig *rc)
+bool gvp_init_accelerator(struct autoconfig_info *aci)
 {
-       return gvp_init(rc, true, true);
+       return gvp_init(aci, true, true);
 }
 
 void cdtv_add_scsi_unit (int ch, struct uaedev_config_info *ci, struct romconfig *rc)
index 8e8eb08b2a56ee84490debdefad5d05d6285ac05..3a53ed9a0a7ae15b86e708f8622a57d57cadc106 100644 (file)
--- a/akiko.cpp
+++ b/akiko.cpp
@@ -31,8 +31,8 @@
 #include "debug.h"
 
 #define AKIKO_DEBUG_NVRAM 0
-#define AKIKO_DEBUG_IO 1
-#define AKIKO_DEBUG_IO_CMD 1
+#define AKIKO_DEBUG_IO 0
+#define AKIKO_DEBUG_IO_CMD 0
 
 int log_cd32 = 0;
 
@@ -412,7 +412,7 @@ static void subfunc (uae_u8 *data, int cnt)
        uae_sem_post (&sub_sem);
 }
 
-static int statusfunc (int status)
+static int statusfunc (int status, int playpos)
 {
        if (status == -1)
                return 0;
index 2bc0fe8d51e432647987dae02f327ba422fa902d..a7e5a473580a23754c51f0fb05fe82d646355354 100644 (file)
--- a/audio.cpp
+++ b/audio.cpp
@@ -82,8 +82,26 @@ typedef struct {
        int time, output;
 } sinc_queue_t;
 
-struct audio_channel_data {
+struct audio_channel_data2
+{
+       int current_sample, last_sample;
+       int sample_accum, sample_accum_time;
+       int sinc_output_state;
+       sinc_queue_t sinc_queue[SINC_QUEUE_LENGTH];
+       int sinc_queue_time;
+       int sinc_queue_head;
+       int vol;
        unsigned int adk_mask;
+};
+struct audio_stream_data
+{
+       bool active;
+       unsigned int evtime;
+       struct audio_channel_data2 data[AUDIO_CHANNEL_MAX_STREAM_CH];
+};
+
+struct audio_channel_data
+{
        unsigned int evtime;
        bool dmaenstore;
        bool intreq2;
@@ -93,17 +111,11 @@ struct audio_channel_data {
        int drhpos;
        bool dat_written;
        uaecptr lc, pt;
-       int current_sample, last_sample;
        int state;
        int per;
-       int vol;
        int len, wlen;
        uae_u16 dat, dat2;
-       int sample_accum, sample_accum_time;
-       int sinc_output_state;
-       sinc_queue_t sinc_queue[SINC_QUEUE_LENGTH];
-    int sinc_queue_time;
-    int sinc_queue_head;
+       struct audio_channel_data2 data;
 #if TEST_AUDIO > 0
        bool hisample, losample;
        bool have_dat;
@@ -116,8 +128,8 @@ struct audio_channel_data {
        int dmaofftime_active;
 };
 
-static int audio_channel_count = AUDIO_CHANNELS_PAULA;
-static bool audio_extra_channels[2];
+static int audio_extra_streams[AUDIO_CHANNEL_STREAMS];
+static int audio_total_extra_streams;
 
 static int samplecnt;
 #if SOUNDSTUFF > 0
@@ -299,7 +311,9 @@ static void do_samplerip (struct audio_channel_data *adp)
        audio_sampleripper (0);
 }
 
-static struct audio_channel_data audio_channel[AUDIO_CHANNELS_MAX];
+static struct audio_channel_data audio_channel[AUDIO_CHANNELS_PAULA];
+static struct audio_stream_data audio_stream[AUDIO_CHANNEL_STREAMS];
+static struct audio_channel_data2 *audio_data[AUDIO_CHANNELS_PAULA + AUDIO_CHANNEL_STREAMS * AUDIO_CHANNEL_MAX_STREAM_CH];
 int sound_available = 0;
 void (*sample_handler) (void);
 static void(*sample_prehandler) (unsigned long best_evtime);
@@ -315,7 +329,7 @@ static unsigned long last_cycles;
 static float next_sample_evtime;
 
 typedef uae_s8 sample8_t;
-#define DO_CHANNEL_1(v, c) do { (v) *= audio_channel[c].vol; } while (0)
+#define DO_CHANNEL_1(v, c) do { (v) *= audio_channel[c].data.vol; } while (0)
 #define SBASEVAL16(logn) ((logn) == 1 ? SOUND16_BASE_VAL >> 1 : SOUND16_BASE_VAL)
 
 STATIC_INLINE int FINISH_DATA (int data, int bits, int ch)
@@ -498,11 +512,11 @@ static void put_sound_word_left2 (uae_u32 w)
 static void anti_prehandler (unsigned long best_evtime)
 {
        int i, output;
-       struct audio_channel_data *acd;
+       struct audio_channel_data2 *acd;
 
        /* Handle accumulator antialiasiation */
-       for (i = 0; i < audio_channel_count; i++) {
-               acd = &audio_channel[i];
+       for (i = 0; audio_data[i]; i++) {
+               acd = audio_data[i];
                output = (acd->current_sample * acd->vol) & acd->adk_mask;
                acd->sample_accum += output * best_evtime;
                acd->sample_accum_time += best_evtime;
@@ -513,19 +527,20 @@ static void samplexx_anti_handler (int *datasp, int ch_start, int ch_num)
 {
        int i, j;
        for (i = ch_start, j = 0; j < ch_num; i++, j++) {
-               datasp[j] = audio_channel[i].sample_accum_time ? (audio_channel[i].sample_accum / audio_channel[i].sample_accum_time) : 0;
-               audio_channel[i].sample_accum = 0;
-               audio_channel[i].sample_accum_time = 0;
+               struct audio_channel_data2 *acd = audio_data[i];
+               datasp[j] = acd->sample_accum_time ? (acd->sample_accum / acd->sample_accum_time) : 0;
+               acd->sample_accum = 0;
+               acd->sample_accum_time = 0;
        }
 }
 
 static void sinc_prehandler_paula (unsigned long best_evtime)
 {
        int i, output;
-       struct audio_channel_data *acd;
+       struct audio_channel_data2 *acd;
 
        for (i = 0; i < AUDIO_CHANNELS_PAULA; i++)  {
-               acd = &audio_channel[i];
+               acd = audio_data[i];
                int vol = acd->vol;
                output = (acd->current_sample * vol) & acd->adk_mask;
 
@@ -561,7 +576,7 @@ static void samplexx_sinc_handler (int *datasp, int ch_start, int ch_num)
 
        for (i = ch_start, k = 0; k < ch_num; i++, k++) {
                int j, v;
-               struct audio_channel_data *acd = &audio_channel[i];
+               struct audio_channel_data2 *acd = audio_data[i];
                /* The sum rings with harmonic components up to infinity... */
                int sum = acd->sinc_output_state << 17;
                /* ...but we cancel them through mixing in BLEPs instead */
@@ -609,40 +624,50 @@ static void get_extra_channels(int *data1, int *data2, int sample1, int sample2)
                *data2 = d2;
        }
 }
-static void get_extra_channels_sample(int *data1, int *data2, int mode)
+
+static void do_extra_channels(int i, int *data1, int *data2, int *data3, int *data4, int *data5, int *data6)
 {
-       if (audio_extra_channels[0]) {
+       int idx = AUDIO_CHANNELS_PAULA + i * AUDIO_CHANNEL_MAX_STREAM_CH;
+       if (audio_extra_streams[i] == 2) {
                int datas[2];
-               samplexx_anti_handler(datas, AUDIO_CHANNEL_SNDBOARD_LEFT, 2);
+               samplexx_anti_handler(datas, idx, 2);
                get_extra_channels(data1, data2, datas[0], datas[1]);
-       }
-       if (audio_extra_channels[1]) {
-               int datas[2];
-               samplexx_anti_handler(datas, AUDIO_CHANNEL_CDA_LEFT, 2);
-               get_extra_channels(data1, data2, datas[0], datas[1]);
-       }
-}
-static void get_extra_channels_sample_mono(int *data1, int mode)
-{
-       if (audio_extra_channels[0]) {
+       } else if (audio_extra_streams[i] == 1) {
                int datas[1];
-               samplexx_anti_handler(datas, AUDIO_CHANNEL_SNDBOARD_LEFT, 1);
+               samplexx_anti_handler(datas, idx, 1);
                int d1 = *data1 + datas[0];
                if (d1 < -32768)
                        d1 = -32768;
                if (d1 > 32767)
                        d1 = 32767;
                *data1 = d1;
+               if (data2)
+                       *data2 = d1;
+       } else if (audio_extra_streams[i] > 2) {
+               int datas[AUDIO_CHANNEL_MAX_STREAM_CH];
+               samplexx_anti_handler(datas, idx, 6);
+               get_extra_channels(data1, data2, datas[0], datas[1]);
+               get_extra_channels(data3, data4, datas[2], datas[3]);
+               if (data5 && data6)
+                       get_extra_channels(data5, data6, datas[4], datas[5]);
        }
-       if (audio_extra_channels[1]) {
-               int datas[1];
-               samplexx_anti_handler(datas, AUDIO_CHANNEL_CDA_LEFT, 1);
-               int d1 = *data1 + datas[0];
-               if (d1 < -32768)
-                       d1 = -32768;
-               if (d1 > 32767)
-                       d1 = 32767;
-               *data1 = d1;
+}
+
+static void get_extra_channels_sample2(int *data1, int *data2, int mode)
+{
+       if (!audio_total_extra_streams)
+               return;
+       for (int i = 0; i < AUDIO_CHANNEL_STREAMS; i++) {
+               do_extra_channels(i, data1, data2, NULL, NULL, NULL, NULL);
+       }
+}
+
+static void get_extra_channels_sample6(int *data1, int *data2, int *data3, int *data4, int *data5, int *data6, int mode)
+{
+       if (!audio_total_extra_streams)
+               return;
+       for (int i = 0; i < AUDIO_CHANNEL_STREAMS; i++) {
+               do_extra_channels(i, data1, data2, data3, data4, data5, data6);
        }
 }
 
@@ -656,7 +681,7 @@ static void sample16i_sinc_handler (void)
        
        do_filter(&data1, 0);
 
-       get_extra_channels_sample_mono(&data1, 2);
+       get_extra_channels_sample2(&data1, NULL, 2);
 
        set_sound_buffers ();
        PUT_SOUND_WORD_MONO (data1);
@@ -665,20 +690,20 @@ static void sample16i_sinc_handler (void)
 
 void sample16_handler (void)
 {
-       int data0 = audio_channel[0].current_sample;
-       int data1 = audio_channel[1].current_sample;
-       int data2 = audio_channel[2].current_sample;
-       int data3 = audio_channel[3].current_sample;
+       int data0 = audio_channel[0].data.current_sample;
+       int data1 = audio_channel[1].data.current_sample;
+       int data2 = audio_channel[2].data.current_sample;
+       int data3 = audio_channel[3].data.current_sample;
        int data;
 
        DO_CHANNEL_1 (data0, 0);
        DO_CHANNEL_1 (data1, 1);
        DO_CHANNEL_1 (data2, 2);
        DO_CHANNEL_1 (data3, 3);
-       data0 &= audio_channel[0].adk_mask;
-       data1 &= audio_channel[1].adk_mask;
-       data2 &= audio_channel[2].adk_mask;
-       data3 &= audio_channel[3].adk_mask;
+       data0 &= audio_channel[0].data.adk_mask;
+       data1 &= audio_channel[1].data.adk_mask;
+       data2 &= audio_channel[2].data.adk_mask;
+       data3 &= audio_channel[3].data.adk_mask;
        data0 += data1;
        data0 += data2;
        data0 += data3;
@@ -687,7 +712,7 @@ void sample16_handler (void)
 
        do_filter(&data, 0);
 
-       get_extra_channels_sample_mono(&data, 0);
+       get_extra_channels_sample2(&data, NULL, 0);
 
        set_sound_buffers ();
        PUT_SOUND_WORD_MONO (data);
@@ -706,7 +731,7 @@ static void sample16i_anti_handler (void)
 
        do_filter(&data1, 0);
 
-       get_extra_channels_sample_mono(&data1, 1);
+       get_extra_channels_sample2(&data1, NULL, 1);
 
        set_sound_buffers ();
        PUT_SOUND_WORD_MONO (data1);
@@ -717,14 +742,14 @@ static void sample16i_rh_handler (void)
 {
        unsigned long delta, ratio;
 
-       int data0 = audio_channel[0].current_sample;
-       int data1 = audio_channel[1].current_sample;
-       int data2 = audio_channel[2].current_sample;
-       int data3 = audio_channel[3].current_sample;
-       int data0p = audio_channel[0].last_sample;
-       int data1p = audio_channel[1].last_sample;
-       int data2p = audio_channel[2].last_sample;
-       int data3p = audio_channel[3].last_sample;
+       int data0 = audio_channel[0].data.current_sample;
+       int data1 = audio_channel[1].data.current_sample;
+       int data2 = audio_channel[2].data.current_sample;
+       int data3 = audio_channel[3].data.current_sample;
+       int data0p = audio_channel[0].data.last_sample;
+       int data1p = audio_channel[1].data.last_sample;
+       int data2p = audio_channel[2].data.last_sample;
+       int data3p = audio_channel[3].data.last_sample;
        int data;
 
        DO_CHANNEL_1 (data0, 0);
@@ -736,14 +761,14 @@ static void sample16i_rh_handler (void)
        DO_CHANNEL_1 (data2p, 2);
        DO_CHANNEL_1 (data3p, 3);
 
-       data0 &= audio_channel[0].adk_mask;
-       data0p &= audio_channel[0].adk_mask;
-       data1 &= audio_channel[1].adk_mask;
-       data1p &= audio_channel[1].adk_mask;
-       data2 &= audio_channel[2].adk_mask;
-       data2p &= audio_channel[2].adk_mask;
-       data3 &= audio_channel[3].adk_mask;
-       data3p &= audio_channel[3].adk_mask;
+       data0 &= audio_channel[0].data.adk_mask;
+       data0p &= audio_channel[0].data.adk_mask;
+       data1 &= audio_channel[1].data.adk_mask;
+       data1p &= audio_channel[1].data.adk_mask;
+       data2 &= audio_channel[2].data.adk_mask;
+       data2p &= audio_channel[2].data.adk_mask;
+       data3 &= audio_channel[3].data.adk_mask;
+       data3p &= audio_channel[3].data.adk_mask;
 
        /* linear interpolation and summing up... */
        delta = audio_channel[0].per;
@@ -763,7 +788,7 @@ static void sample16i_rh_handler (void)
 
        do_filter(&data, 0);
 
-       get_extra_channels_sample_mono(&data, 0);
+       get_extra_channels_sample2(&data, NULL, 0);
 
        set_sound_buffers ();
        PUT_SOUND_WORD_MONO (data);
@@ -772,14 +797,14 @@ static void sample16i_rh_handler (void)
 
 static void sample16i_crux_handler (void)
 {
-       int data0 = audio_channel[0].current_sample;
-       int data1 = audio_channel[1].current_sample;
-       int data2 = audio_channel[2].current_sample;
-       int data3 = audio_channel[3].current_sample;
-       int data0p = audio_channel[0].last_sample;
-       int data1p = audio_channel[1].last_sample;
-       int data2p = audio_channel[2].last_sample;
-       int data3p = audio_channel[3].last_sample;
+       int data0 = audio_channel[0].data.current_sample;
+       int data1 = audio_channel[1].data.current_sample;
+       int data2 = audio_channel[2].data.current_sample;
+       int data3 = audio_channel[3].data.current_sample;
+       int data0p = audio_channel[0].data.last_sample;
+       int data1p = audio_channel[1].data.last_sample;
+       int data2p = audio_channel[2].data.last_sample;
+       int data3p = audio_channel[3].data.last_sample;
        int data;
 
        DO_CHANNEL_1 (data0, 0);
@@ -791,14 +816,14 @@ static void sample16i_crux_handler (void)
        DO_CHANNEL_1 (data2p, 2);
        DO_CHANNEL_1 (data3p, 3);
 
-       data0 &= audio_channel[0].adk_mask;
-       data0p &= audio_channel[0].adk_mask;
-       data1 &= audio_channel[1].adk_mask;
-       data1p &= audio_channel[1].adk_mask;
-       data2 &= audio_channel[2].adk_mask;
-       data2p &= audio_channel[2].adk_mask;
-       data3 &= audio_channel[3].adk_mask;
-       data3p &= audio_channel[3].adk_mask;
+       data0 &= audio_channel[0].data.adk_mask;
+       data0p &= audio_channel[0].data.adk_mask;
+       data1 &= audio_channel[1].data.adk_mask;
+       data1p &= audio_channel[1].data.adk_mask;
+       data2 &= audio_channel[2].data.adk_mask;
+       data2p &= audio_channel[2].data.adk_mask;
+       data3 &= audio_channel[3].data.adk_mask;
+       data3p &= audio_channel[3].data.adk_mask;
 
        {
                struct audio_channel_data *cdp;
@@ -840,7 +865,7 @@ static void sample16i_crux_handler (void)
 
        do_filter(&data, 0);
 
-       get_extra_channels_sample_mono(&data, 0);
+       get_extra_channels_sample2(&data, NULL, 0);
 
        set_sound_buffers ();
        PUT_SOUND_WORD_MONO (data);
@@ -849,29 +874,30 @@ static void sample16i_crux_handler (void)
 
 #ifdef HAVE_STEREO_SUPPORT
 
-STATIC_INLINE void make6ch (uae_s32 d0, uae_s32 d1, uae_s32 d2, uae_s32 d3)
+STATIC_INLINE void make6ch (uae_s32 d0, uae_s32 d1, uae_s32 d2, uae_s32 d3, uae_s32 *d4, uae_s32 *d5)
 {
        uae_s32 sum = d0 + d1 + d2 + d3;
        sum /= 8;
-       PUT_SOUND_WORD (sum);
-       PUT_SOUND_WORD (sum);
+       *d4 = sum;
+       *d5 = sum;
 }
 
 void sample16ss_handler (void)
 {
-       int data0 = audio_channel[0].current_sample;
-       int data1 = audio_channel[1].current_sample;
-       int data2 = audio_channel[2].current_sample;
-       int data3 = audio_channel[3].current_sample;
+       int data0 = audio_channel[0].data.current_sample;
+       int data1 = audio_channel[1].data.current_sample;
+       int data2 = audio_channel[2].data.current_sample;
+       int data3 = audio_channel[3].data.current_sample;
+       int data4, data5;
        DO_CHANNEL_1 (data0, 0);
        DO_CHANNEL_1 (data1, 1);
        DO_CHANNEL_1 (data2, 2);
        DO_CHANNEL_1 (data3, 3);
 
-       data0 &= audio_channel[0].adk_mask;
-       data1 &= audio_channel[1].adk_mask;
-       data2 &= audio_channel[2].adk_mask;
-       data3 &= audio_channel[3].adk_mask;
+       data0 &= audio_channel[0].data.adk_mask;
+       data1 &= audio_channel[1].data.adk_mask;
+       data2 &= audio_channel[2].data.adk_mask;
+       data3 &= audio_channel[3].data.adk_mask;
 
        data0 = FINISH_DATA (data0, 14, 0);
        data1 = FINISH_DATA (data1, 14, 0);
@@ -883,14 +909,18 @@ void sample16ss_handler (void)
        do_filter(&data2, 3);
        do_filter(&data3, 2);
 
-       get_extra_channels_sample(&data0, &data1, 0);
-       get_extra_channels_sample(&data2, &data3, 0);
+       if (currprefs.sound_stereo == SND_6CH)
+               make6ch(data0, data1, data2, data3, &data4, &data5);
+
+       get_extra_channels_sample6(&data0, &data1, &data3, &data2, &data4, &data5, 0);
 
        set_sound_buffers ();
        put_sound_word_right(data0);
        put_sound_word_left (data1);
-       if (currprefs.sound_stereo == SND_6CH)
-               make6ch (data0, data1, data2, data3);
+       if (currprefs.sound_stereo == SND_6CH) {
+               PUT_SOUND_WORD(data4);
+               PUT_SOUND_WORD(data5);
+       }
        put_sound_word_right2(data3);
        put_sound_word_left2 (data2);
        check_sound_buffers ();
@@ -901,7 +931,7 @@ void sample16ss_handler (void)
 
 static void sample16ss_anti_handler (void)
 {
-       int data0, data1, data2, data3;
+       int data0, data1, data2, data3, data4, data5;
        int datas[AUDIO_CHANNELS_PAULA];
 
        samplexx_anti_handler (datas, 0, AUDIO_CHANNELS_PAULA);
@@ -915,14 +945,18 @@ static void sample16ss_anti_handler (void)
        do_filter(&data2, 3);
        do_filter(&data3, 2);
 
-       get_extra_channels_sample(&data0, &data1, 1);
-       get_extra_channels_sample(&data3, &data2, 1);
+       if (currprefs.sound_stereo == SND_6CH)
+               make6ch(data0, data1, data2, data3, &data4, &data5);
+
+       get_extra_channels_sample6(&data0, &data1, &data3, &data2, &data4, &data5, 0);
 
        set_sound_buffers ();
        put_sound_word_right(data0);
        put_sound_word_left (data1);
-       if (currprefs.sound_stereo == SND_6CH)
-               make6ch (data0, data1, data2, data3);
+       if (currprefs.sound_stereo == SND_6CH) {
+               PUT_SOUND_WORD(data4);
+               PUT_SOUND_WORD(data5);
+       }
        put_sound_word_right2(data3);
        put_sound_word_left2 (data2);
        check_sound_buffers ();
@@ -941,7 +975,7 @@ static void sample16si_anti_handler (void)
        do_filter(&data1, 0);
        do_filter(&data2, 1);
 
-       get_extra_channels_sample(&data1, &data2, 1);
+       get_extra_channels_sample2(&data1, &data2, 1);
 
        set_sound_buffers ();
        put_sound_word_right(data1);
@@ -951,7 +985,7 @@ static void sample16si_anti_handler (void)
 
 static void sample16ss_sinc_handler (void)
 {
-       int data0, data1, data2, data3;
+       int data0, data1, data2, data3, data4, data5;
        int datas[AUDIO_CHANNELS_PAULA];
 
        samplexx_sinc_handler (datas, 0, AUDIO_CHANNELS_PAULA);
@@ -965,14 +999,18 @@ static void sample16ss_sinc_handler (void)
        do_filter(&data2, 3);
        do_filter(&data3, 2);
 
-       get_extra_channels_sample(&data0, &data1, 2);
-       get_extra_channels_sample(&data3, &data2, 2);
+       if (currprefs.sound_stereo == SND_6CH)
+               make6ch(data0, data1, data2, data3, &data4, &data5);
+
+       get_extra_channels_sample6(&data0, &data1, &data3, &data2, &data4, &data5, 0);
 
        set_sound_buffers ();
        put_sound_word_right(data0);
        put_sound_word_left (data1);
-       if (currprefs.sound_stereo == SND_6CH)
-               make6ch (data0, data1, data2, data3);
+       if (currprefs.sound_stereo == SND_6CH) {
+               PUT_SOUND_WORD(data4);
+               PUT_SOUND_WORD(data5);
+       }
        put_sound_word_right2(data3);
        put_sound_word_left2 (data2);
        check_sound_buffers ();
@@ -991,7 +1029,7 @@ static void sample16si_sinc_handler (void)
        do_filter(&data1, 0);
        do_filter(&data2, 1);
 
-       get_extra_channels_sample(&data1, &data2, 2);
+       get_extra_channels_sample2(&data1, &data2, 2);
 
        set_sound_buffers ();
        put_sound_word_right(data1);
@@ -1001,19 +1039,19 @@ static void sample16si_sinc_handler (void)
 
 void sample16s_handler (void)
 {
-       int data0 = audio_channel[0].current_sample;
-       int data1 = audio_channel[1].current_sample;
-       int data2 = audio_channel[2].current_sample;
-       int data3 = audio_channel[3].current_sample;
+       int data0 = audio_channel[0].data.current_sample;
+       int data1 = audio_channel[1].data.current_sample;
+       int data2 = audio_channel[2].data.current_sample;
+       int data3 = audio_channel[3].data.current_sample;
        DO_CHANNEL_1 (data0, 0);
        DO_CHANNEL_1 (data1, 1);
        DO_CHANNEL_1 (data2, 2);
        DO_CHANNEL_1 (data3, 3);
 
-       data0 &= audio_channel[0].adk_mask;
-       data1 &= audio_channel[1].adk_mask;
-       data2 &= audio_channel[2].adk_mask;
-       data3 &= audio_channel[3].adk_mask;
+       data0 &= audio_channel[0].data.adk_mask;
+       data1 &= audio_channel[1].data.adk_mask;
+       data2 &= audio_channel[2].data.adk_mask;
+       data3 &= audio_channel[3].data.adk_mask;
 
        data0 += data3;
        data1 += data2;
@@ -1025,7 +1063,7 @@ void sample16s_handler (void)
        do_filter(&data2, 0);
        do_filter(&data3, 1);
 
-       get_extra_channels_sample(&data2, &data3, 0);
+       get_extra_channels_sample2(&data2, &data3, 0);
 
        set_sound_buffers ();
        put_sound_word_right(data2);
@@ -1035,14 +1073,14 @@ void sample16s_handler (void)
 
 static void sample16si_crux_handler (void)
 {
-       int data0 = audio_channel[0].current_sample;
-       int data1 = audio_channel[1].current_sample;
-       int data2 = audio_channel[2].current_sample;
-       int data3 = audio_channel[3].current_sample;
-       int data0p = audio_channel[0].last_sample;
-       int data1p = audio_channel[1].last_sample;
-       int data2p = audio_channel[2].last_sample;
-       int data3p = audio_channel[3].last_sample;
+       int data0 = audio_channel[0].data.current_sample;
+       int data1 = audio_channel[1].data.current_sample;
+       int data2 = audio_channel[2].data.current_sample;
+       int data3 = audio_channel[3].data.current_sample;
+       int data0p = audio_channel[0].data.last_sample;
+       int data1p = audio_channel[1].data.last_sample;
+       int data2p = audio_channel[2].data.last_sample;
+       int data3p = audio_channel[3].data.last_sample;
 
        DO_CHANNEL_1 (data0, 0);
        DO_CHANNEL_1 (data1, 1);
@@ -1053,14 +1091,14 @@ static void sample16si_crux_handler (void)
        DO_CHANNEL_1 (data2p, 2);
        DO_CHANNEL_1 (data3p, 3);
 
-       data0 &= audio_channel[0].adk_mask;
-       data0p &= audio_channel[0].adk_mask;
-       data1 &= audio_channel[1].adk_mask;
-       data1p &= audio_channel[1].adk_mask;
-       data2 &= audio_channel[2].adk_mask;
-       data2p &= audio_channel[2].adk_mask;
-       data3 &= audio_channel[3].adk_mask;
-       data3p &= audio_channel[3].adk_mask;
+       data0 &= audio_channel[0].data.adk_mask;
+       data0p &= audio_channel[0].data.adk_mask;
+       data1 &= audio_channel[1].data.adk_mask;
+       data1p &= audio_channel[1].data.adk_mask;
+       data2 &= audio_channel[2].data.adk_mask;
+       data2p &= audio_channel[2].data.adk_mask;
+       data3 &= audio_channel[3].data.adk_mask;
+       data3p &= audio_channel[3].data.adk_mask;
 
        {
                struct audio_channel_data *cdp;
@@ -1104,7 +1142,7 @@ static void sample16si_crux_handler (void)
        do_filter(&data2, 0);
        do_filter(&data3, 1);
 
-       get_extra_channels_sample(&data2, &data3, 0);
+       get_extra_channels_sample2(&data2, &data3, 0);
 
        set_sound_buffers ();
        put_sound_word_right(data2);
@@ -1116,14 +1154,14 @@ static void sample16si_rh_handler (void)
 {
        unsigned long delta, ratio;
 
-       int data0 = audio_channel[0].current_sample;
-       int data1 = audio_channel[1].current_sample;
-       int data2 = audio_channel[2].current_sample;
-       int data3 = audio_channel[3].current_sample;
-       int data0p = audio_channel[0].last_sample;
-       int data1p = audio_channel[1].last_sample;
-       int data2p = audio_channel[2].last_sample;
-       int data3p = audio_channel[3].last_sample;
+       int data0 = audio_channel[0].data.current_sample;
+       int data1 = audio_channel[1].data.current_sample;
+       int data2 = audio_channel[2].data.current_sample;
+       int data3 = audio_channel[3].data.current_sample;
+       int data0p = audio_channel[0].data.last_sample;
+       int data1p = audio_channel[1].data.last_sample;
+       int data2p = audio_channel[2].data.last_sample;
+       int data3p = audio_channel[3].data.last_sample;
 
        DO_CHANNEL_1 (data0, 0);
        DO_CHANNEL_1 (data1, 1);
@@ -1134,14 +1172,14 @@ static void sample16si_rh_handler (void)
        DO_CHANNEL_1 (data2p, 2);
        DO_CHANNEL_1 (data3p, 3);
 
-       data0 &= audio_channel[0].adk_mask;
-       data0p &= audio_channel[0].adk_mask;
-       data1 &= audio_channel[1].adk_mask;
-       data1p &= audio_channel[1].adk_mask;
-       data2 &= audio_channel[2].adk_mask;
-       data2p &= audio_channel[2].adk_mask;
-       data3 &= audio_channel[3].adk_mask;
-       data3p &= audio_channel[3].adk_mask;
+       data0 &= audio_channel[0].data.adk_mask;
+       data0p &= audio_channel[0].data.adk_mask;
+       data1 &= audio_channel[1].data.adk_mask;
+       data1p &= audio_channel[1].data.adk_mask;
+       data2 &= audio_channel[2].data.adk_mask;
+       data2p &= audio_channel[2].data.adk_mask;
+       data3 &= audio_channel[3].data.adk_mask;
+       data3p &= audio_channel[3].data.adk_mask;
 
        /* linear interpolation and summing up... */
        delta = audio_channel[0].per;
@@ -1164,7 +1202,7 @@ static void sample16si_rh_handler (void)
        do_filter(&data2, 0);
        do_filter(&data3, 1);
 
-       get_extra_channels_sample(&data2, &data3, 0);
+       get_extra_channels_sample2(&data2, &data3, 0);
 
        set_sound_buffers ();
        put_sound_word_right(data2);
@@ -1214,7 +1252,7 @@ static void schedule_audio (void)
 
        eventtab[ev_audio].active = 0;
        eventtab[ev_audio].oldcycles = get_cycles ();
-       for (i = 0; i < audio_channel_count; i++) {
+       for (i = 0; i < AUDIO_CHANNELS_PAULA; i++) {
                struct audio_channel_data *cdp = audio_channel + i;
                if (cdp->evtime != MAX_EV) {
                        if (best > cdp->evtime) {
@@ -1223,6 +1261,15 @@ static void schedule_audio (void)
                        }
                }
        }
+       for (i = 0; i < audio_total_extra_streams; i++) {
+               struct audio_stream_data *cdp = audio_stream + i;
+               if (cdp->evtime != MAX_EV) {
+                       if (best > cdp->evtime) {
+                               best = cdp->evtime;
+                               eventtab[ev_audio].active = 1;
+                       }
+               }
+       }
        eventtab[ev_audio].evtime = get_cycles () + best;
 }
 
@@ -1235,6 +1282,8 @@ static void audio_event_reset (void)
        if (!isrestore ()) {
                for (i = 0; i < AUDIO_CHANNELS_PAULA; i++)
                        zerostate (i);
+               for (i = 0; i < audio_total_extra_streams; i++)
+                       audio_stream[i].evtime = MAX_EV;
        }
        schedule_audio ();
        events_schedule ();
@@ -1314,8 +1363,8 @@ static void newsample (int nr, sample8_t sample)
 #endif
        if (!(audio_channel_mask & (1 << nr)))
                sample = 0;
-       cdp->last_sample = cdp->current_sample;
-       cdp->current_sample = sample;
+       cdp->data.last_sample = cdp->data.current_sample;
+       cdp->data.current_sample = sample;
 }
 
 STATIC_INLINE void setdr (int nr)
@@ -1352,10 +1401,10 @@ static void loaddat (int nr, bool modper)
                        else
                                cdp[1].per = PERIOD_MIN * CYCLE_UNIT;
                } else  if (audav) {
-                       cdp[1].vol = cdp->dat;
-                       cdp[1].vol &= 127;
-                       if (cdp[1].vol > 64)
-                               cdp[1].vol = 64;
+                       cdp[1].data.vol = cdp->dat;
+                       cdp[1].data.vol &= 127;
+                       if (cdp[1].data.vol > 64)
+                               cdp[1].data.vol = 64;
                }
        } else {
 #if TEST_AUDIO > 0
@@ -1588,18 +1637,14 @@ static void audio_state_channel2 (int nr, bool perfin)
        }
 }
 
-static void audio_state_cda(void);
-
 static void audio_state_channel (int nr, bool perfin)
 {
        struct audio_channel_data *cdp = audio_channel + nr;
        if (nr < AUDIO_CHANNELS_PAULA) {
                audio_state_channel2 (nr, perfin);
                cdp->dat_written = false;
-       } else if (nr == AUDIO_CHANNEL_SNDBOARD_LEFT || nr == AUDIO_CHANNEL_SNDBOARD_RIGHT) {
-               audio_state_sndboard(nr - AUDIO_CHANNEL_SNDBOARD_LEFT);
-       } else if (nr == AUDIO_CHANNEL_CDA_LEFT) {
-               audio_state_cda();
+       } else {
+               audio_state_stream(nr - AUDIO_CHANNELS_PAULA + 1);
        }
 }
 
@@ -1627,13 +1672,16 @@ void audio_reset (void)
        reset_sound ();
        memset (sound_filter_state, 0, sizeof sound_filter_state);
        if (!isrestore ()) {
-               for (i = 0; i < AUDIO_CHANNELS_MAX; i++) {
+               for (i = 0; i < AUDIO_CHANNELS_PAULA; i++) {
                        cdp = &audio_channel[i];
                        memset (cdp, 0, sizeof *audio_channel);
                        cdp->per = PERIOD_MAX - 1;
-                       cdp->vol = 0;
+                       cdp->data.vol = 0;
                        cdp->evtime = MAX_EV;
                }
+               for (i = 0; i < AUDIO_CHANNEL_STREAMS; i++) {
+                       audio_stream[i].evtime = MAX_EV;
+               }
        }
 
        last_cycles = get_cycles ();
@@ -1714,7 +1762,7 @@ void check_prefs_changed_audio (void)
 
 static void set_extra_prehandler(void)
 {
-       if (audio_channel_count > AUDIO_CHANNELS_PAULA && sample_prehandler != anti_prehandler) {
+       if (audio_total_extra_streams && sample_prehandler != anti_prehandler) {
                extra_sample_prehandler = anti_prehandler;
        } else {
                extra_sample_prehandler = NULL;
@@ -1847,6 +1895,13 @@ void set_audio (void)
        } else if (sample_handler == sample16si_anti_handler || sample_handler == sample16i_anti_handler || sample_handler == sample16ss_anti_handler) {
                sample_prehandler = anti_prehandler;
        }
+       for (int i = 0; i < AUDIO_CHANNELS_PAULA; i++) {
+               audio_data[i] = &audio_channel[i].data;
+       }
+       audio_total_extra_streams = 0;
+       for (int i = 0; i < AUDIO_CHANNEL_STREAMS; i++) {
+               audio_extra_streams[i] = 0;
+       }
        set_extra_prehandler();
 
        if (currprefs.produce_sound == 0) {
@@ -1880,10 +1935,14 @@ void update_audio (void)
                unsigned long rounded;
                int i;
 
-               for (i = 0; i < audio_channel_count; i++) {
+               for (i = 0; i < AUDIO_CHANNELS_PAULA; i++) {
                        if (audio_channel[i].evtime != MAX_EV && best_evtime > audio_channel[i].evtime)
                                best_evtime = audio_channel[i].evtime;
                }
+               for (i = 0; i < audio_total_extra_streams; i++) {
+                       if (audio_stream[i].evtime != MAX_EV && best_evtime > audio_stream[i].evtime)
+                               best_evtime= audio_stream[i].evtime;
+               }
 
                /* next_sample_evtime >= 0 so floor() behaves as expected */
                rounded = floorf (next_sample_evtime);
@@ -1906,10 +1965,14 @@ void update_audio (void)
                                extra_sample_prehandler(best_evtime / CYCLE_UNIT);
                }
 
-               for (i = 0; i < audio_channel_count; i++) {
+               for (i = 0; i < AUDIO_CHANNELS_PAULA; i++) {
                        if (audio_channel[i].evtime != MAX_EV)
                                audio_channel[i].evtime -= best_evtime;
                }
+               for (i = 0; i < audio_total_extra_streams; i++) {
+                       if (audio_stream[i].evtime != MAX_EV)
+                               audio_stream[i].evtime -= best_evtime;
+               }
 
                n_cycles -= best_evtime;
 
@@ -1945,13 +2008,14 @@ void update_audio (void)
                        }
                }
 
-               for (i = 0; i < audio_channel_count; i++) {
+               for (i = 0; i < AUDIO_CHANNELS_PAULA; i++) {
                        if (audio_channel[i].evtime == 0) {
                                audio_state_channel (i, true);
-                               if (audio_channel[i].evtime == 0) {
-                                       write_log (_T("evtime==0 sound bug channel %d\n"), i);
-                                       audio_channel[i].evtime = MAX_EV;
-                               }
+                       }
+               }
+               for (i = 0; i < audio_total_extra_streams; i++) {
+                       if (audio_stream[i].evtime == 0) {
+                               audio_state_channel(i + AUDIO_CHANNELS_PAULA, true);
                        }
                }
        }
@@ -1971,7 +2035,7 @@ void audio_hsync (void)
                return;
        if (!isaudio ())
                return;
-       if (audio_work_to_do > 0 && currprefs.sound_auto && !audio_extra_channels[0] && !audio_extra_channels[1]
+       if (audio_work_to_do > 0 && currprefs.sound_auto && !audio_total_extra_streams
 #ifdef AVIOUTPUT
                        && !avioutput_enabled
 #endif
@@ -2148,7 +2212,7 @@ void AUDxVOL (int nr, uae_u16 v)
                v = 64;
        audio_activate ();
        update_audio ();
-       cdp->vol = v;
+       cdp->data.vol = v;
 #if DEBUG_AUDIO > 0
        if (debugchannel (nr))
                write_log (_T("AUD%dVOL: %d %08X\n"), nr, v, M68K_GETPC);
@@ -2160,10 +2224,10 @@ void audio_update_adkmasks (void)
        static int prevcon = -1;
        unsigned long t = adkcon | (adkcon >> 4);
 
-       audio_channel[0].adk_mask = (((t >> 0) & 1) - 1);
-       audio_channel[1].adk_mask = (((t >> 1) & 1) - 1);
-       audio_channel[2].adk_mask = (((t >> 2) & 1) - 1);
-       audio_channel[3].adk_mask = (((t >> 3) & 1) - 1);
+       audio_channel[0].data.adk_mask = (((t >> 0) & 1) - 1);
+       audio_channel[1].data.adk_mask = (((t >> 1) & 1) - 1);
+       audio_channel[2].data.adk_mask = (((t >> 2) & 1) - 1);
+       audio_channel[3].data.adk_mask = (((t >> 3) & 1) - 1);
        if ((prevcon & 0xff) != (adkcon & 0xff)) {
                audio_activate ();
 #if DEBUG_AUDIO > 0
@@ -2235,7 +2299,7 @@ uae_u8 *restore_audio (int nr, uae_u8 *src)
 
        zerostate (nr);
        acd->state = restore_u8 ();
-       acd->vol = restore_u8 ();
+       acd->data.vol = restore_u8 ();
        acd->intreq2 = restore_u8 () ? true : false;
        uae_u8 flags = restore_u8 ();
        acd->dr = acd->dsr = false;
@@ -2269,7 +2333,7 @@ uae_u8 *save_audio (int nr, int *len, uae_u8 *dstptr)
        else
                dstbak = dst = xmalloc (uae_u8, 100);
        save_u8 (acd->state);
-       save_u8 (acd->vol);
+       save_u8 (acd->data.vol);
        save_u8 (acd->intreq2);
        save_u8 ((acd->dr ? 1 : 0) | (acd->dsr ? 2 : 0) | 0x80);
        save_u16 (acd->len);
@@ -2286,48 +2350,68 @@ uae_u8 *save_audio (int nr, int *len, uae_u8 *dstptr)
 
 static void audio_set_extra_channels(void)
 {
-       audio_channel_count = audio_extra_channels[1] ? AUDIO_CHANNELS_PAULA + 4 : (audio_extra_channels[0] ? AUDIO_CHANNELS_PAULA + 2 : AUDIO_CHANNELS_PAULA);
+       int index = AUDIO_CHANNELS_PAULA;
+       audio_total_extra_streams = 0;
+       for (int i = 0; i < AUDIO_CHANNEL_STREAMS; i++) {
+               if (audio_extra_streams[i])
+                       audio_total_extra_streams++;
+               for (int j = 0; j < audio_extra_streams[i]; j++) {
+                       audio_data[index++] = &audio_stream[i].data[j];
+               }
+       }
        set_extra_prehandler();
 }
 
-void audio_enable_sndboard(bool enable)
+int audio_enable_stream(bool enable, int streamid, int ch)
 {
-       struct audio_channel_data *acd = audio_channel + AUDIO_CHANNEL_SNDBOARD_LEFT;
+       if (streamid == 0)
+               return 0;
        if (!enable) {
-               audio_extra_channels[0] = false;
-               acd[1].evtime = acd->evtime = MAX_EV;
+               if (streamid <= 0)
+                       return 0;
+               streamid--;
+               struct audio_stream_data *asd = audio_stream + streamid;
+               audio_extra_streams[streamid] = 0;
+               asd->evtime = MAX_EV;
        } else {
-               audio_extra_channels[0] = true;
-               acd[1].evtime = acd->evtime = CYCLE_UNIT;
-               acd[1].adk_mask = acd->adk_mask = 0xffffffff;
-               acd[1].vol = acd->vol = 1;
+               if (streamid < 0) {
+                       for (int i = 0; i < AUDIO_CHANNEL_STREAMS; i++) {
+                               if (!audio_extra_streams[i]) {
+                                       streamid = i;
+                                       break;
+                               }
+                       }
+                       if (streamid < 0)
+                               return 0;
+               }
+               audio_extra_streams[streamid] = ch;
+               struct audio_stream_data *asd = audio_stream + streamid;
+               asd->evtime = CYCLE_UNIT;
+               for (int i = 0; i < ch; i++) {
+                       struct audio_channel_data2 *acd = &asd->data[i];
+                       acd->adk_mask = 0xffffffff;
+                       acd->vol = 1;
+               }
                audio_activate();
        }
        audio_set_extra_channels();
+       return streamid + 1;
 }
 
-static void audio_enable_cda(bool enable)
+void audio_state_stream_state(int streamid, int *samplep, int highestch, unsigned int evt)
 {
-       struct audio_channel_data *acd = audio_channel + AUDIO_CHANNEL_CDA_LEFT;
-       if (!enable) {
-               audio_extra_channels[1] = false;
-               acd[1].evtime = acd->evtime = MAX_EV;
-       } else {
-               audio_extra_channels[1] = true;
-               acd[1].evtime = acd->evtime = CYCLE_UNIT;
-               acd[1].adk_mask = acd->adk_mask = 0xffffffff;
-               acd[1].vol = acd->vol = 1;
-               audio_activate();
+       streamid--;
+       struct audio_stream_data *asd = audio_stream + streamid;
+       if (highestch > audio_extra_streams[streamid]) {
+               audio_extra_streams[streamid] = highestch;
+               audio_set_extra_channels();
        }
-       audio_set_extra_channels();
-}
-
-void audio_state_sndboard_state(int ch, int sample, unsigned int evt)
-{
-       struct audio_channel_data *acd = audio_channel + AUDIO_CHANNEL_SNDBOARD_LEFT + ch;
-       acd->last_sample = acd->current_sample;
-       acd->current_sample = sample;
-       acd->evtime = evt;
+       for (int i = 0; i < audio_extra_streams[streamid]; i++) {
+               struct audio_channel_data2 *acd = &asd->data[i];
+               acd->last_sample = acd->current_sample;
+               acd->current_sample = samplep[i];
+       }
+       asd->evtime = evt;
 }
 
 static uae_s16 *cda_bufptr;
@@ -2336,6 +2420,7 @@ static unsigned int cda_evt;
 static uae_s16 dummy_buffer[4] = { 0 };
 static CDA_CALLBACK cda_next_cd_audio_buffer_callback;
 static int cda_volume[2];
+static int cda_streamid = -1;
 
 void update_cda_sound(double clk)
 {
@@ -2363,8 +2448,8 @@ void audio_cda_new_buffer(uae_s16 *buffer, int length, int userdata, CDA_CALLBAC
                cda_bufptr = buffer;
                cda_length = length;
                cda_userdata = userdata;
-               if (!audio_extra_channels[1])
-                       audio_enable_cda(true);
+               if (cda_streamid <= 0)
+                       cda_streamid = audio_enable_stream(true, -1, 2);
        }
        cda_next_cd_audio_buffer_callback = next_cd_audio_buffer_callback;
        audio_activate();
@@ -2373,17 +2458,21 @@ void audio_cda_new_buffer(uae_s16 *buffer, int length, int userdata, CDA_CALLBAC
 static void audio_state_cda(void)
 {
        if (cda_bufptr >= dummy_buffer && cda_bufptr <= dummy_buffer + 4) {
-               audio_enable_cda(false);
+               audio_enable_stream(false, cda_streamid, 0);
+               cda_streamid = 0;
                return; 
        }
-       struct audio_channel_data *acd = audio_channel + AUDIO_CHANNEL_CDA_LEFT;
+       if (cda_streamid <= 0)
+               return;
+       struct audio_stream_data *asd = audio_stream + cda_streamid;
+       asd->evtime = cda_evt;
+       struct audio_channel_data2 *acd;
+       acd = &asd->data[0];
        acd->last_sample = acd->current_sample;
        acd->current_sample = cda_bufptr[0] * cda_volume[0] / 32768;
-       acd->evtime = cda_evt;
-       acd++;
+       acd = &asd->data[1];
        acd->last_sample = acd->current_sample;
        acd->current_sample = cda_bufptr[1] * cda_volume[1] / 32768;
-       acd->evtime = cda_evt;
        cda_bufptr += 2;
        cda_length--;
        if (cda_length <= 0 && cda_next_cd_audio_buffer_callback) {
index 64b3182707f224e6ec716408a4eb0d4b4877ac82..eeb6ce90d254630061dd21dd0a6d84d019156c01 100644 (file)
@@ -138,12 +138,18 @@ static int REGPARAM2 rtarea_check (uaecptr addr, uae_u32 size)
 static uae_u32 REGPARAM2 rtarea_lget (uaecptr addr)
 {
        addr &= 0xFFFF;
+       if (addr & 1)
+               return 0;
+       if (addr >= 0xfffd)
+               return 0;
        return (rtarea_bank.baseaddr[addr + 0] << 24) | (rtarea_bank.baseaddr[addr + 1] << 16) |
                (rtarea_bank.baseaddr[addr + 2] << 8) | (rtarea_bank.baseaddr[addr + 3] << 0);
 }
 static uae_u32 REGPARAM2 rtarea_wget (uaecptr addr)
 {
        addr &= 0xFFFF;
+       if (addr & 1)
+               return 0;
 
        uaecptr addr2 = addr - RTAREA_TRAP_STATUS;
 
@@ -249,6 +255,9 @@ static void REGPARAM2 rtarea_wput (uaecptr addr, uae_u32 value)
        addr &= 0xffff;
        value &= 0xffff;
 
+       if (addr & 1)
+               return;
+
        if (!rtarea_write(addr))
                return;
 
@@ -290,6 +299,10 @@ static void REGPARAM2 rtarea_wput (uaecptr addr, uae_u32 value)
 static void REGPARAM2 rtarea_lput (uaecptr addr, uae_u32 value)
 {
        addr &= 0xffff;
+       if (addr & 1)
+               return;
+       if (addr >= 0xfffd)
+               return;
        if (!rtarea_write(addr))
                return;
        rtarea_bank.baseaddr[addr + 0] = value >> 24;
@@ -527,7 +540,7 @@ static uae_u32 REGPARAM2 uae_puts (TrapContext *ctx)
 
 void rtarea_init_mem (void)
 {
-       if (need_uae_boot_rom()) {
+       if (need_uae_boot_rom(&currprefs)) {
                rtarea_bank.flags &= ~ABFLAG_ALLOCINDIRECT;
        } else {
                rtarea_bank.flags |= ABFLAG_ALLOCINDIRECT;
@@ -620,7 +633,7 @@ volatile uae_atomic uae_int_requested = 0;
 
 void rtarea_setup (void)
 {
-       uaecptr base = need_uae_boot_rom ();
+       uaecptr base = need_uae_boot_rom (&currprefs);
        if (base) {
                write_log (_T("RTAREA located at %08X\n"), base);
                rtarea_base = base;
index 05b9732674e323dbc949238311fcc83777fcc8f4..06512efdc1003e0689cd53de703bbb75919860dc 100644 (file)
@@ -1009,7 +1009,7 @@ struct device_info *sys_command_info (int unitnum, struct device_info *di, int q
        struct device_info *dix;
 
        dix = sys_command_info_session (unitnum, di, quick, -1);
-       if (dix && dix->media_inserted && !quick) {
+       if (dix && dix->media_inserted && !quick && !dix->audio_playing) {
                TCHAR *name = NULL;
                uae_u8 buf[2048];
                if (sys_command_cd_read(unitnum, buf, 16, 1)) {
index 9a9506ce573707593fb9d079ec714eacfda5863a..2aa4bd510395fdb6841b3c7d8090819855eafa58 100644 (file)
@@ -373,11 +373,11 @@ static void dosub (struct cdunit *cdu, uae_u8 *subbuf)
        cdu->cdda_subfunc (subbuf2, 1);
 }
 
-static int setstate (struct cdunit *cdu, int state)
+static int setstate (struct cdunit *cdu, int state, int playpos)
 {
        cdu->cdda_play_state = state;
        if (cdu->cdda_statusfunc)
-               return cdu->cdda_statusfunc (cdu->cdda_play_state);
+               return cdu->cdda_statusfunc (cdu->cdda_play_state, playpos);
        return 0;
 }
 
@@ -501,7 +501,7 @@ static void *cdda_play_func (void *v)
                                t = findtoc (cdu, &sector, false);
                                if (!t) {
                                        write_log (_T("IMAGE CDDA: illegal sector number %d\n"), cdu->cdda_start);
-                                       setstate (cdu, AUDIO_STATUS_PLAY_ERROR);
+                                       setstate (cdu, AUDIO_STATUS_PLAY_ERROR, -1);
                                } else {
                                        audio_unpack (cdu, t);
                                }
@@ -550,7 +550,7 @@ static void *cdda_play_func (void *v)
                        diff -= cdu->cdda_delay;
                        if (idleframes >= 0 && diff < 0 && cdu->cdda_play > 0)
                                sleep_millis(-diff);
-                       setstate (cdu, AUDIO_STATUS_IN_PROGRESS);
+                       setstate (cdu, AUDIO_STATUS_IN_PROGRESS, cdda_pos);
 
                        sector = cdda_pos;
                        struct cdtoc *t1 = findtoc (cdu, &sector, false);
@@ -579,7 +579,7 @@ static void *cdda_play_func (void *v)
                        goto end;
 
                if (idleframes <= 0 && cdda_pos >= cdu->cdda_start && !isaudiotrack (&cdu->di.toc, cdda_pos)) {
-                       setstate (cdu, AUDIO_STATUS_PLAY_ERROR);
+                       setstate (cdu, AUDIO_STATUS_PLAY_ERROR, -1);
                        write_log (_T("IMAGE CDDA: attempted to play data track %d\n"), cdda_pos);
                        goto end; // data track?
                }
@@ -591,6 +591,8 @@ static void *cdda_play_func (void *v)
 
                        gui_flicker_led (LED_CD, cdu->di.unitnum - 1, LED_CD_AUDIO);
 
+                       setstate(cdu, AUDIO_STATUS_IN_PROGRESS, cdda_pos);
+
                        memset (cda->buffers[bufnum], 0, CDDA_BUFFERS * 2352);
 
                        for (cnt = 0; cnt < CDDA_BUFFERS && cdu->cdda_play > 0; cnt++) {
@@ -681,16 +683,16 @@ static void *cdda_play_func (void *v)
                                cda->setvolume (cdu->cdda_volume[0], cdu->cdda_volume[1]);
                                if (!cda->play (bufnum)) {
                                        if (cdu->cdda_play > 0)
-                                               setstate (cdu, AUDIO_STATUS_PLAY_ERROR);
+                                               setstate (cdu, AUDIO_STATUS_PLAY_ERROR, -1);
                                        goto end;
                                }
                        }
 
                        if (dofinish) {
+                               cdda_pos = cdu->cdda_end + 1;
                                if (cdu->cdda_play >= 0)
-                                       setstate (cdu, AUDIO_STATUS_PLAY_COMPLETE);
+                                       setstate (cdu, AUDIO_STATUS_PLAY_COMPLETE, cdda_pos);
                                cdu->cdda_play = -1;
-                               cdda_pos = cdu->cdda_end + 1;
                        }
 
                }
@@ -774,11 +776,11 @@ static int command_play (int unitnum, int startlsn, int endlsn, int scan, play_s
        cdu->cdda_subfunc = subfunc;
        cdu->cdda_statusfunc = statusfunc;
        cdu->cdda_scan = scan > 0 ? 10 : (scan < 0 ? 10 : 0);
-       cdu->cdda_delay = setstate (cdu, -1);
-       cdu->cdda_delay_frames = setstate (cdu, -2);
-       setstate (cdu, AUDIO_STATUS_NOT_SUPPORTED);
+       cdu->cdda_delay = setstate (cdu, -1, -1);
+       cdu->cdda_delay_frames = setstate (cdu, -2, -1);
+       setstate (cdu, AUDIO_STATUS_NOT_SUPPORTED, -1);
        if (!isaudiotrack (&cdu->di.toc, startlsn)) {
-               setstate (cdu, AUDIO_STATUS_PLAY_ERROR);
+               setstate (cdu, AUDIO_STATUS_PLAY_ERROR, -1);
                return 0;
        }
        if (!cdu->thread_active) {
@@ -2099,6 +2101,7 @@ static struct device_info *info_device (int unitnum, struct device_info *di, int
        if (ismedia (unitnum, 1)) {
                di->media_inserted = 1;
                _tcscpy (di->mediapath, cdu->imgname);
+               di->audio_playing = cdu->cdda_play > 0;
        }
        memset (&di->toc, 0, sizeof (struct cd_toc_head));
        command_toc (unitnum, &di->toc);
index 545b6251af8375f71db4569c8a0293dd1b7fd23d..5724c21a99abc8b9aec1759b56ede94e447f1a31 100644 (file)
@@ -329,7 +329,7 @@ DECLARE_MEMORY_FUNCTIONS(fmv_rom);
 static addrbank fmv_rom_bank = {
        fmv_rom_lget, fmv_rom_wget, fmv_rom_bget,
        fmv_rom_lput, fmv_rom_wput, fmv_rom_bput,
-       fmv_rom_xlate, fmv_rom_check, NULL, _T("fmv_rom"), _T("CD32 FMV ROM"),
+       fmv_rom_xlate, fmv_rom_check, NULL, _T("*"), _T("CD32 FMV ROM"),
        fmv_rom_lget, fmv_rom_wget,
        ABFLAG_ROM, S_READ, S_WRITE
 };
@@ -338,7 +338,7 @@ DECLARE_MEMORY_FUNCTIONS(fmv_ram);
 static addrbank fmv_ram_bank = {
        fmv_ram_lget, fmv_ram_wget, fmv_ram_bget,
        fmv_ram_lput, fmv_ram_wput, fmv_ram_bput,
-       fmv_ram_xlate, fmv_ram_check, NULL, _T("fmv_ram"), _T("CD32 FMV RAM"),
+       fmv_ram_xlate, fmv_ram_check, NULL, _T("*"), _T("CD32 FMV RAM"),
        fmv_ram_lget, fmv_ram_wget,
        ABFLAG_RAM, S_READ, S_WRITE
 };
@@ -1546,42 +1546,28 @@ void cd32_fmv_free(void)
        l64111_reset();
 }
 
-addrbank *cd32_fmv_init (uaecptr start)
+addrbank *cd32_fmv_init (struct autoconfig_info *aci)
 {
-       struct zfile *z;
-
        cd32_fmv_free();
-       write_log (_T("CD32 FMV mapped @$%x\n"), start);
-       if (start != fmv_start) {
-               write_log(_T("CD32 FMV invalid base address!\n"));
-               return &expamem_null;
+       write_log (_T("CD32 FMV mapped @$%x\n"), expamem_board_pointer);
+       if (expamem_board_pointer != fmv_start) {
+               write_log(_T("CD32 FMV unexpected base address!\n"));
        }
-       if (!validate_banks_z2(&fmv_bank, fmv_start >> 16, expamem_z2_size >> 16))
+       if (!validate_banks_z2(&fmv_bank, expamem_board_pointer >> 16, expamem_board_size >> 16))
                return &expamem_null;
 
-       z = read_rom_name(currprefs.cartfile);
-       if (!z) {
-               int ids[] = { 74, 23, -1 };
-               struct romdata *rd;
-               struct romlist *rl = getromlistbyids (ids, NULL);
-               if (rl) {
-                       rd = rl->rd;
-                       write_log (_T("CD32 FMV ROM %d.%d\n"), rd->ver, rd->rev);
-                       z = read_rom (rd);
-               }
-       }
+       fmv_rom_bank.start = expamem_board_pointer;
+       fmv_ram_bank.start = fmv_rom_bank.start + 0x80000;
+
        fmv_rom_bank.mask = fmv_rom_size - 1;
        fmv_rom_bank.allocated = fmv_rom_size;
        fmv_ram_bank.mask = fmv_ram_size - 1;
        fmv_ram_bank.allocated = fmv_ram_size;
 
-       if (z) {
-               if (mapped_malloc(&fmv_rom_bank)) {
-                       int size = zfile_size(z);
-                       zfile_fread (fmv_rom_bank.baseaddr, size > fmv_rom_size ? fmv_rom_size : size, 1, z);
-               }
-               zfile_fclose (z);
+       if (mapped_malloc(&fmv_rom_bank)) {
+               load_rom_rc(aci->rc, ROMTYPE_CD32CART, 262144, 0, fmv_rom_bank.baseaddr, 262144, 0);
        }
+
        if (!fmv_rom_bank.baseaddr) {
                write_log(_T("CD32 FMV without ROM is not supported.\n"));
                return &expamem_null;
index 8d8065e7a96c3e1a68283e7dfc79cadad4b67302..150d9757cd43a2a4c0ac4a723bc5467b6e4d99ea 100644 (file)
--- a/cdtv.cpp
+++ b/cdtv.cpp
@@ -62,7 +62,8 @@ static smp_comm_pipe requests;
 static volatile int thread_alive;
 
 static int configured;
-static uae_u8 dmacmemory[100];
+static int cdtvscsi;
+static uae_u8 dmacmemory[128];
 
 static struct cd_toc_head toc;
 static uae_u32 last_cd_position, play_start, play_end;
@@ -258,7 +259,7 @@ static void subfunc (uae_u8 *data, int cnt)
        subcodebufferoffsetw = offset;
        uae_sem_post (&sub_sem);
 }
-static int statusfunc (int status)
+static int statusfunc (int status, int playpos)
 {
        if (status == -1)
                return 500;
@@ -273,6 +274,8 @@ static int statusfunc (int status)
                        activate_stch = 1;
                }
        }
+       if (status == AUDIO_STATUS_IN_PROGRESS)
+               last_play_pos = playpos;
        cd_audio_status = status;
        return 0;
 }
@@ -1066,7 +1069,7 @@ static void checkint (void)
 {
        int irq = 0;
 
-       if (currprefs.cs_cdtvscsi && (wdscsi_getauxstatus (&wd_cdtv->wc) & 0x80)) {
+       if (cdtvscsi && (wdscsi_getauxstatus (&wd_cdtv->wc) & 0x80)) {
                dmac_istr |= ISTR_INTS;
                if ((dmac_cntr & CNTR_INTEN) && (dmac_istr & ISTR_INTS))
                        irq = 1;
@@ -1257,11 +1260,11 @@ static uae_u32 dmac_bget2 (uaecptr addr)
                v = dmac_cntr;
                break;
        case 0x91:
-               if (currprefs.cs_cdtvscsi)
+               if (cdtvscsi)
                        v = wdscsi_getauxstatus (&wd_cdtv->wc);
                break;
        case 0x93:
-               if (currprefs.cs_cdtvscsi) {
+               if (cdtvscsi) {
                        v = wdscsi_get (&wd_cdtv->wc, wd_cdtv);
                        checkint ();
                }
@@ -1364,13 +1367,13 @@ static void dmac_bput2 (uaecptr addr, uae_u32 b)
                dmac_dawr |= b << 0;
                break;
        case 0x91:
-               if (currprefs.cs_cdtvscsi) {
+               if (cdtvscsi) {
                        wdscsi_sasr (&wd_cdtv->wc, b);
                        checkint ();
                }
                break;
        case 0x93:
-               if (currprefs.cs_cdtvscsi) {
+               if (cdtvscsi) {
                        wdscsi_put (&wd_cdtv->wc, wd_cdtv, b);
                        checkint ();
                }
@@ -1625,8 +1628,28 @@ void cdtv_free (void)
        configured = 0;
 }
 
-addrbank *cdtv_init (struct romconfig *rc)
+bool cdtv_init (struct autoconfig_info *aci)
 {
+       memset(dmacmemory, 0xff, sizeof dmacmemory);
+       ew(0x00, 0xc0 | 0x01);
+       ew(0x04, 0x03);
+       ew(0x08, 0x40);
+       ew(0x10, 0x02);
+       ew(0x14, 0x02);
+
+       ew(0x18, 0x00); /* ser.no. Byte 0 */
+       ew(0x1c, 0x00); /* ser.no. Byte 1 */
+       ew(0x20, 0x00); /* ser.no. Byte 2 */
+       ew(0x24, 0x00); /* ser.no. Byte 3 */
+
+       if (aci) {
+               aci->label = dmac_bank.name;
+               if (!aci->doinit) {
+                       memcpy(aci->autoconfig_raw, dmacmemory, sizeof dmacmemory);
+                       return true;
+               }
+       }
+
        close_unit ();
        if (!thread_alive) {
                init_comm_pipe (&requests, 100, 1);
@@ -1639,17 +1662,6 @@ addrbank *cdtv_init (struct romconfig *rc)
 
        cdrom_command_cnt_out = -1;
        cmd = enable = xaen = dten = 0;
-       memset (dmacmemory, 0xff, 100);
-       ew (0x00, 0xc0 | 0x01);
-       ew (0x04, 0x03);
-       ew (0x08, 0x40);
-       ew (0x10, 0x02);
-       ew (0x14, 0x02);
-
-       ew (0x18, 0x00); /* ser.no. Byte 0 */
-       ew (0x1c, 0x00); /* ser.no. Byte 1 */
-       ew (0x20, 0x00); /* ser.no. Byte 2 */
-       ew (0x24, 0x00); /* ser.no. Byte 3 */
 
        /* KS autoconfig handles the rest */
        if (!savestate_state) {
@@ -1661,22 +1673,28 @@ addrbank *cdtv_init (struct romconfig *rc)
                sten = 0;
                scor = 0;
                sbcp = 0;
+               cdtvscsi = 0;
        }
 
        cdtv_battram_reset ();
        open_unit ();
        gui_flicker_led (LED_CD, 0, -1);
-       if (currprefs.cs_cdtvscsi) {
-               init_wd_scsi (wd_cdtv);
-               wd_cdtv->dmac_type = COMMODORE_DMAC;
-       }
-       return &dmac_bank;
+       if (aci)
+               aci->addrbank = &dmac_bank;
+       return true;
 }
 
-void cdtv_check_banks (void)
+bool cdtvscsi_init(struct autoconfig_info *aci)
 {
+       aci->parent_name = _T("CDTV DMAC");
+       if (!aci->doinit)
+               return true;
+       cdtvscsi = true;
+       init_wd_scsi(wd_cdtv);
+       wd_cdtv->dmac_type = COMMODORE_DMAC;
        if (configured > 0)
-               map_banks_z2 (&dmac_bank, configured, 0x10000 >> 16);
+               map_banks_z2(&dmac_bank, configured, 0x10000 >> 16);
+       return true;
 }
 
 #ifdef SAVESTATE
@@ -1775,7 +1793,7 @@ uae_u8 *restore_cdtv (uae_u8 *src)
        if (!currprefs.cs_cdtvcd) {
                changed_prefs.cs_cdtvcd = changed_prefs.cs_cdtvram = true;
                currprefs.cs_cdtvcd = currprefs.cs_cdtvram = true;
-               cdtv_init (0);
+               cdtv_init(NULL);
        }
        restore_u32 ();
        
index a5d76a017d0ecc5b3f61d6e23907c3142744bbba..972c045a6e2522361b3c7bb90b52a26bb1bd2a2c 100644 (file)
@@ -421,7 +421,7 @@ static void subfunc(uae_u8 *data, int cnt)
        uae_sem_post(&sub_sem);
 }
 
-static int statusfunc(int status)
+static int statusfunc(int status, int playpos)
 {
        if (status == -1)
                return 75;
@@ -842,7 +842,7 @@ static void REGPARAM2 cdtvcr_bput (uaecptr addr, uae_u32 b)
 }
 
 
-addrbank cdtvcr_bank = {
+static addrbank cdtvcr_bank = {
        cdtvcr_lget, cdtvcr_wget, cdtvcr_bget,
        cdtvcr_lput, cdtvcr_wput, cdtvcr_bput,
        default_xlate, default_check, NULL, NULL, _T("CDTV-CR"),
@@ -988,6 +988,17 @@ static void close_unit (void)
        unitnum = -1;
 }
 
+bool cdtvcr_init(struct autoconfig_info *aci)
+{
+       aci->start = 0xb80000;
+       aci->size = 0x10000;
+       aci->addrbank = &expamem_nonautoconfig;
+       if (!aci->doinit)
+               return true;
+       map_banks(&cdtvcr_bank, 0xB8, 1, 0);
+       return true;
+}
+
 void cdtvcr_reset(void)
 {
        if (!currprefs.cs_cdtvcr)
index 3a8d85bf11dfde762bd76f39972eb79c113c681a..6dd54e729991e55459d4ed5a130b3b3785408ed8 100644 (file)
@@ -240,20 +240,24 @@ static const TCHAR *lacer[] = { _T("off"), _T("i"), _T("p"), 0 };
 /* another boolean to choice update.. */
 static const TCHAR *cycleexact[] = { _T("false"), _T("memory"), _T("true"), 0  };
 
-static const TCHAR *hdcontrollers[] = {
-       _T("uae"),
+struct hdcontrollerconfig
+{
+       const TCHAR *label;
+       int romtype;
+};
 
-       _T("ide%d"),
-       _T("ide%d_mainboard"),
+static const struct hdcontrollerconfig hdcontrollers[] = {
+       { _T("uae"), 0 },
 
-       _T("scsi%d"),
-       _T("scsi%d_a3000"),
-       _T("scsi%d_a4000t"),
-       _T("scsi%d_cdtv"),
+       { _T("ide%d"), 0 },
+       { _T("ide%d_mainboard"), ROMTYPE_MB_IDE },
 
-       _T("scsram"),
-       _T("scide"),
-       NULL
+       { _T("scsi%d"), 0 },
+       { _T("scsi%d_a3000"), ROMTYPE_SCSI_A3000 },
+       { _T("scsi%d_a4000t"), ROMTYPE_SCSI_A4000T },
+       { _T("scsi%d_cdtv"), ROMTYPE_CDTVSCSI },
+
+       { NULL }
 };
 static const TCHAR *z3mapping[] = {
        _T("auto"),
@@ -558,7 +562,7 @@ static TCHAR *cfgfile_subst_path2 (const TCHAR *path, const TCHAR *subst, const
                        l++;
                _tcscat (p, _T("/"));
                _tcscat (p, file + l);
-               p2 = target_expand_environment (p);
+               p2 = target_expand_environment (p, NULL, 0);
                xfree (p);
                return p2;
        }
@@ -570,7 +574,7 @@ TCHAR *cfgfile_subst_path (const TCHAR *path, const TCHAR *subst, const TCHAR *f
        TCHAR *s = cfgfile_subst_path2 (path, subst, file);
        if (s)
                return s;
-       s = target_expand_environment (file);
+       s = target_expand_environment (file, NULL, 0);
        if (s) {
                TCHAR tmp[MAX_DPATH];
                _tcscpy (tmp, s);
@@ -879,10 +883,9 @@ static void cfgfile_dwrite_path (struct zfile *f, struct multipath *mp, const TC
 
 static void write_filesys_config (struct uae_prefs *p, struct zfile *f)
 {
-       int i;
        TCHAR tmp[MAX_DPATH], tmp2[MAX_DPATH], tmp3[MAX_DPATH], hdcs[MAX_DPATH];
 
-       for (i = 0; i < p->mountitems; i++) {
+       for (int i = 0; i < p->mountitems; i++) {
                struct uaedev_config_data *uci = &p->mountconfig[i];
                struct uaedev_config_info *ci = &uci->ci;
                TCHAR *str1, *str1b, *str2b;
@@ -906,18 +909,32 @@ static void write_filesys_config (struct uae_prefs *p, struct zfile *f)
                        str1 = cfgfile_put_multipath (&p->path_hardfile, ci->rootdir);
                }
                int ct = ci->controller_type;
+               int romtype = 0;
                if (ct >= HD_CONTROLLER_TYPE_SCSI_EXPANSION_FIRST && ct <= HD_CONTROLLER_TYPE_SCSI_LAST) {
                        _stprintf(hdcs, _T("scsi%d_%s"), ci->controller_unit, expansionroms[ct - HD_CONTROLLER_TYPE_SCSI_EXPANSION_FIRST].name);
+                       romtype = expansionroms[ct - HD_CONTROLLER_TYPE_SCSI_EXPANSION_FIRST].romtype;
                } else if (ct >= HD_CONTROLLER_TYPE_IDE_EXPANSION_FIRST && ct <= HD_CONTROLLER_TYPE_IDE_LAST) {
                        _stprintf(hdcs, _T("ide%d_%s"), ci->controller_unit, expansionroms[ct - HD_CONTROLLER_TYPE_IDE_EXPANSION_FIRST].name);
+                       romtype = expansionroms[ct - HD_CONTROLLER_TYPE_IDE_EXPANSION_FIRST].romtype;
                } else if (ct >= HD_CONTROLLER_TYPE_SCSI_FIRST && ct < HD_CONTROLLER_TYPE_SCSI_EXPANSION_FIRST) {
-                       _stprintf(hdcs, hdcontrollers[ct - HD_CONTROLLER_EXPANSION_MAX], ci->controller_unit);
-               } else if (ct >= HD_CONTROLLER_TYPE_PCMCIA_SRAM && ct <= HD_CONTROLLER_TYPE_PCMCIA_IDE) {
-                       _stprintf(hdcs, hdcontrollers[ct - 2 * HD_CONTROLLER_EXPANSION_MAX], ci->controller_unit);
+                       _stprintf(hdcs, hdcontrollers[ct - HD_CONTROLLER_EXPANSION_MAX].label, ci->controller_unit);
+               } else if (ct == HD_CONTROLLER_TYPE_PCMCIA) {
+                       if (ci->controller_type_unit == 0)
+                               _tcscpy(hdcs, _T("scsram"));
+                       else
+                               _tcscpy(hdcs, _T("scide"));
                } else {
-                       _stprintf(hdcs, hdcontrollers[ct], ci->controller_unit);
+                       _stprintf(hdcs, hdcontrollers[ct].label, ci->controller_unit);
                }
-               if (ci->controller_type_unit > 0)
+               if (romtype) {
+                       for (int j = 0; hdcontrollers[j].label; j++) {
+                               if (hdcontrollers[j].romtype == (romtype & ROMTYPE_MASK)) {
+                                       _stprintf(hdcs, hdcontrollers[j].label, ci->controller_unit);
+                                       break;
+                               }
+                       }
+               }
+               if (ci->controller_type_unit > 0 && ct != HD_CONTROLLER_TYPE_PCMCIA)
                        _stprintf(hdcs + _tcslen(hdcs), _T("-%d"), ci->controller_type_unit + 1);
 
                str1b = cfgfile_escape (str1, _T(":,"), true);
@@ -1196,7 +1213,7 @@ static void cfgfile_write_board_rom(struct zfile *f, struct multipath *mp, struc
                                _stprintf(buf, _T("%s%s_rom"), name, i ? _T("_ext") : _T(""));
                                cfgfile_dwrite_str (f, buf, br->roms[i].romident);
                        }
-                       if (br->roms[i].autoboot_disabled || ert->subtypes || ert->settings || ert->id_jumper) {
+                       if (br->roms[i].autoboot_disabled || ert->subtypes || ert->settings || ert->id_jumper || br->device_order > 0) {
                                TCHAR buf2[256], *p;
                                buf2[0] = 0;
                                p = buf2;
@@ -1210,6 +1227,11 @@ static void cfgfile_write_board_rom(struct zfile *f, struct multipath *mp, struc
                                        }
                                        _stprintf(p, _T("subtype=%s"), srt->configname);
                                }
+                               if (br->device_order > 0) {
+                                       if (buf2[0])
+                                               _tcscat(buf2, _T(","));
+                                       _stprintf(buf2, _T("order=%d"), br->device_order);
+                               }
                                if (br->roms[i].autoboot_disabled) {
                                        if (buf2[0])
                                                _tcscat(buf2, _T(","));
@@ -1237,6 +1259,100 @@ static void cfgfile_write_board_rom(struct zfile *f, struct multipath *mp, struc
        }
 }
 
+static bool cfgfile_readramboard(const TCHAR *option, const TCHAR *value, const TCHAR *name, struct ramboard *rbp)
+{
+       TCHAR tmp1[MAX_DPATH];
+       int v;
+       for (int i = 0; i < MAX_RAM_BOARDS; i++) {
+               struct ramboard *rb = &rbp[i];
+               if (i > 0)
+                       _stprintf(tmp1, _T("%s%d_size"), name, i + 1);
+               else
+                       _stprintf(tmp1, _T("%s_size"), name);
+               if (!_tcsicmp(option, tmp1)) {
+                       v = 0;
+                       cfgfile_intval(option, value, tmp1, &v, 0x100000);
+                       rb->size = v;
+                       return true;
+               }
+               if (i > 0)
+                       _stprintf(tmp1, _T("%s%d_size_k"), name, i + 1);
+               else
+                       _stprintf(tmp1, _T("%s_size_k"), name);
+               if (!_tcsicmp(option, tmp1)) {
+                       v = 0;
+                       cfgfile_intval(option, value, tmp1, &v, 1024);
+                       rb->size = v;
+                       return true;
+               }
+               if (i > 0)
+                       _stprintf(tmp1, _T("%s%d_options"), name, i + 1);
+               else
+                       _stprintf(tmp1, _T("%s_options"), name);
+               if (!_tcsicmp(option, tmp1)) {
+                       TCHAR *s;
+                       s = cfgfile_option_get(value, _T("order"));
+                       if (s)
+                               rb->device_order = _tstol(s);
+                       s = cfgfile_option_get(value, _T("mid"));
+                       if (s)
+                               rb->manufacturer = _tstol(s);
+                       s = cfgfile_option_get(value, _T("pid"));
+                       if (s)
+                               rb->product = _tstol(s);
+                       s = cfgfile_option_get(value, _T("data"));
+                       if (s && _tcslen(s) >= 3 * 16 - 1) {
+                               rb->autoconfig_inuse = true;
+                               for (int i = 0; i < sizeof rb->autoconfig; i++) {
+                                       TCHAR *s2 = &s[i * 3];
+                                       if (i + 1 < sizeof rb->autoconfig && s2[2] != '.')
+                                               break;
+                                       TCHAR *endptr;
+                                       s[2] = 0;
+                                       rb->autoconfig[i] = (uae_u8)_tcstol(s2, &endptr, 16);
+                               }
+                       }
+                       return true;
+               }
+       }
+       return false;
+}
+
+static void cfgfile_writeramboard(struct zfile *f, const TCHAR *name, int num, struct ramboard *rb)
+{
+       TCHAR tmp1[MAX_DPATH], tmp2[MAX_DPATH];
+       if (num > 0)
+               _stprintf(tmp1, _T("%s%d_options"), name, num);
+       else
+               _stprintf(tmp1, _T("%s_options"), name);
+       tmp2[0] = 0;
+       TCHAR *p = tmp2;
+       if (rb->device_order > 0) {
+               if (tmp2[0])
+                       *p++ = ',';
+               _stprintf(p, _T("order=%d"), rb->device_order);
+               p += _tcslen(p);
+       }
+       if (rb->manufacturer) {
+               if (tmp2[0])
+                       *p++ = ',';
+               _stprintf(p, _T("mid=%u,pid=%u"), rb->manufacturer, rb->product);
+               p += _tcslen(p);
+       }
+       if (rb->autoconfig_inuse) {
+               uae_u8 *ac = rb->autoconfig;
+               if (tmp2[0])
+                       *p++ = ',';
+               _stprintf(p, _T("data=%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x"),
+                       ac[0], ac[1], ac[2], ac[3], ac[4], ac[5], ac[6], ac[7],
+                       ac[8], ac[9], ac[10], ac[11], ac[12], ac[13], ac[14], ac[15]);
+               p += _tcslen(p);
+       }
+       if (tmp2[0]) {
+               cfgfile_write(f, tmp1, tmp2);
+       }
+}
+
 void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
 {
        struct strlist *sl;
@@ -1534,6 +1650,7 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
        cfgfile_write (f, _T("maprom"), _T("0x%x"), p->maprom);
        cfgfile_dwrite_str (f, _T("boot_rom_uae"), uaebootrom[p->boot_rom]);
        cfgfile_dwrite_str(f, _T("uaeboard"), uaeboard[p->uaeboard]);
+       cfgfile_dwrite(f, _T("uaeboard_options"), _T("order=%d"), p->uaeboard_order);
        cfgfile_dwrite_str (f, _T("parallel_matrix_emulation"), epsonprinter[p->parallel_matrix_emulation]);
        cfgfile_write_bool (f, _T("parallel_postscript_emulation"), p->parallel_postscript_emulation);
        cfgfile_write_bool (f, _T("parallel_postscript_detection"), p->parallel_postscript_detection);
@@ -1809,19 +1926,14 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
        cfgfile_dwrite_bool(f, _T("cd32c2p"), p->cs_cd32c2p);
        cfgfile_dwrite_bool(f, _T("cd32nvram"), p->cs_cd32nvram);
        cfgfile_dwrite(f, _T("cd32nvram_size"), _T("%d"), p->cs_cd32nvram_size / 1024);
-       cfgfile_dwrite_bool(f, _T("cd32fmv"), p->cs_cd32fmv);
        cfgfile_dwrite_bool(f, _T("cdtvcd"), p->cs_cdtvcd);
        cfgfile_dwrite_bool(f, _T("cdtv-cr"), p->cs_cdtvcr);
        cfgfile_dwrite_bool(f, _T("cdtvram"), p->cs_cdtvram);
        cfgfile_dwrite(f, _T("cdtvramcard"), _T("%d"), p->cs_cdtvcard);
-       cfgfile_dwrite_str(f, _T("ide"), p->cs_ide == IDE_A600A1200 ? _T("a600/a1200") : (p->cs_ide == IDE_A4000 ? _T("a4000") : _T("none")));
        cfgfile_dwrite_bool(f, _T("a1000ram"), p->cs_a1000ram);
        cfgfile_dwrite(f, _T("fatgary"), _T("%d"), p->cs_fatgaryrev);
        cfgfile_dwrite(f, _T("ramsey"), _T("%d"), p->cs_ramseyrev);
        cfgfile_dwrite_bool(f, _T("pcmcia"), p->cs_pcmcia);
-       cfgfile_dwrite_bool(f, _T("scsi_cdtv"), p->cs_cdtvscsi);
-       cfgfile_dwrite_bool(f, _T("scsi_a3000"), p->cs_mbdmac == 1);
-       cfgfile_dwrite_bool(f, _T("scsi_a4000t"), p->cs_mbdmac == 2);
        cfgfile_dwrite_bool(f, _T("bogomem_fast"), p->cs_slowmemisfast);
        cfgfile_dwrite_bool(f, _T("resetwarning"), p->cs_resetwarning);
        cfgfile_dwrite_bool(f, _T("denise_noehb"), p->cs_denisenoehb);
@@ -1833,21 +1945,56 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
        cfgfile_dwrite_bool(f, _T("color_burst"), p->cs_color_burst);
        cfgfile_dwrite (f, _T("chipset_hacks"), _T("0x%x"), p->cs_hacks);
 
+       if (cfgfile_board_enabled(p, ROMTYPE_CD32CART, 0)) {
+               cfgfile_dwrite_bool(f, _T("cd32fmv"), true);
+       }
+       if (cfgfile_board_enabled(p, ROMTYPE_MB_IDE, 0) && p->cs_ide == 1) {
+               cfgfile_dwrite_str(f, _T("ide"), _T("a600/a1200"));
+       }
+       if (cfgfile_board_enabled(p, ROMTYPE_MB_IDE, 0) && p->cs_ide == 2) {
+               cfgfile_dwrite_str(f, _T("ide"), _T("a4000"));
+       }
+       if (cfgfile_board_enabled(p, ROMTYPE_CDTVSCSI, 0)) {
+               cfgfile_dwrite_bool(f, _T("scsi_cdtv"), true);
+       }
+       if (cfgfile_board_enabled(p, ROMTYPE_SCSI_A3000, 0)) {
+               cfgfile_dwrite_bool(f, _T("scsi_a3000"), true);
+       }
+       if (cfgfile_board_enabled(p, ROMTYPE_SCSI_A4000T, 0)) {
+               cfgfile_dwrite_bool(f, _T("scsi_a4000t"), true);
+       }
+
        cfgfile_dwrite_str (f, _T("z3mapping"), z3mapping[p->z3_mapping_mode]);
-       cfgfile_dwrite_bool (f, _T("fastmem_autoconfig"), p->fastmem_autoconfig);
-       if (p->fastmem_size < 0x100000 && p->fastmem_size)
-               cfgfile_write (f, _T("fastmem_size_k"), _T("%d"), p->fastmem_size / 1024);
-       else
-               cfgfile_write (f, _T("fastmem_size"), _T("%d"), p->fastmem_size / 0x100000);
-       if (p->fastmem2_size < 0x100000 && p->fastmem2_size)
-               cfgfile_dwrite (f, _T("fastmem2_size_k"), _T("%d"), p->fastmem2_size / 1024);
-       else
-               cfgfile_dwrite (f, _T("fastmem2_size"), _T("%d"), p->fastmem2_size / 0x100000);
+       cfgfile_dwrite_bool(f, _T("board_custom_order"), p->autoconfig_custom_sort);
+       for (int i = 0; i < MAX_RAM_BOARDS; i++) {
+               if (p->fastmem[i].size < 0x100000 && p->fastmem[i].size) {
+                       if (i > 0)
+                               _stprintf(tmp, _T("fastmem%d_size_k"), i + 1);
+                       else
+                               _tcscpy(tmp, _T("fastmem_size_k"));
+                       cfgfile_write(f, tmp, _T("%d"), p->fastmem[i].size / 1024);
+               } else if (p->fastmem[i].size || i == 0) {
+                       if (i > 0)
+                               _stprintf(tmp, _T("fastmem%d_size"), i + 1);
+                       else
+                               _tcscpy(tmp, _T("fastmem_size"));
+                       cfgfile_write(f, tmp, _T("%d"), p->fastmem[i].size / 0x100000);
+               }
+               cfgfile_writeramboard(f, _T("fastmem"), i, &p->fastmem[i]);
+       }
        cfgfile_write (f, _T("mem25bit_size"), _T("%d"), p->mem25bit_size / 0x100000);
        cfgfile_write (f, _T("a3000mem_size"), _T("%d"), p->mbresmem_low_size / 0x100000);
        cfgfile_write (f, _T("mbresmem_size"), _T("%d"), p->mbresmem_high_size / 0x100000);
-       cfgfile_write (f, _T("z3mem_size"), _T("%d"), p->z3fastmem_size / 0x100000);
-       cfgfile_dwrite (f, _T("z3mem2_size"), _T("%d"), p->z3fastmem2_size / 0x100000);
+       for (int i = 0; i < MAX_RAM_BOARDS; i++) {
+               if (i == 0 || p->z3fastmem[i].size) {
+                       if (i > 0)
+                               _stprintf(tmp, _T("z3mem%d_size"), i + 1);
+                       else
+                               _tcscpy(tmp, _T("z3mem_size"));
+                       cfgfile_write(f, tmp, _T("%d"), p->z3fastmem[i].size / 0x100000);
+               }
+               cfgfile_writeramboard(f, _T("z3mem"), i, &p->z3fastmem[i]);
+       }
        cfgfile_write (f, _T("z3mem_start"), _T("0x%x"), p->z3autoconfig_start);
        cfgfile_write(f, _T("bogomem_size"), _T("%d"), p->bogomem_size / 0x40000);
        if (p->cpuboard_type) {
@@ -1865,10 +2012,32 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
        }
        cfgfile_dwrite(f, _T("cpuboardmem1_size"), _T("%d"), p->cpuboardmem1_size / 0x100000);
        cfgfile_dwrite(f, _T("cpuboardmem2_size"), _T("%d"), p->cpuboardmem2_size / 0x100000);
-       cfgfile_write(f, _T("gfxcard_size"), _T("%d"), p->rtgboards[0].rtgmem_size / 0x100000);
-       cfgfile_write_str(f, _T("gfxcard_type"), gfxboard_get_configname(p->rtgboards[0].rtgmem_type));
        cfgfile_write_bool(f, _T("gfxcard_hardware_vblank"), p->rtg_hardwareinterrupt);
        cfgfile_write_bool (f, _T("gfxcard_hardware_sprite"), p->rtg_hardwaresprite);
+       for (int i = 0; i < MAX_RTG_BOARDS; i++) {
+               TCHAR tmp2[100];
+               struct rtgboardconfig *rbc = &p->rtgboards[i];
+               if (rbc->rtgmem_size) {
+                       if (i > 0)
+                               _stprintf(tmp, _T("gfxcard%d_size"), i + 1);
+                       else
+                               _tcscpy(tmp, _T("gfxcard_size"));
+                       cfgfile_write(f, tmp, _T("%d"), rbc->rtgmem_size / 0x100000);
+                       if (i > 0)
+                               _stprintf(tmp, _T("gfxcard%d_type"), i + 1);
+                       else
+                               _tcscpy(tmp, _T("gfxcard_type"));
+                       cfgfile_dwrite_str(f, tmp, gfxboard_get_configname(rbc->rtgmem_type));
+                       if (rbc->device_order) {
+                               _stprintf(tmp2, _T("order=%d"), rbc->device_order);
+                               if (i > 0)
+                                       _stprintf(tmp, _T("gfxcard%d_options"), i + 1);
+                               else
+                                       _tcscpy(tmp, _T("gfxcard_options"));
+                               cfgfile_dwrite_str(f, tmp, tmp2);
+                       }
+               }
+       }
        cfgfile_write (f, _T("chipmem_size"), _T("%d"), p->chipmem_size == 0x20000 ? -1 : (p->chipmem_size == 0x40000 ? 0 : p->chipmem_size / 0x80000));
        cfgfile_dwrite (f, _T("megachipmem_size"), _T("%d"), p->z3chipmem_size / 0x100000);
        // do not save aros rom special space
@@ -1936,15 +2105,18 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
        cfgfile_write (f, _T("rtg_modes"), _T("0x%x"), p->picasso96_modeflags);
 
        cfgfile_write_bool (f, _T("log_illegal_mem"), p->illegal_mem);
+
+#if 0
        if (p->catweasel >= 100)
                cfgfile_dwrite (f, _T("catweasel"), _T("0x%x"), p->catweasel);
        else
                cfgfile_dwrite (f, _T("catweasel"), _T("%d"), p->catweasel);
-       cfgfile_write_bool(f, _T("toccata"), p->sound_toccata);
-       if (p->sound_toccata_mixer)
-               cfgfile_write_bool(f, _T("toccata_mixer"), p->sound_toccata_mixer);
-       cfgfile_write_bool(f, _T("es1370_pci"), p->sound_es1370);
-       cfgfile_write_bool(f, _T("fm801_pci"), p->sound_fm801);
+       cfgfile_write_bool(f, _T("toccata"), p->obs_sound_toccata);
+       if (p->obs_sound_toccata_mixer)
+               cfgfile_write_bool(f, _T("toccata_mixer"), p->obs_sound_toccata_mixer);
+       cfgfile_write_bool(f, _T("es1370_pci"), p->obs_sound_es1370);
+       cfgfile_write_bool(f, _T("fm801_pci"), p->obs_sound_fm801);
+#endif
 
        cfgfile_write_str (f, _T("kbd_lang"), (p->keyboard_lang == KBD_LANG_DE ? _T("de")
                : p->keyboard_lang == KBD_LANG_DK ? _T("dk")
@@ -2189,7 +2361,7 @@ static int cfgfile_path (const TCHAR *option, const TCHAR *value, const TCHAR *n
 {
        if (!cfgfile_string (option, value, name, location, maxsz))
                return 0;
-       TCHAR *s = target_expand_environment (location);
+       TCHAR *s = target_expand_environment (location, NULL, 0);
        _tcsncpy (location, s, maxsz - 1);
        location[maxsz - 1] = 0;
        if (mp) {
@@ -2224,7 +2396,7 @@ static int cfgfile_multipath (const TCHAR *option, const TCHAR *value, const TCH
                return 0;
        for (int i = 0; i < MAX_PATHS; i++) {
                if (mp->path[i][0] == 0 || (i == 0 && (!_tcscmp (mp->path[i], _T(".\\")) || !_tcscmp (mp->path[i], _T("./"))))) {
-                       TCHAR *s = target_expand_environment (tmploc);
+                       TCHAR *s = target_expand_environment (tmploc, NULL, 0);
                        _tcsncpy (mp->path[i], s, 256 - 1);
                        mp->path[i][256 - 1] = 0;
                        fixtrailing (mp->path[i]);
@@ -3348,10 +3520,12 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value)
                        struct chipset_refresh *cr = &p->cr[i];
                        if (_tcscmp (option, _T("displaydata_pal")) == 0) {
                                i = CHIPSET_REFRESH_PAL;
+                               cr = &p->cr[i];
                                cr->rate = -1;
                                _tcscpy (label, _T("PAL"));
                        } else if (_tcscmp (option, _T("displaydata_ntsc")) == 0) {
                                i = CHIPSET_REFRESH_NTSC;
+                               cr = &p->cr[i];
                                cr->rate = -1;
                                _tcscpy (label, _T("NTSC"));
                        }
@@ -3662,14 +3836,22 @@ static void get_filesys_controller (const TCHAR *hdc, int *type, int *typenum, i
                                idx = ext[len - 1] - '1';
                                len -= 2;
                        }
-                       for (int i = 0; hdcontrollers[i]; i++) {
-                               const TCHAR *ext2 = _tcsrchr(hdcontrollers[i], '_');
+                       for (int i = 0; hdcontrollers[i].label; i++) {
+                               const TCHAR *ext2 = _tcsrchr(hdcontrollers[i].label, '_');
                                if (ext2) {
                                        ext2++;
-                                       if (_tcslen(ext2) == len && !_tcsnicmp(ext, ext2, len) && hdc[0] == hdcontrollers[i][0]) {
+                                       if (_tcslen(ext2) == len && !_tcsnicmp(ext, ext2, len) && hdc[0] == hdcontrollers[i].label[0]) {
+                                               if (hdcontrollers[i].romtype) {
+                                                       for (int j = 0; expansionroms[j].name; j++) {
+                                                               if ((expansionroms[j].romtype & ROMTYPE_MASK) == hdcontrollers[i].romtype) {
+                                                                       hdcv = hdcv == HD_CONTROLLER_TYPE_IDE_AUTO ? j + HD_CONTROLLER_TYPE_IDE_EXPANSION_FIRST : j + HD_CONTROLLER_TYPE_SCSI_EXPANSION_FIRST;
+                                                                       break;
+                                                               }
+                                                       }
+                                               }
                                                if (hdcv == HD_CONTROLLER_TYPE_IDE_AUTO) {
                                                        hdcv = i;
-                                               } else {
+                                               } else if (hdcv == HD_CONTROLLER_TYPE_SCSI_AUTO) {
                                                        hdcv = i + HD_CONTROLLER_EXPANSION_MAX;
                                                }
                                                found = true;
@@ -3693,11 +3875,13 @@ static void get_filesys_controller (const TCHAR *hdc, int *type, int *typenum, i
                        }
                }
        } else if (_tcslen (hdc) >= 6 && !_tcsncmp (hdc, _T("scsram"), 6)) {
-               hdcv = HD_CONTROLLER_TYPE_PCMCIA_SRAM;
+               hdcv = HD_CONTROLLER_TYPE_PCMCIA;
                hdunit = 0;
+               idx = 0;
        } else if (_tcslen (hdc) >= 5 && !_tcsncmp (hdc, _T("scide"), 6)) {
-               hdcv = HD_CONTROLLER_TYPE_PCMCIA_IDE;
+               hdcv = HD_CONTROLLER_TYPE_PCMCIA;
                hdunit = 0;
+               idx = 1;
        }
        if (idx >= MAX_DUPLICATE_EXPANSION_BOARDS)
                idx = MAX_DUPLICATE_EXPANSION_BOARDS - 1;
@@ -4296,21 +4480,26 @@ static bool cfgfile_read_board_rom(struct uae_prefs *p, const TCHAR *option, con
                        if (cfgfile_string (option, value, buf, buf2, sizeof buf2 / sizeof (TCHAR))) {
                                brc = get_device_rom(p, ert->romtype, j, &idx);
                                if (brc) {
+                                       TCHAR *p;
                                        if (cfgfile_option_bool(buf2, _T("autoboot_disabled")) == 1) {
                                                brc->roms[idx].autoboot_disabled = true;
                                        }
+                                       p = cfgfile_option_get(buf2, _T("order"));
+                                       if (p) {
+                                               brc->device_order = _tstol(p);
+                                       }
                                        if (ert->settings) {
                                                brc->roms[idx].device_settings = cfgfile_read_rom_settings(ert->settings, buf2);
                                        }
                                        if (ert->id_jumper) {
-                                               TCHAR *p = cfgfile_option_get(buf2, _T("id"));
+                                               p = cfgfile_option_get(buf2, _T("id"));
                                                if (p) {
                                                        brc->roms[idx].device_id = _tstol(p);
                                                }
                                        }
                                        if (ert->subtypes) {
                                                const struct expansionsubromtype *srt = ert->subtypes;
-                                               TCHAR tmp[MAX_DPATH], *p;
+                                               TCHAR tmp[MAX_DPATH];
                                                p = tmp;
                                                *p = 0;
                                                while (srt->name) {
@@ -4340,6 +4529,18 @@ static bool cfgfile_read_board_rom(struct uae_prefs *p, const TCHAR *option, con
        return false;
 }
 
+static void addbcromtype(struct uae_prefs *p, int romtype, bool add)
+{
+       if (!add) {
+               clear_device_rom(p, romtype, 0, true);
+       } else {
+               struct boardromconfig *brc = get_device_rom_new(p, romtype, 0, NULL);
+               if (brc && !brc->roms[0].romfile[0]) {
+                       _tcscpy(brc->roms[0].romfile, _T(":ENABLED"));
+               }
+       }
+}
+
 static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCHAR *value)
 {
        int tmpval, dummyint, i;
@@ -4387,19 +4588,12 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH
        }
 
 
-       if (cfgfile_yesno (option, value, _T("scsi_a3000"), &dummybool)) {
-               if (dummybool)
-                       p->cs_mbdmac = 1;
-               return 1;
-       }
-       if (cfgfile_yesno (option, value, _T("scsi_a4000t"), &dummybool)) {
-               if (dummybool)
-                       p->cs_mbdmac = 2;
+       if (cfgfile_string(option, value, _T("a2065"), p->a2065name, sizeof p->a2065name / sizeof(TCHAR))) {
+               if (p->a2065name[0])
+                       addbcromtype(p, ROMTYPE_A2065, true);
                return 1;
        }
 
-       if (cfgfile_string(option, value, _T("a2065"), p->a2065name, sizeof p->a2065name / sizeof(TCHAR)))
-               return 1;
        if (cfgfile_string(option, value, _T("ne2000_pci"), p->ne2000pciname, sizeof p->ne2000pciname / sizeof(TCHAR)))
                return 1;
        if (cfgfile_string(option, value, _T("ne2000_pcmcia"), p->ne2000pcmcianame, sizeof p->ne2000pcmcianame / sizeof(TCHAR)))
@@ -4411,12 +4605,10 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH
                || cfgfile_yesno(option, value, _T("cd32cd"), &p->cs_cd32cd)
                || cfgfile_yesno(option, value, _T("cd32c2p"), &p->cs_cd32c2p)
                || cfgfile_yesno(option, value, _T("cd32nvram"), &p->cs_cd32nvram)
-               || cfgfile_yesno(option, value, _T("cd32fmv"), &p->cs_cd32fmv)
                || cfgfile_yesno(option, value, _T("cdtvcd"), &p->cs_cdtvcd)
                || cfgfile_yesno(option, value, _T("cdtv-cr"), &p->cs_cdtvcr)
                || cfgfile_yesno(option, value, _T("cdtvram"), &p->cs_cdtvram)
                || cfgfile_yesno(option, value, _T("a1000ram"), &p->cs_a1000ram)
-               || cfgfile_yesno(option, value, _T("pcmcia"), &p->cs_pcmcia)
                || cfgfile_yesno(option, value, _T("scsi_cdtv"), &p->cs_cdtvscsi)
                || cfgfile_yesno(option, value, _T("cia_overlay"), &p->cs_ciaoverlay)
                || cfgfile_yesno(option, value, _T("bogomem_fast"), &p->cs_slowmemisfast)
@@ -4430,7 +4622,6 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH
                || cfgfile_yesno(option, value, _T("color_burst"), &p->cs_color_burst)
                || cfgfile_yesno(option, value, _T("1mchipjumper"), &p->cs_1mchipjumper)
                || cfgfile_yesno(option, value, _T("agnus_bltbusybug"), &p->cs_agnusbltbusybug)
-               || cfgfile_yesno(option, value, _T("fastmem_autoconfig"), &p->fastmem_autoconfig)
                || cfgfile_yesno(option, value, _T("gfxcard_hardware_vblank"), &p->rtg_hardwareinterrupt)
                || cfgfile_yesno(option, value, _T("gfxcard_hardware_sprite"), &p->rtg_hardwaresprite)
                || cfgfile_yesno(option, value, _T("synchronize_clock"), &p->tod_hack)
@@ -4460,11 +4651,8 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH
                || cfgfile_yesno (option, value, _T("rtg_nocustom"), &p->picasso96_nocustom)
                || cfgfile_yesno (option, value, _T("floppy_write_protect"), &p->floppy_read_only)
                || cfgfile_yesno(option, value, _T("harddrive_write_protect"), &p->harddrive_read_only)
-               || cfgfile_yesno (option, value, _T("uae_hide_autoconfig"), &p->uae_hide_autoconfig)
-               || cfgfile_yesno(option, value, _T("toccata"), &p->sound_toccata)
-               || cfgfile_yesno(option, value, _T("es1370_pci"), &p->sound_es1370)
-               || cfgfile_yesno(option, value, _T("fm801_pci"), &p->sound_fm801)
-               || cfgfile_yesno (option, value, _T("toccata_mixer"), &p->sound_toccata_mixer)
+               || cfgfile_yesno(option, value, _T("uae_hide_autoconfig"), &p->uae_hide_autoconfig)
+               || cfgfile_yesno(option, value, _T("board_custom_order"), &p->autoconfig_custom_sort)
                || cfgfile_yesno (option, value, _T("uaeserial"), &p->uaeserial))
                return 1;
 
@@ -4480,19 +4668,12 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH
                || cfgfile_doubleval (option, value, _T("chipset_refreshrate"), &p->chipset_refreshrate)
                || cfgfile_intval(option, value, _T("cpuboardmem1_size"), &p->cpuboardmem1_size, 0x100000)
                || cfgfile_intval(option, value, _T("cpuboardmem2_size"), &p->cpuboardmem2_size, 0x100000)
-               || cfgfile_intval(option, value, _T("fastmem_size"), &p->fastmem_size, 0x100000)
-               || cfgfile_intval(option, value, _T("fastmem_size_k"), &p->fastmem_size, 1024)
-               || cfgfile_intval (option, value, _T("fastmem2_size"), &p->fastmem2_size, 0x100000)
-               || cfgfile_intval (option, value, _T("fastmem2_size_k"), &p->fastmem2_size, 1024)
                || cfgfile_intval (option, value, _T("mem25bit_size"), &p->mem25bit_size, 0x100000)
                || cfgfile_intval (option, value, _T("a3000mem_size"), &p->mbresmem_low_size, 0x100000)
                || cfgfile_intval (option, value, _T("mbresmem_size"), &p->mbresmem_high_size, 0x100000)
-               || cfgfile_intval (option, value, _T("z3mem_size"), &p->z3fastmem_size, 0x100000)
-               || cfgfile_intval (option, value, _T("z3mem2_size"), &p->z3fastmem2_size, 0x100000)
                || cfgfile_intval (option, value, _T("megachipmem_size"), &p->z3chipmem_size, 0x100000)
                || cfgfile_intval (option, value, _T("z3mem_start"), &p->z3autoconfig_start, 1)
                || cfgfile_intval (option, value, _T("bogomem_size"), &p->bogomem_size, 0x40000)
-               || cfgfile_intval (option, value, _T("gfxcard_size"), &p->rtgboards[0].rtgmem_size, 0x100000)
                || cfgfile_intval(option, value, _T("rtg_modes"), &p->picasso96_modeflags, 1)
                || cfgfile_intval (option, value, _T("floppy_speed"), &p->floppy_speed, 1)
                || cfgfile_intval (option, value, _T("cd_speed"), &p->cd_speed, 1)
@@ -4509,14 +4690,12 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH
                || cfgfile_intval (option, value, _T("uae_hide"), &p->uae_hide, 1)
                || cfgfile_intval (option, value, _T("cpu_frequency"), &p->cpu_frequency, 1)
                || cfgfile_intval(option, value, _T("kickstart_ext_rom_file2addr"), &p->romextfile2addr, 1)
-               || cfgfile_intval(option, value, _T("genlock_mix"), &p->genlock_mix, 1)
-               || cfgfile_intval (option, value, _T("catweasel"), &p->catweasel, 1))
+               || cfgfile_intval(option, value, _T("genlock_mix"), &p->genlock_mix, 1))
                return 1;
 
        if (cfgfile_strval (option, value, _T("comp_trustbyte"), &p->comptrustbyte, compmode, 0)
                || cfgfile_strval (option, value, _T("rtc"), &p->cs_rtc, rtctype, 0)
                || cfgfile_strval (option, value, _T("ciaatod"), &p->cs_ciaatod, ciaatodmode, 0)
-               || cfgfile_strval (option, value, _T("ide"), &p->cs_ide, idemode, 0)
                || cfgfile_strval (option, value, _T("scsi"), &p->scsi, scsimode, 0)
                || cfgfile_strval (option, value, _T("comp_trustword"), &p->comptrustword, compmode, 0)
                || cfgfile_strval (option, value, _T("comp_trustlong"), &p->comptrustlong, compmode, 0)
@@ -4549,23 +4728,127 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH
                || cfgfile_string (option, value, _T("ghostscript_parameters"), p->ghostscript_parameters, sizeof p->ghostscript_parameters / sizeof (TCHAR)))
                return 1;
 
-       if (cfgfile_string(option, value, _T("gfxcard_type"), tmpbuf, sizeof tmpbuf / sizeof(TCHAR))) {
-               p->rtgboards[0].rtgmem_type = 0;
-               i = 0;
-               for (;;) {
-                       const TCHAR *t = gfxboard_get_configname(i);
-                       if (!t) {
-                               break;
-                       }
-                       if (!_tcsicmp(t, tmpbuf)) {
-                               p->rtgboards[0].rtgmem_type = i;
-                               break;
-                       }
-                       i++;
+       if (cfgfile_string(option, value, _T("uaeboard_options"), tmpbuf, sizeof tmpbuf / sizeof(TCHAR))) {
+               TCHAR *s = cfgfile_option_get(value, _T("order"));
+               if (s)
+                       p->uaeboard_order = _tstol(s);
+               return 1;
+       }
+
+       if (cfgfile_readramboard(option, value, _T("fastmem"), &p->fastmem[0])) {
+               return 1;
+       }
+       if (cfgfile_readramboard(option, value, _T("z3mem"), &p->z3fastmem[0])) {
+               return 1;
+       }
+
+       if (cfgfile_yesno(option, value, _T("pcmcia"), &p->cs_pcmcia)) {
+               if (p->cs_pcmcia)
+                       addbcromtype(p, ROMTYPE_MB_PCMCIA, true);
+               return 1;
+       }
+       if (cfgfile_strval(option, value, _T("ide"), &p->cs_ide, idemode, 0)) {
+               if (p->cs_ide)
+                       addbcromtype(p, ROMTYPE_MB_IDE, true);
+               return 1;
+       }
+       if (cfgfile_yesno(option, value, _T("scsi_a3000"), &dummybool)) {
+               if (dummybool) {
+                       addbcromtype(p, ROMTYPE_SCSI_A3000, true);
+                       p->cs_mbdmac = 1;
+               }
+               return 1;
+       }
+       if (cfgfile_yesno(option, value, _T("scsi_a4000t"), &dummybool)) {
+               if (dummybool) {
+                       addbcromtype(p, ROMTYPE_SCSI_A4000T, true);
+                       p->cs_mbdmac = 2;
+               }
+               return 1;
+       }
+       if (cfgfile_yesno(option, value, _T("cd32fmv"), &p->cs_cd32fmv)) {
+               if (p->cs_cd32fmv) {
+                       addbcromtype(p, ROMTYPE_CD32CART, true);
+               }
+               return 1;
+       }
+       if (cfgfile_intval(option, value, _T("catweasel"), &p->catweasel, 1)) {
+               if (p->catweasel) {
+                       addbcromtype(p, ROMTYPE_CATWEASEL, true);
+               }
+               return 1;
+       }
+       if (cfgfile_yesno(option, value, _T("toccata"), &dummybool))
+       {
+               if (dummybool) {
+                       addbcromtype(p, ROMTYPE_TOCCATA, true);
+               }
+               return 1;
+       }
+       if (cfgfile_yesno(option, value, _T("es1370_pci"), &dummybool))
+       {
+               if (dummybool) {
+                       addbcromtype(p, ROMTYPE_ES1370, true);
+               }
+               return 1;
+       }
+       if (cfgfile_yesno(option, value, _T("fm801_pci"), &dummybool))
+       {
+               if (dummybool) {
+                       addbcromtype(p, ROMTYPE_FM801, true);
+               }
+               return 1;
+       }
+       if (cfgfile_yesno(option, value, _T("toccata_mixer"), &dummybool))
+       {
+               if (dummybool) {
+                       addbcromtype(p, ROMTYPE_TOCCATA, true);
                }
                return 1;
        }
 
+       for (int i = 0; i < MAX_RTG_BOARDS; i++) {
+               struct rtgboardconfig *rbc = &p->rtgboards[i];
+               TCHAR tmp[100];
+               if (i > 0)
+                       _stprintf(tmp, _T("gfxcard%d_size"), i + 1);
+               else
+                       _tcscpy(tmp, _T("gfxcard_size"));
+               if (cfgfile_intval(option, value, tmp, &rbc->rtgmem_size, 0x100000))
+                       return 1;
+               if (i > 0)
+                       _stprintf(tmp, _T("gfxcard%d_options"), i + 1);
+               else
+                       _tcscpy(tmp, _T("gfxcard_options"));
+               if (!_tcsicmp(option, tmp)) {
+                       TCHAR *s = cfgfile_option_get(value, _T("order"));
+                       if (s) {
+                               rbc->device_order = _tstol(s);
+                       }
+                       return 1;
+               }
+               if (i > 0)
+                       _stprintf(tmp, _T("gfxcard%d_type"), i + 1);
+               else
+                       _tcscpy(tmp, _T("gfxcard_type"));
+               if (cfgfile_string(option, value, tmp, tmpbuf, sizeof tmpbuf / sizeof(TCHAR))) {
+                       rbc->rtgmem_type = 0;
+                       rbc->rtg_index = i;
+                       int j = 0;
+                       for (;;) {
+                               const TCHAR *t = gfxboard_get_configname(j);
+                               if (!t) {
+                                       break;
+                               }
+                               if (!_tcsicmp(t, tmpbuf)) {
+                                       rbc->rtgmem_type = j;
+                                       break;
+                               }
+                               j++;
+                       }
+                       return 1;
+               }
+       }
 
        if (cfgfile_string(option, value, _T("cpuboard_type"), tmpbuf, sizeof tmpbuf / sizeof(TCHAR))) {
                p->cpuboard_type = 0;
@@ -4591,7 +4874,6 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH
                        for(i = 0; cbs[i].name; i++) {
                                if (cfgfile_option_find(tmpbuf, cbs[i].configname)) {
                                        p->cpuboard_settings |= 1 << (i + cbs[i].bitshift);
-                                       break;
                                }
                        }
                }
@@ -4789,6 +5071,136 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH
        return 0;
 }
 
+static void romtype_restricted(struct uae_prefs *p, int *list)
+{
+       for (int i = 0; list[i]; i++) {
+               int romtype = list[i];
+               if (cfgfile_board_enabled(p, romtype, 0)) {
+                       i++;
+                       while (list[i]) {
+                               romtype = list[i];
+                               if (cfgfile_board_enabled(p, romtype, 0)) {
+                                       addbcromtype(p, romtype, false);
+                               }
+                               i++;
+                               return;
+                       }
+               }
+       }
+}
+
+void cfgfile_compatibility_rtg(struct uae_prefs *p)
+{
+       int uaegfx = -1;
+       // only one uaegfx
+       for (int i = 0; i < MAX_RTG_BOARDS; i++) {
+               struct rtgboardconfig *rbc = &p->rtgboards[i];
+               if (rbc->rtgmem_size && rbc->rtgmem_type < GFXBOARD_HARDWARE) {
+                       if (uaegfx >= 0) {
+                               rbc->rtgmem_size = 0;
+                               rbc->rtgmem_type = 0;
+                       } else {
+                               uaegfx = i;
+                       }
+               }
+       }
+       // uaegfx must be first
+       if (uaegfx > 0) {
+               struct rtgboardconfig *rbc = &p->rtgboards[uaegfx];
+               struct rtgboardconfig *rbc2 = &p->rtgboards[0];
+               int size = rbc->rtgmem_size;
+               int type = rbc->rtgmem_type;
+               rbc->rtgmem_size = rbc2->rtgmem_size;
+               rbc->rtgmem_type = rbc2->rtgmem_type;
+               rbc2->rtgmem_size = size;
+               rbc2->rtgmem_type = type;
+       }
+       // allow only one a2410 and vga
+       int a2410 = -1;
+       int vga = -1;
+       for (int i = 0; i < MAX_RTG_BOARDS; i++) {
+               struct rtgboardconfig *rbc = &p->rtgboards[i];
+               if (rbc->rtgmem_type == GFXBOARD_A2410) {
+                       if (a2410 >= 0) {
+                               rbc->rtgmem_size = 0;
+                               rbc->rtgmem_type = 0;
+                       } else {
+                               a2410 = i;
+                       }
+               }
+               if (rbc->rtgmem_type == GFXBOARD_VGA) {
+                       if (vga >= 0) {
+                               rbc->rtgmem_size = 0;
+                               rbc->rtgmem_type = 0;
+                       } else {
+                               vga = i;
+                       }
+               }
+       }
+       // empty slots last
+       bool reorder = true;
+       while (reorder) {
+               reorder = false;
+               for (int i = 0; i < MAX_RTG_BOARDS; i++) {
+                       struct rtgboardconfig *rbc = &p->rtgboards[i];
+                       if (i > 0 && rbc->rtgmem_size && p->rtgboards[i - 1].rtgmem_size == 0) {
+                               struct rtgboardconfig *rbc2 = &p->rtgboards[i - 1];
+                               rbc2->rtgmem_size = rbc->rtgmem_size;
+                               rbc2->rtgmem_type = rbc->rtgmem_type;
+                               rbc2->device_order = rbc->device_order;
+                               rbc->rtgmem_size = 0;
+                               rbc->rtgmem_type = 0;
+                               rbc->device_order = 0;
+                               reorder = true;
+                               break;
+                       }
+               }
+       }
+       for (int i = 0; i < MAX_RTG_BOARDS; i++) {
+               if (p->rtgboards[i].rtgmem_size) {
+                       uae_u32 romtype = gfxboard_get_romtype(&p->rtgboards[i]);
+                       if (romtype) {
+                               addbcromtype(p, romtype, true);
+                       }
+               }
+       }
+}
+
+void cfgfile_compatibility_romtype(struct uae_prefs *p)
+{
+       addbcromtype(p, ROMTYPE_MB_PCMCIA, p->cs_pcmcia);
+
+       addbcromtype(p, ROMTYPE_MB_IDE, p->cs_ide != 0);
+
+       if (p->cs_mbdmac == 1) {
+               addbcromtype(p, ROMTYPE_SCSI_A4000T, false);
+               addbcromtype(p, ROMTYPE_SCSI_A3000, true);
+       } else if (p->cs_mbdmac == 2) {
+               addbcromtype(p, ROMTYPE_SCSI_A3000, false);
+               addbcromtype(p, ROMTYPE_SCSI_A4000T, true);
+       } else {
+               addbcromtype(p, ROMTYPE_SCSI_A3000, false);
+               addbcromtype(p, ROMTYPE_SCSI_A4000T, false);
+       }
+
+       addbcromtype(p, ROMTYPE_CDTVDMAC, p->cs_cdtvcd && !p->cs_cdtvcr);
+       addbcromtype(p, ROMTYPE_CDTVSCSI, p->cs_cdtvscsi);
+
+       addbcromtype(p, ROMTYPE_CDTVCR, p->cs_cdtvcr);
+
+       addbcromtype(p, ROMTYPE_CD32CART, p->cs_cd32fmv);
+
+       addbcromtype(p, ROMTYPE_A2065, p->a2065name[0] != 0);
+       addbcromtype(p, ROMTYPE_NE2KPCMCIA, p->ne2000pcmcianame[0] != 0);
+       addbcromtype(p, ROMTYPE_NE2KPCI, p->ne2000pciname[0] != 0);
+
+       static int restricted_net[] = { ROMTYPE_A2065, ROMTYPE_NE2KPCMCIA, ROMTYPE_NE2KPCI, 0 };
+       static int restricted_x86[] = { ROMTYPE_A1060, ROMTYPE_A2088, ROMTYPE_A2088T, ROMTYPE_A2286, ROMTYPE_A2386, 0 };
+       static int restricted_pci[] = { ROMTYPE_GREX, ROMTYPE_MEDIATOR, ROMTYPE_PROMETHEUS, 0 };
+       romtype_restricted(p, restricted_net);
+       romtype_restricted(p, restricted_x86);
+       romtype_restricted(p, restricted_pci);
+}
 
 static bool createconfigstore (struct uae_prefs*);
 static int getconfigstoreline (const TCHAR *option, TCHAR *value);
@@ -5562,7 +5974,7 @@ static void parse_cpu_specs (struct uae_prefs *p, const TCHAR *spec)
 
 static void cmdpath (TCHAR *dst, const TCHAR *src, int maxsz)
 {
-       TCHAR *s = target_expand_environment (src);
+       TCHAR *s = target_expand_environment (src, NULL, 0);
        _tcsncpy (dst, s, maxsz);
        dst[maxsz] = 0;
        xfree (s);
@@ -5624,7 +6036,7 @@ int parse_cmdline_option (struct uae_prefs *p, TCHAR c, const TCHAR *arg)
                break;
 
        case 'Z':
-               p->z3fastmem_size = _tstoi (arg) * 0x100000;
+               p->z3fastmem[0].size = _tstoi (arg) * 0x100000;
                break;
 
        case 'U':
@@ -5632,7 +6044,7 @@ int parse_cmdline_option (struct uae_prefs *p, TCHAR c, const TCHAR *arg)
                break;
 
        case 'F':
-               p->fastmem_size = _tstoi (arg) * 0x100000;
+               p->fastmem[0].size = _tstoi (arg) * 0x100000;
                break;
 
        case 'b':
@@ -6365,23 +6777,18 @@ void default_prefs (struct uae_prefs *p, bool reset, int type)
        p->filesys_max_name = 107;
        p->filesys_max_file_size = 0x7fffffff;
 
-       p->fastmem_size = 0x00000000;
-       p->fastmem2_size = 0x00000000;
-       p->mem25bit_size = 0x00000000;
-       p->mbresmem_low_size = 0x00000000;
-       p->mbresmem_high_size = 0x00000000;
-       p->z3fastmem_size = 0x00000000;
-       p->z3fastmem2_size = 0x00000000;
        p->z3autoconfig_start = 0x10000000;
        p->chipmem_size = 0x00080000;
        p->bogomem_size = 0x00080000;
+       for (int i = 0; i < MAX_RTG_BOARDS; i++) {
+               p->rtgboards[i].rtg_index = i;
+       }
        p->rtgboards[0].rtgmem_size = 0x00000000;
        p->rtgboards[0].rtgmem_type = GFXBOARD_UAE_Z3;
        p->custom_memory_addrs[0] = 0;
        p->custom_memory_sizes[0] = 0;
        p->custom_memory_addrs[1] = 0;
        p->custom_memory_sizes[1] = 0;
-       p->fastmem_autoconfig = true;
 
        p->nr_floppies = 2;
        p->floppy_read_only = false;
@@ -6395,8 +6802,12 @@ void default_prefs (struct uae_prefs *p, bool reset, int type)
        p->floppy_random_bits_max = 3;
        p->dfxclickvolume_disk[0] = 33;
        p->dfxclickvolume_disk[1] = 33;
+       p->dfxclickvolume_disk[2] = 33;
+       p->dfxclickvolume_disk[3] = 33;
        p->dfxclickvolume_empty[0] = 33;
        p->dfxclickvolume_empty[1] = 33;
+       p->dfxclickvolume_empty[2] = 33;
+       p->dfxclickvolume_empty[3] = 33;
        p->dfxclickchannelmask = 0xffff;
        p->cd_speed = 100;
 
@@ -6527,23 +6938,26 @@ static void buildin_default_prefs (struct uae_prefs *p)
        p->maprom = 0;
        p->cachesize = 0;
        p->socket_emu = 0;
-       p->sound_volume_master = 0;
-       p->sound_volume_paula = 0;
-       p->sound_volume_cd = 0;
        p->clipboard_sharing = false;
        p->ppc_mode = 0;
+       p->ppc_model[0] = 0;
+       p->cpuboard_type = 0;
+       p->cpuboard_subtype = 0;
 
        p->chipmem_size = 0x00080000;
        p->bogomem_size = 0x00080000;
-       p->fastmem_size = 0x00000000;
-       p->mem25bit_size = 0x00000000;
-       p->mbresmem_low_size = 0x00000000;
-       p->mbresmem_high_size = 0x00000000;
-       p->z3fastmem_size = 0x00000000;
-       p->z3fastmem2_size = 0x00000000;
-       p->z3chipmem_size = 0x00000000;
-       p->rtgboards[0].rtgmem_size = 0x00000000;
-       p->rtgboards[0].rtgmem_type = GFXBOARD_UAE_Z3;
+       p->z3chipmem_size = 0;
+       for (int i = 0; i < MAX_RAM_BOARDS; i++) {
+               p->fastmem[i].size = 0;
+               p->z3fastmem[i].size = 0;
+       }
+       for (int i = 0; i < MAX_RTG_BOARDS; i++) {
+               p->rtgboards[i].rtgmem_size = 0x00000000;
+               p->rtgboards[i].rtgmem_type = GFXBOARD_UAE_Z3;
+       }
+       for (int i = 0; i < MAX_EXPANSION_BOARDS; i++) {
+               memset(&p->expansionboard[i], 0, sizeof(struct boardromconfig));
+       }
 
        p->cs_rtc = 0;
        p->cs_a1000ram = false;
@@ -6567,7 +6981,10 @@ static void buildin_default_prefs (struct uae_prefs *p)
 
        _tcscpy (p->romextfile, _T(""));
        _tcscpy (p->romextfile2, _T(""));
-       set_device_rom(p, NULL, ROMTYPE_CPUBOARD, 0);
+
+       p->ne2000pciname[0] = 0;
+       p->ne2000pcmcianame[0] = 0;
+       p->a2065name[0] = 0;
 
        p->prtname[0] = 0;
        p->sername[0] = 0;
@@ -6575,6 +6992,7 @@ static void buildin_default_prefs (struct uae_prefs *p)
        p->mountitems = 0;
 
        target_default_options (p, 1);
+       cfgfile_compatibility_romtype(p);
 }
 
 static void set_68020_compa (struct uae_prefs *p, int compa, int cd32)
@@ -6918,7 +7336,7 @@ static int bip_a1200 (struct uae_prefs *p, int config, int compa, int romcheck)
        switch (config)
        {
                case 1:
-               p->fastmem_size = 0x400000;
+               p->fastmem[0].size = 0x400000;
                p->cs_rtc = 1;
                break;
                case 2:
@@ -6983,7 +7401,7 @@ static int bip_a600 (struct uae_prefs *p, int config, int compa, int romcheck)
        if (config == 1)
                p->chipmem_size = 0x200000;
        if (config == 2)
-               p->fastmem_size = 0x400000;
+               p->fastmem[0].size = 0x400000;
        p->chipset_mask = CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE;
        return configure_rom (p, roms, romcheck);
 }
@@ -7004,7 +7422,7 @@ static int bip_a500p (struct uae_prefs *p, int config, int compa, int romcheck)
        if (config == 1)
                p->chipmem_size = 0x200000;
        if (config == 2)
-               p->fastmem_size = 0x400000;
+               p->fastmem[0].size = 0x400000;
        p->chipset_mask = CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE;
        return configure_rom (p, roms, romcheck);
 }
@@ -7073,7 +7491,7 @@ static int bip_super (struct uae_prefs *p, int config, int compa, int romcheck)
        roms[6] = -1;
        p->bogomem_size = 0;
        p->chipmem_size = 0x400000;
-       p->z3fastmem_size = 8 * 1024 * 1024;
+       p->z3fastmem[0].size = 8 * 1024 * 1024;
        p->rtgboards[0].rtgmem_size = 16 * 1024 * 1024;
        p->cpu_model = 68040;
        p->fpu_model = 68040;
@@ -7191,6 +7609,7 @@ int built_in_prefs (struct uae_prefs *p, int model, int config, int compa, int r
                p->sound_filter_type = FILTER_SOUND_TYPE_A500;
        if (p->cpu_model >= 68040)
                p->cs_bytecustomwritebug = true;
+       cfgfile_compatibility_romtype(p);
        return v;
 }
 
@@ -7240,7 +7659,7 @@ int built_in_chipset_prefs (struct uae_prefs *p)
                        // very A500-like
                        p->cs_df0idhw = 0;
                        p->cs_resetwarning = 0;
-                       if (p->bogomem_size || p->chipmem_size > 0x80000 || p->fastmem_size)
+                       if (p->bogomem_size || p->chipmem_size > 0x80000 || p->fastmem[0].size)
                                p->cs_rtc = 1;
                        p->cs_ciatodbug = true;
                } else {
@@ -7278,7 +7697,7 @@ int built_in_chipset_prefs (struct uae_prefs *p)
        case CP_A500: // A500
                p->cs_df0idhw = 0;
                p->cs_resetwarning = 0;
-               if (p->bogomem_size || p->chipmem_size > 0x80000 || p->fastmem_size)
+               if (p->bogomem_size || p->chipmem_size > 0x80000 || p->fastmem[0].size)
                        p->cs_rtc = 1;
                p->cs_ciatodbug = true;
                break;
@@ -7315,7 +7734,7 @@ int built_in_chipset_prefs (struct uae_prefs *p)
                p->cs_pcmcia = 1;
                p->cs_ksmirror_a8 = 1;
                p->cs_ciaoverlay = 0;
-               if (p->fastmem_size || p->z3fastmem_size || p->cpuboard_type)
+               if (p->fastmem[0].size || p->z3fastmem[0].size || p->cpuboard_type)
                        p->cs_rtc = 1;
                break;
        case CP_A2000: // A2000
diff --git a/cia.cpp b/cia.cpp
index 9a09c609b79d5041c4970120e8612701c135c5fe..8d469addc4261f83ce0febe37e2ce3aeb932627d 100644 (file)
--- a/cia.cpp
+++ b/cia.cpp
@@ -820,24 +820,28 @@ static void check_keyboard(void)
        }
 }
 
-void CIA_hsync_posthandler (bool dotod)
-{
-       // Previous line was supposed to increase TOD but
-       // no one cared. Do it now.
-       if (ciab_tod_event_state == 1)
-               CIAB_tod_inc (false);
-       ciab_tod_event_state = 0;
-
-       if (currprefs.tod_hack && ciaatodon)
-               do_tod_hack (dotod);
-
-       if (resetwarning_phase) {
-               resetwarning_check ();
-               while (keys_available ())
-                       get_next_key ();
+void CIA_hsync_posthandler (bool ciahsync, bool dotod)
+{
+       if (ciahsync) {
+               // cia hysnc
+               // Previous line was supposed to increase TOD but
+               // no one cared. Do it now.
+               if (ciab_tod_event_state == 1)
+                       CIAB_tod_inc (false);
+               ciab_tod_event_state = 0;
+
+               if (currprefs.tod_hack && ciaatodon)
+                       do_tod_hack (dotod);
        } else {
-               if ((hsync_counter & 15) == 0)
-                       check_keyboard();
+               // custom hsync
+               if (resetwarning_phase) {
+                       resetwarning_check ();
+                       while (keys_available ())
+                               get_next_key ();
+               } else {
+                       if ((hsync_counter & 15) == 0)
+                               check_keyboard();
+               }
        }
 }
 
index 25a05597c4d5b93b849637aba137168796d2f835..69b58bee48ddf8f2aaad624d41d1df7a223fd759 100644 (file)
@@ -39,7 +39,7 @@ void consolehook_config (struct uae_prefs *p)
        p->cpu_compatible = 0;
        p->address_space_24 = 0;
        p->chipmem_size = 0x00200000;
-       p->fastmem_size = 0x00800000;
+       p->fastmem[0].size = 0x00800000;
        p->bogomem_size = 0;
        p->nr_floppies = 1;
        p->floppyslots[1].dfxtype = DRV_NONE;
index 0b7af51def966811902bd5a619e0488767f7552a..a8dcc23ae940acbf2f4c45f7dd9a0aa642ccd1cc 100644 (file)
@@ -37,6 +37,7 @@
 // 00F83B7C 3.1 A4000
 // 00F83C96 3.1 A1200
 
+#define MAPROM_DEBUG 0
 #define PPC_IRQ_DEBUG 0
 #define CPUBOARD_IO_LOG 0
 #define CPUBOARD_IRQ_LOG 0
@@ -97,7 +98,7 @@
 // 0x08 always set
 #define P5_FLASH                       0x04 // Flash writable (CSMK3,CSPPC only)
 // 0x02 (can be modified even when locked)
-#define        P5_SHADOW                       0x01 // KS MAP ROM
+#define        P5_SHADOW                       0x01 // KS MAP ROM (CSMK3,CSPPC only)
 
 /* REG_LOCK 0x20. CSMK3,CSPPC only */
 #define        P5_MAGIC1                       0x60 // REG_SHADOW and flash write protection unlock sequence
 #define        P5_LVL2                         0x02
 #define        P5_LVL1                         0x01
 
-#define CS_RAM_BASE 0x0c000000
+#define CS_RAM_BASE 0x08000000
 
-#define BLIZZARD_RAM_BASE_48 0x48000000
-#define BLIZZARD_RAM_BASE_68 0x68000000
-#define BLIZZARD_RAM_256M_BASE_40 0x40000000
-#define BLIZZARD_RAM_256M_BASE_70 0x70000000
-#define BLIZZARD_MAPROM_BASE    0x4ff80000
-#define BLIZZARDMK2_MAPROM_BASE 0x0ff80000
+#define BLIZZARDMK4_RAM_BASE_48 0x48000000
+#define BLIZZARDMK4_MAPROM_BASE        0x4ff80000
+#define BLIZZARDMK2_MAPROM_BASE        0x0ff80000
 #define BLIZZARDMK3_MAPROM_BASE 0x1ef80000
 #define BLIZZARD_MAPROM_ENABLE  0x80ffff00
 #define BLIZZARD_BOARD_DISABLE  0x80fa0000
@@ -252,81 +250,81 @@ void cpuboard_set_flash_unlocked(bool unlocked)
        flash_unlocked = unlocked;
 }
 
-static bool is_blizzard1230mk2(void)
+static bool is_blizzard1230mk2(struct uae_prefs *p)
 {
-       return ISCPUBOARD(BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_1230II);
+       return ISCPUBOARDP(p, BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_1230II);
 }
-static bool is_blizzard1230mk3(void)
+static bool is_blizzard1230mk3(struct uae_prefs *p)
 {
-       return ISCPUBOARD(BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_1230III);
+       return ISCPUBOARDP(p, BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_1230III);
 }
-static bool is_blizzard(void)
+static bool is_blizzard(struct uae_prefs *p)
 {
-       return ISCPUBOARD(BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_1230IV) || ISCPUBOARD(BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_1260);
+       return ISCPUBOARDP(p, BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_1230IV) || ISCPUBOARDP(p, BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_1260);
 }
-static bool is_blizzard2060(void)
+static bool is_blizzard2060(struct uae_prefs *p)
 {
-       return ISCPUBOARD(BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_2060);
+       return ISCPUBOARDP(p, BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_2060);
 }
-static bool is_csmk1(void)
+static bool is_csmk1(struct uae_prefs *p)
 {
-       return ISCPUBOARD(BOARD_CYBERSTORM, BOARD_CYBERSTORM_SUB_MK1);
+       return ISCPUBOARDP(p, BOARD_CYBERSTORM, BOARD_CYBERSTORM_SUB_MK1);
 }
-static bool is_csmk2(void)
+static bool is_csmk2(struct uae_prefs *p)
 {
-       return ISCPUBOARD(BOARD_CYBERSTORM, BOARD_CYBERSTORM_SUB_MK2);
+       return ISCPUBOARDP(p, BOARD_CYBERSTORM, BOARD_CYBERSTORM_SUB_MK2);
 }
-static bool is_csmk3(void)
+static bool is_csmk3(struct uae_prefs *p)
 {
-       return ISCPUBOARD(BOARD_CYBERSTORM, BOARD_CYBERSTORM_SUB_MK3) || ISCPUBOARD(BOARD_CYBERSTORM, BOARD_CYBERSTORM_SUB_PPC);
+       return ISCPUBOARDP(p, BOARD_CYBERSTORM, BOARD_CYBERSTORM_SUB_MK3) || ISCPUBOARDP(p, BOARD_CYBERSTORM, BOARD_CYBERSTORM_SUB_PPC);
 }
-static bool is_blizzardppc(void)
+static bool is_blizzardppc(struct uae_prefs *p)
 {
-       return ISCPUBOARD(BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_PPC);
+       return ISCPUBOARDP(p, BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_PPC);
 }
-static bool is_ppc(void)
+static bool is_ppc(struct uae_prefs *p)
 {
-       return ISCPUBOARD(BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_PPC) || ISCPUBOARD(BOARD_CYBERSTORM, BOARD_CYBERSTORM_SUB_PPC);
+       return ISCPUBOARDP(p, BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_PPC) || ISCPUBOARDP(p, BOARD_CYBERSTORM, BOARD_CYBERSTORM_SUB_PPC);
 }
-static bool is_tekmagic(void)
+static bool is_tekmagic(struct uae_prefs *p)
 {
-       return ISCPUBOARD(BOARD_GVP, BOARD_GVP_SUB_TEKMAGIC);
+       return ISCPUBOARDP(p, BOARD_GVP, BOARD_GVP_SUB_TEKMAGIC);
 }
-static bool is_a2630(void)
+static bool is_a2630(struct uae_prefs *p)
 {
-       return ISCPUBOARD(BOARD_COMMODORE, BOARD_COMMODORE_SUB_A26x0);
+       return ISCPUBOARDP(p, BOARD_COMMODORE, BOARD_COMMODORE_SUB_A26x0);
 }
-static bool is_dkb_12x0(void)
+static bool is_dkb_12x0(struct uae_prefs *p)
 {
-       return ISCPUBOARD(BOARD_DKB, BOARD_DKB_SUB_12x0);
+       return ISCPUBOARDP(p, BOARD_DKB, BOARD_DKB_SUB_12x0);
 }
-static bool is_dkb_wildfire(void)
+static bool is_dkb_wildfire(struct uae_prefs *p)
 {
-       return ISCPUBOARD(BOARD_DKB, BOARD_DKB_SUB_WILDFIRE);
+       return ISCPUBOARDP(p, BOARD_DKB, BOARD_DKB_SUB_WILDFIRE);
 }
-static bool is_mtec_ematrix530(void)
+static bool is_mtec_ematrix530(struct uae_prefs *p)
 {
-       return ISCPUBOARD(BOARD_MTEC, BOARD_MTEC_SUB_EMATRIX530);
+       return ISCPUBOARDP(p, BOARD_MTEC, BOARD_MTEC_SUB_EMATRIX530);
 }
-static bool is_fusionforty(void)
+static bool is_fusionforty(struct uae_prefs *p)
 {
-       return ISCPUBOARD(BOARD_RCS, BOARD_RCS_SUB_FUSIONFORTY);
+       return ISCPUBOARDP(p, BOARD_RCS, BOARD_RCS_SUB_FUSIONFORTY);
 }
-static bool is_apollo(void)
+static bool is_apollo(struct uae_prefs *p)
 {
-       return ISCPUBOARD(BOARD_ACT, BOARD_ACT_SUB_APOLLO);
+       return ISCPUBOARDP(p, BOARD_ACT, BOARD_ACT_SUB_APOLLO);
 }
-static bool is_kupke(void)
+static bool is_kupke(struct uae_prefs *p)
 {
-       return ISCPUBOARD(BOARD_KUPKE, 0);
+       return ISCPUBOARDP(p, BOARD_KUPKE, 0);
 }
-static bool is_sx32pro(void)
+static bool is_sx32pro(struct uae_prefs *p)
 {
-       return ISCPUBOARD(BOARD_DCE, 0);
+       return ISCPUBOARDP(p, BOARD_DCE, 0);
 }
-static bool is_aca500(void)
+static bool is_aca500(struct uae_prefs *p)
 {
-       return ISCPUBOARD(BOARD_IC, BOARD_IC_ACA500);
+       return ISCPUBOARDP(p, BOARD_IC, BOARD_IC_ACA500);
 }
 
 DECLARE_MEMORY_FUNCTIONS(blizzardio);
@@ -374,6 +372,7 @@ static addrbank blizzardf0_bank = {
        ABFLAG_ROM, S_READ, S_WRITE
 };
 
+#if 0
 DECLARE_MEMORY_FUNCTIONS(blizzardram_nojit);
 static addrbank blizzardram_nojit_bank = {
        blizzardram_nojit_lget, blizzardram_nojit_wget, blizzardram_nojit_bget,
@@ -382,6 +381,7 @@ static addrbank blizzardram_nojit_bank = {
        blizzardram_nojit_lget, blizzardram_nojit_wget,
        ABFLAG_RAM | ABFLAG_THREADSAFE, S_READ, S_WRITE
 };
+#endif
 
 DECLARE_MEMORY_FUNCTIONS(blizzardmaprom);
 static addrbank blizzardmaprom_bank = {
@@ -429,6 +429,7 @@ int REGPARAM2 cyberstorm_scsi_ram_check(uaecptr a, uae_u32 b)
 
 MEMORY_FUNCTIONS(blizzardram);
 
+#if 0
 MEMORY_BGET(blizzardram_nojit);
 MEMORY_WGET(blizzardram_nojit);
 MEMORY_LGET(blizzardram_nojit);
@@ -462,6 +463,7 @@ static void REGPARAM2 blizzardram_nojit_bput(uaecptr addr, uae_u32 b)
                return;
        blizzardram_nojit_bank.baseaddr[addr] = b;
 }
+#endif
 
 static void no_rom_protect(void)
 {
@@ -471,15 +473,43 @@ static void no_rom_protect(void)
        protect_roms(false);
 }
 
+static uae_u8 *writeprotect_addr;
+static int writeprotect_size;
+
+static void maprom_unwriteprotect(void)
+{
+       if (!writeprotect_addr)
+               return;
+       if (currprefs.cachesize && !currprefs.comptrustlong)
+               uae_vm_protect(writeprotect_addr, writeprotect_size, UAE_VM_READ_WRITE);
+       writeprotect_addr = NULL;
+}
+
+static void maprom_writeprotect(uae_u8 *addr, int size)
+{
+       maprom_unwriteprotect();
+       writeprotect_addr = addr;
+       writeprotect_size = size;
+       if (currprefs.cachesize && !currprefs.comptrustlong)
+               uae_vm_protect(addr, size, UAE_VM_READ);
+}
+
 MEMORY_BGET(blizzardmaprom2);
 MEMORY_WGET(blizzardmaprom2);
 MEMORY_LGET(blizzardmaprom2);
-MEMORY_BPUT(blizzardmaprom2);
-MEMORY_WPUT(blizzardmaprom2);
-MEMORY_LPUT(blizzardmaprom2);
 MEMORY_CHECK(blizzardmaprom2);
 MEMORY_XLATE(blizzardmaprom2);
 
+static void REGPARAM2 blizzardmaprom2_lput(uaecptr addr, uae_u32 l)
+{
+}
+static void REGPARAM2 blizzardmaprom2_wput(uaecptr addr, uae_u32 l)
+{
+}
+static void REGPARAM2 blizzardmaprom2_bput(uaecptr addr, uae_u32 l)
+{
+}
+
 MEMORY_BGET(blizzardmaprom);
 MEMORY_WGET(blizzardmaprom);
 MEMORY_LGET(blizzardmaprom);
@@ -489,12 +519,15 @@ MEMORY_XLATE(blizzardmaprom);
 static void REGPARAM2 blizzardmaprom_lput(uaecptr addr, uae_u32 l)
 {
        uae_u32 *m;
-       if (is_blizzard2060() && !maprom_state)
+       if (is_blizzard2060(&currprefs) && !maprom_state)
                return;
        addr &= blizzardmaprom_bank.mask;
        m = (uae_u32 *)(blizzardmaprom_bank.baseaddr + addr);
        do_put_mem_long(m, l);
-       if (maprom_state && !(addr & 0x80000)) {
+#if MAPROM_DEBUG
+       write_log(_T("LPUT %08x %08x %d %08x\n"), addr, l, maprom_state, M68K_GETPC);
+#endif
+       if (maprom_state > 0 && !(addr & 0x80000)) {
                no_rom_protect();
                m = (uae_u32 *)(kickmem_bank.baseaddr + addr);
                do_put_mem_long(m, l);
@@ -503,12 +536,15 @@ static void REGPARAM2 blizzardmaprom_lput(uaecptr addr, uae_u32 l)
 static void REGPARAM2 blizzardmaprom_wput(uaecptr addr, uae_u32 w)
 {
        uae_u16 *m;
-       if (is_blizzard2060() && !maprom_state)
+       if (is_blizzard2060(&currprefs) && !maprom_state)
                return;
        addr &= blizzardmaprom_bank.mask;
        m = (uae_u16 *)(blizzardmaprom_bank.baseaddr + addr);
        do_put_mem_word(m, w);
-       if (maprom_state && !(addr & 0x80000)) {
+#if MAPROM_DEBUG
+       write_log(_T("WPUT %08x %08x %d\n"), addr, w, maprom_state);
+#endif
+       if (maprom_state > 0 && !(addr & 0x80000)) {
                no_rom_protect();
                m = (uae_u16 *)(kickmem_bank.baseaddr + addr);
                do_put_mem_word(m, w);
@@ -516,11 +552,14 @@ static void REGPARAM2 blizzardmaprom_wput(uaecptr addr, uae_u32 w)
 }
 static void REGPARAM2 blizzardmaprom_bput(uaecptr addr, uae_u32 b)
 {
-       if (is_blizzard2060() && !maprom_state)
+       if (is_blizzard2060(&currprefs) && !maprom_state)
                return;
        addr &= blizzardmaprom_bank.mask;
        blizzardmaprom_bank.baseaddr[addr] = b;
-       if (maprom_state && !(addr & 0x80000)) {
+#if MAPROM_DEBUG
+       write_log(_T("LPUT %08x %08x %d\n"), addr, b, maprom_state);
+#endif
+       if (maprom_state > 0 && !(addr & 0x80000)) {
                no_rom_protect();
                kickmem_bank.baseaddr[addr] = b;
        }
@@ -531,7 +570,7 @@ MEMORY_XLATE(blizzardea);
 
 static void blizzardf0_slow(int size)
 {
-       if (is_blizzard() || is_blizzardppc() || is_blizzard2060()) {
+       if (is_blizzard(&currprefs) || is_blizzardppc(&currprefs) || is_blizzard2060(&currprefs)) {
                if (size == 4)
                        regs.memory_waitstate_cycles += F0_WAITSTATES * 6;
                else if (size == 2)
@@ -556,19 +595,19 @@ static uae_u32 REGPARAM2 blizzardf0_bget(uaecptr addr)
 
        blizzardf0_slow(1);
 
-       if (is_csmk3() || is_blizzardppc()) {
+       if (is_csmk3(&currprefs) || is_blizzardppc(&currprefs)) {
                if (flash_unlocked) {
                        return flash_read(flashrom, addr);
                }
-       } else if (is_csmk2()) {
+       } else if (is_csmk2(&currprefs)) {
                addr &= 65535;
                addr += 65536;
                return flash_read(flashrom, addr);
-       } else if (is_csmk1()) {
+       } else if (is_csmk1(&currprefs)) {
                addr &= 65535;
                addr += 65536;
                return flash_read(flashrom, addr);
-       } else if (is_dkb_wildfire()) {
+       } else if (is_dkb_wildfire(&currprefs)) {
                if (flash_unlocked) {
                        if (addr & 1)
                                return flash_read(flashrom2, addr);
@@ -597,7 +636,7 @@ static uae_u32 REGPARAM2 blizzardf0_wget(uaecptr addr)
        uae_u16 *m, v;
 
        blizzardf0_slow(2);
-       if (is_dkb_wildfire() && flash_unlocked) {
+       if (is_dkb_wildfire(&currprefs) && flash_unlocked) {
                v = blizzardf0_bget(addr + 0) << 8;
                v |= blizzardf0_bget(addr + 1);
        } else {
@@ -612,21 +651,21 @@ static void REGPARAM2 blizzardf0_bput(uaecptr addr, uae_u32 b)
 {
        blizzardf0_slow(1);
 
-       if (is_csmk3() || is_blizzardppc()) {
+       if (is_csmk3(&currprefs) || is_blizzardppc(&currprefs)) {
                if (flash_unlocked) {
                        flash_write(flashrom, addr, b);
                }
-       } else if (is_csmk2()) {
+       } else if (is_csmk2(&currprefs)) {
                addr &= 65535;
                addr += 65536;
                addr &= ~3;
                addr |= csmk2_flashaddressing;
                flash_write(flashrom, addr, b);
-       } else if (is_csmk1()) {
+       } else if (is_csmk1(&currprefs)) {
                addr &= 65535;
                addr += 65536;
                flash_write(flashrom, addr, b);
-       } else if (is_dkb_wildfire()) {
+       } else if (is_dkb_wildfire(&currprefs)) {
                if (flash_unlocked) {
                        if (addr & 1)
                                flash_write(flashrom2, addr, b);
@@ -642,7 +681,7 @@ static void REGPARAM2 blizzardf0_lput(uaecptr addr, uae_u32 b)
 static void REGPARAM2 blizzardf0_wput(uaecptr addr, uae_u32 b)
 {
        blizzardf0_slow(2);
-       if (is_dkb_wildfire()) {
+       if (is_dkb_wildfire(&currprefs)) {
                blizzardf0_bput(addr + 0, b >> 8);
                blizzardf0_bput(addr + 1, b >> 0);
        }
@@ -676,19 +715,19 @@ static uae_u32 REGPARAM2 blizzardea_bget(uaecptr addr)
        uae_u8 v;
 
        addr &= blizzardea_bank.mask;
-       if (is_tekmagic()) {
+       if (is_tekmagic(&currprefs)) {
                cpuboard_non_byte_ea = true;
                v = cpuboard_ncr710_io_bget(addr);
-       } else if (is_blizzard2060() && addr >= BLIZZARD_2060_SCSI_OFFSET) {
+       } else if (is_blizzard2060(&currprefs) && addr >= BLIZZARD_2060_SCSI_OFFSET) {
                v = cpuboard_ncr9x_scsi_get(addr);
-       } else if (is_blizzard1230mk2() && addr >= 0x10000 && (currprefs.cpuboard_settings & 2)) {
+       } else if (is_blizzard1230mk2(&currprefs) && addr >= 0x10000 && (currprefs.cpuboard_settings & 2)) {
                v = cpuboard_ncr9x_scsi_get(addr);
-       } else if (is_blizzard()) {
+       } else if (is_blizzard(&currprefs)) {
                if (addr & BLIZZARD_SCSI_KIT_SCSI_OFFSET)
                        v = cpuboard_ncr9x_scsi_get(addr);
                else
                        v = blizzardea_bank.baseaddr[addr];
-       } else if (is_csmk1()) {
+       } else if (is_csmk1(&currprefs)) {
                if (addr >= CYBERSTORM_MK1_SCSI_OFFSET) {
                        v = cpuboard_ncr9x_scsi_get(addr);
                } else if (flash_active(flashrom, addr)) {
@@ -696,7 +735,7 @@ static uae_u32 REGPARAM2 blizzardea_bget(uaecptr addr)
                } else {
                        v = blizzardea_bank.baseaddr[addr];
                }
-       } else if (is_csmk2()) {
+       } else if (is_csmk2(&currprefs)) {
                if (addr >= CYBERSTORM_MK2_SCSI_OFFSET) {
                        v = cpuboard_ncr9x_scsi_get(addr);
                } else if (flash_active(flashrom, addr)) {
@@ -704,7 +743,7 @@ static uae_u32 REGPARAM2 blizzardea_bget(uaecptr addr)
                } else {
                        v = blizzardea_bank.baseaddr[addr];
                }
-       } else if (is_mtec_ematrix530()) {
+       } else if (is_mtec_ematrix530(&currprefs)) {
                v = blizzardea_bank.baseaddr[addr];
                if ((addr & 0xf800) == 0xe800) {
                        if ((addr & 3) < 2) {
@@ -751,22 +790,22 @@ static void REGPARAM2 blizzardea_wput(uaecptr addr, uae_u32 w)
 static void REGPARAM2 blizzardea_bput(uaecptr addr, uae_u32 b)
 {
        addr &= blizzardea_bank.mask;
-       if (is_tekmagic()) {
+       if (is_tekmagic(&currprefs)) {
                cpuboard_non_byte_ea = true;
                cpuboard_ncr710_io_bput(addr, b);
-       } else if (is_blizzard1230mk2() && addr >= 0x10000 && (currprefs.cpuboard_settings & 2)) {
+       } else if (is_blizzard1230mk2(&currprefs) && addr >= 0x10000 && (currprefs.cpuboard_settings & 2)) {
                cpuboard_ncr9x_scsi_put(addr, b);
-       } else if (is_blizzard2060() && addr >= BLIZZARD_2060_SCSI_OFFSET) {
+       } else if (is_blizzard2060(&currprefs) && addr >= BLIZZARD_2060_SCSI_OFFSET) {
                cpuboard_ncr9x_scsi_put(addr, b);
-       } else if ((is_blizzard()) && addr >= BLIZZARD_SCSI_KIT_SCSI_OFFSET) {
+       } else if ((is_blizzard(&currprefs)) && addr >= BLIZZARD_SCSI_KIT_SCSI_OFFSET) {
                cpuboard_ncr9x_scsi_put(addr, b);
-       } else if (is_csmk1()) {
+       } else if (is_csmk1(&currprefs)) {
                if (addr >= CYBERSTORM_MK1_SCSI_OFFSET) {
                        cpuboard_ncr9x_scsi_put(addr, b);
                } else {
                        flash_write(flashrom, addr, b);
                }
-       } else if (is_csmk2()) {
+       } else if (is_csmk2(&currprefs)) {
                if (addr >= CYBERSTORM_MK2_SCSI_OFFSET) {
                        cpuboard_ncr9x_scsi_put(addr, b);
                }  else {
@@ -774,7 +813,7 @@ static void REGPARAM2 blizzardea_bput(uaecptr addr, uae_u32 b)
                        addr |= csmk2_flashaddressing;
                        flash_write(flashrom, addr, b);
                }
-       } else if (is_mtec_ematrix530()) {
+       } else if (is_mtec_ematrix530(&currprefs)) {
                if ((addr & 0xf800) == 0xe800) {
                        if ((addr & 3) < 2) {
                                map_banks(&dummy_bank, 0x10000000 >> 16, 0x8000000 >> 16, 0);
@@ -839,9 +878,9 @@ static void blizzard_copymaprom(void)
                reload_roms();
        } else {
                uae_u8 *src = NULL;
-               if (is_blizzard()) {
-                       src = get_real_address(BLIZZARD_MAPROM_BASE);
-               } else if (is_blizzard1230mk2() || is_blizzard1230mk3()) {
+               if (is_blizzardppc(&currprefs)) {
+                       src = blizzardram_bank.baseaddr + cpuboard_size - 524288;
+               } else {
                        src = blizzardmaprom_bank.baseaddr;
                }
                if (src) {
@@ -851,9 +890,12 @@ static void blizzard_copymaprom(void)
                        protect_roms(true);
                        set_roms_modified();
                }
-               if (is_blizzard1230mk2() && cpuboard_size >= 64 * 1024 * 1024) {
+               if (is_blizzard1230mk2(&currprefs) && cpuboard_size >= 64 * 1024 * 1024) {
                        map_banks(&blizzardmaprom_bank, BLIZZARDMK2_MAPROM_BASE >> 16, 524288 >> 16, 0);
                }
+               if (is_blizzard(&currprefs) && cpuboard_size >= 256 * 1024 * 1024) {
+                       map_banks(&blizzardmaprom_bank, BLIZZARDMK4_MAPROM_BASE >> 16, 524288 >> 16, 0);
+               }
        }
 }
 static void cyberstorm_copymaprom(void)
@@ -894,7 +936,7 @@ static void cyberstormmk1_copymaprom(void)
 
 bool cpuboard_is_ppcboard_irq(void)
 {
-       if (is_csmk3() || is_blizzardppc()) {
+       if (is_csmk3(&currprefs) || is_blizzardppc(&currprefs)) {
                if (!(io_reg[CSIII_REG_IRQ] & (P5_IRQ_SCSI_EN | P5_IRQ_SCSI))) {
                        return true;
                } else if (!(io_reg[CSIII_REG_IRQ] & (P5_IRQ_PPC_1 | P5_IRQ_PPC_2))) {
@@ -906,7 +948,7 @@ bool cpuboard_is_ppcboard_irq(void)
 
 void cpuboard_rethink(void)
 {
-       if (is_csmk3() || is_blizzardppc()) {
+       if (is_csmk3(&currprefs) || is_blizzardppc(&currprefs)) {
                if (!(io_reg[CSIII_REG_IRQ] & (P5_IRQ_SCSI_EN | P5_IRQ_SCSI))) {
                        INTREQ_0(0x8000 | 0x0008);
                        if (currprefs.cachesize)
@@ -929,21 +971,68 @@ static void blizzardppc_maprom(void)
 {
        if (cpuboard_size <= 2 * 524288)
                return;
+
+       map_banks(&dummy_bank, CYBERSTORM_MAPROM_BASE >> 16, 524288 >> 16, 0);
+
+       if (blizzardmaprom_bank_mapped)
+               mapped_free(&blizzardmaprom_bank);
+       if (blizzardmaprom2_bank_mapped)
+               mapped_free(&blizzardmaprom2_bank);
+
+       // BPPC write protects MAP ROM region. CSPPC does not.
+
        if (maprom_state) {
-               map_banks(&blizzardmaprom2_bank, CYBERSTORM_MAPROM_BASE >> 16, 524288 >> 16, 0);
+               blizzardmaprom_bank.baseaddr = blizzardram_bank.baseaddr + cpuboard_size - 2 * 524288;
+
+               blizzardmaprom2_bank.baseaddr = blizzardram_bank.baseaddr + cpuboard_size - 524288;
+               blizzardmaprom2_bank.start = blizzardram_bank.start + cpuboard_size - 524288;
+               blizzardmaprom2_bank.allocated = 524288;
+               blizzardmaprom2_bank.mask = 524288 - 1;
+               blizzardmaprom2_bank.flags |= ABFLAG_INDIRECT | ABFLAG_NOALLOC;
+               mapped_malloc(&blizzardmaprom2_bank);
+               blizzardmaprom2_bank_mapped = true;
+               map_banks(&blizzardmaprom2_bank, blizzardmaprom2_bank.start >> 16, 524288 >> 16, 0);
+
+               maprom_writeprotect(blizzardmaprom2_bank.baseaddr, 524288);
+
        } else {
-               map_banks(&blizzardmaprom_bank, CYBERSTORM_MAPROM_BASE >> 16, 524288 >> 16, 0);
+
+               blizzardmaprom_bank.baseaddr = blizzardram_bank.baseaddr + cpuboard_size - 524288;
+               blizzardmaprom2_bank.baseaddr = NULL;
+               maprom_unwriteprotect();
+
        }
+
+       blizzardmaprom_bank.start = CYBERSTORM_MAPROM_BASE;
+       blizzardmaprom_bank.allocated = 524288;
+       blizzardmaprom_bank.mask = 524288 - 1;
+       blizzardmaprom_bank.flags |= ABFLAG_INDIRECT | ABFLAG_NOALLOC;
+       mapped_malloc(&blizzardmaprom_bank);
+       blizzardmaprom_bank_mapped = true;
+       map_banks(&blizzardmaprom_bank, CYBERSTORM_MAPROM_BASE >> 16, 524288 >> 16, 0);
 }
+
 static void cyberstorm_maprom(void)
 {
        if (a3000hmem_bank.allocated <= 2 * 524288)
                return;
-       if (maprom_state && is_ppc()) {
-               map_banks(&blizzardmaprom2_bank, CYBERSTORM_MAPROM_BASE >> 16, 524288 >> 16, 0);
+
+       map_banks(&dummy_bank, CYBERSTORM_MAPROM_BASE >> 16, 524288 >> 16, 0);
+       if (blizzardmaprom_bank_mapped)
+               mapped_free(&blizzardmaprom_bank);
+       if (maprom_state) {
+               blizzardmaprom_bank.baseaddr = a3000hmem_bank.baseaddr + a3000hmem_bank.allocated - 2 * 524288;
        } else {
-               map_banks(&blizzardmaprom_bank, CYBERSTORM_MAPROM_BASE >> 16, 524288 >> 16, 0);
+               blizzardmaprom_bank.baseaddr = a3000hmem_bank.baseaddr + a3000hmem_bank.allocated - 524288;
        }
+       blizzardmaprom_bank.start = CYBERSTORM_MAPROM_BASE;
+       blizzardmaprom_bank.allocated = 524288;
+       blizzardmaprom_bank.mask = 524288 - 1;
+       blizzardmaprom_bank.flags |= ABFLAG_INDIRECT | ABFLAG_NOALLOC;
+       mapped_malloc(&blizzardmaprom_bank);
+       blizzardmaprom_bank_mapped = true;
+
+       map_banks(&blizzardmaprom_bank, CYBERSTORM_MAPROM_BASE >> 16, 524288 >> 16, 0);
 }
 
 static void cyberstormmk2_maprom(void)
@@ -974,7 +1063,7 @@ static uae_u32 REGPARAM2 blizzardio_bget(uaecptr addr)
 {
        uae_u8 v = 0;
        //write_log(_T("CS IO XBGET %08x=%02X PC=%08x\n"), addr, v & 0xff, M68K_GETPC);
-       if (is_csmk3() || is_blizzardppc()) {
+       if (is_csmk3(&currprefs) || is_blizzardppc(&currprefs)) {
                uae_u32 bank = addr & 0x10000;
                if (bank == 0) {
                        int reg = (addr & 0xff) / 8;
@@ -982,8 +1071,11 @@ static uae_u32 REGPARAM2 blizzardio_bget(uaecptr addr)
                        if (reg == CSIII_REG_LOCK) {
                                v &= 0x01;
                                v |= 0x10;
-                               if (is_blizzardppc())
+                               if (is_blizzardppc(&currprefs)) {
                                        v |= 0x08; // BPPC identification
+                                       if (maprom_state)
+                                               v |= 0x04;
+                               }
                        } else if (reg == CSIII_REG_IRQ)  {
                                v &= 0x3f;
                        } else if (reg == CSIII_REG_INT) {
@@ -1011,10 +1103,10 @@ static uae_u32 REGPARAM2 blizzardio_bget(uaecptr addr)
 }
 static uae_u32 REGPARAM2 blizzardio_wget(uaecptr addr)
 {
-       if (is_csmk3() || is_blizzardppc()) {
+       if (is_csmk3(&currprefs) || is_blizzardppc(&currprefs)) {
                ;//write_log(_T("CS IO WGET %08x\n"), addr);
                //activate_debugger();
-       } else if (is_aca500()) {
+       } else if (is_aca500(&currprefs)) {
                addr &= 0x3f000;
                switch (addr)
                {
@@ -1055,7 +1147,7 @@ static uae_u32 REGPARAM2 blizzardio_wget(uaecptr addr)
 static uae_u32 REGPARAM2 blizzardio_lget(uaecptr addr)
 {
        write_log(_T("CS IO LGET %08x PC=%08x\n"), addr, M68K_GETPC);
-       if (is_blizzard2060() && mapromconfigured()) {
+       if (is_blizzard2060(&currprefs) && mapromconfigured()) {
                if (addr & 0x10000000) {
                        maprom_state = 0;
                } else {
@@ -1069,16 +1161,16 @@ static void REGPARAM2 blizzardio_bput(uaecptr addr, uae_u32 v)
 #if CPUBOARD_IO_LOG > 1
        write_log(_T("CS IO XBPUT %08x %02x PC=%08x\n"), addr, v & 0xff, M68K_GETPC);
 #endif
-       if (is_fusionforty()) {
+       if (is_fusionforty(&currprefs)) {
                write_log(_T("FusionForty IO XBPUT %08x %02x PC=%08x\n"), addr, v & 0xff, M68K_GETPC);
-       } else if (is_csmk2()) {
+       } else if (is_csmk2(&currprefs)) {
                csmk2_flashaddressing = addr & 3;
                if (addr == 0x880000e3 && v == 0x2a) {
                        maprom_state = 1;
                        write_log(_T("CSMKII: MAPROM enabled\n"));
                        cyberstormmk2_copymaprom();
                }
-       } else if (is_blizzard() || is_blizzard1230mk2() || is_blizzard1230mk3()) {
+       } else if (is_blizzard(&currprefs) || is_blizzard1230mk2(&currprefs) || is_blizzard1230mk3(&currprefs)) {
                if ((addr & 65535) == (BLIZZARD_MAPROM_ENABLE & 65535)) {
                        if (v != 0x42 || maprom_state || !mapromconfigured())
                                return;
@@ -1086,14 +1178,14 @@ static void REGPARAM2 blizzardio_bput(uaecptr addr, uae_u32 v)
                        write_log(_T("Blizzard: MAPROM enabled\n"));
                        blizzard_copymaprom();
                }
-       } else if (is_csmk3() || is_blizzardppc()) {
+       } else if (is_csmk3(&currprefs) || is_blizzardppc(&currprefs)) {
 #if CPUBOARD_IO_LOG > 0
                write_log(_T("CS IO BPUT %08x %02x PC=%08x\n"), addr, v & 0xff, M68K_GETPC);
 #endif
                uae_u32 bank = addr & 0x10000;
                if (bank == 0) {
                        addr &= 0xff;
-                       if (is_blizzardppc()) {
+                       if (is_blizzardppc(&currprefs)) {
                                if (addr == BPPC_UNLOCK_FLASH && v == BPPC_MAGIC_UNLOCK_VALUE) {
                                        flash_unlocked = 1;
                                        write_log(_T("BPPC: flash unlocked\n"));
@@ -1102,7 +1194,7 @@ static void REGPARAM2 blizzardio_bput(uaecptr addr, uae_u32 v)
                                        write_log(_T("BPPC: flash locked\n"));
                                } else if (addr == BPPC_MAPROM_ON) {
                                        write_log(_T("BPPC: maprom enabled\n"));
-                                       maprom_state = 1;
+                                       maprom_state = -1;
                                        cyberstorm_copymaprom();
                                        blizzardppc_maprom();
                                } else if (addr == BPPC_MAPROM_OFF) {
@@ -1167,7 +1259,7 @@ static void REGPARAM2 blizzardio_bput(uaecptr addr, uae_u32 v)
                                                if ((regval & P5_SCSI_RESET) != (oldval & P5_SCSI_RESET))
                                                        write_log(_T("CS: SCSI reset cleared\n"));
                                                map_banks(&blizzardf0_bank, 0xf00000 >> 16, 0x40000 >> 16, 0);
-                                               if (is_blizzardppc() || flash_size(flashrom) >= 262144) {
+                                               if (is_blizzardppc(&currprefs) || flash_size(flashrom) >= 262144) {
                                                        map_banks(&ncr_bank_generic, 0xf40000 >> 16, 0x10000 >> 16, 0);
                                                } else {
                                                        map_banks(&ncr_bank_cyberstorm, 0xf40000 >> 16, 0x10000 >> 16, 0);
@@ -1249,8 +1341,8 @@ static void REGPARAM2 blizzardio_bput(uaecptr addr, uae_u32 v)
                                                write_log(_T("CS: IRQ: %02x\n"), regval);
 #endif
                                } else if (addr == CSIII_REG_SHADOW) {
-                                       if (is_csmk3() && ((oldval ^ regval) & 1)) {
-                                               maprom_state = (regval & 1) ? 0 : 1;
+                                       if (is_csmk3(&currprefs) && ((oldval ^ regval) & 1)) {
+                                               maprom_state = (regval & P5_SHADOW) ? 0 : -1;
                                                write_log(_T("CyberStorm MAPROM = %d\n"), maprom_state);
                                                cyberstorm_copymaprom();
                                                cyberstorm_maprom();
@@ -1270,9 +1362,9 @@ static void REGPARAM2 blizzardio_bput(uaecptr addr, uae_u32 v)
 }
 static void REGPARAM2 blizzardio_wput(uaecptr addr, uae_u32 v)
 {
-       if (is_fusionforty()) {
+       if (is_fusionforty(&currprefs)) {
                write_log(_T("FusionForty IO WPUT %08x %04x\n"), addr, v);
-       } else if (is_blizzard()) {
+       } else if (is_blizzard(&currprefs)) {
                write_log(_T("CS IO WPUT %08x %04x\n"), addr, v);
                if((addr & 65535) == (BLIZZARD_BOARD_DISABLE & 65535)) {
                        if (v != 0xcafe)
@@ -1280,9 +1372,9 @@ static void REGPARAM2 blizzardio_wput(uaecptr addr, uae_u32 v)
                        write_log(_T("Blizzard: board disable!\n"));
                        cpu_halt(CPU_HALT_ACCELERATOR_CPU_FALLBACK); // not much choice..
                }
-       } else if (is_csmk3() || is_blizzardppc()) {
+       } else if (is_csmk3(&currprefs) || is_blizzardppc(&currprefs)) {
                write_log(_T("CS IO WPUT %08x %04x\n"), addr, v);
-       } else if (is_csmk2()) {
+       } else if (is_csmk2(&currprefs)) {
                write_log(_T("CS IO WPUT %08x %04x\n"), addr, v);
                if (addr == CSMK2_BOARD_DISABLE) {
                        if (v != 0xcafe)
@@ -1295,13 +1387,13 @@ static void REGPARAM2 blizzardio_wput(uaecptr addr, uae_u32 v)
 static void REGPARAM2 blizzardio_lput(uaecptr addr, uae_u32 v)
 {
        write_log(_T("CS IO LPUT %08x %08x\n"), addr, v);
-       if (is_csmk1()) {
+       if (is_csmk1(&currprefs)) {
                if (addr == 0x80f80000) {
                        maprom_state = 1;
                        cyberstormmk1_copymaprom();
                }
        }
-       if (is_blizzard2060() && mapromconfigured()) {
+       if (is_blizzard2060(&currprefs) && mapromconfigured()) {
                if (addr & 0x10000000) {
                        maprom_state = 0;
                } else {
@@ -1315,7 +1407,7 @@ void cpuboard_hsync(void)
        // we should call check_ppc_int_lvl() immediately
        // after PPC CPU's interrupt flag is cleared but this
        // should be fast enough for now
-       if (is_csmk3() || is_blizzardppc()) {
+       if (is_csmk3(&currprefs) || is_blizzardppc(&currprefs)) {
                check_ppc_int_lvl();
        }
 }
@@ -1333,39 +1425,21 @@ void cpuboard_map(void)
 {
        if (!currprefs.cpuboard_type)
                return;
-       if (is_blizzard1230mk2() || is_blizzard1230mk3()) {
+       if (is_blizzard1230mk2(&currprefs) || is_blizzard1230mk3(&currprefs)) {
                map_banks(&blizzardram_bank, blizzardram_bank.start >> 16, cpuboard_size >> 16, 0);
                map_banks(&blizzardio_bank, BLIZZARD_MAPROM_ENABLE >> 16, 65536 >> 16, 0);
-               if (is_blizzard1230mk2 () && cpuboard_size < 64 * 1024 * 1024) {
+               if (is_blizzard1230mk2 (&currprefs) && cpuboard_size < 64 * 1024 * 1024) {
                        map_banks(&blizzardmaprom_bank, BLIZZARDMK2_MAPROM_BASE >> 16, 524288 >> 16, 0);
                }
-               if (is_blizzard1230mk3()) {
+               if (is_blizzard1230mk3(&currprefs)) {
                        map_banks(&blizzardmaprom_bank, BLIZZARDMK3_MAPROM_BASE >> 16, 524288 >> 16, 0);
                }
        }
-       if (is_blizzard() || is_blizzardppc()) {
-               if (cpuboard_size) {
-                       if (cpuboard_size < 256 * 1024 * 1024) {
-                               if (blizzard_jit) {
-                                       map_banks(&blizzardram_bank, blizzardram_bank.start >> 16, cpuboard_size >> 16, 0);
-                                       map_banks(&blizzardram_bank, BLIZZARD_RAM_BASE_68 >> 16, cpuboard_size >> 16, 0);
-                               } else {
-                                       for (int i = 0; i < 0x08000000; i += cpuboard_size) {
-                                               map_banks_nojitdirect(&blizzardram_nojit_bank, (BLIZZARD_RAM_BASE_48 + i)  >> 16, cpuboard_size >> 16, 0);
-                                               map_banks_nojitdirect(&blizzardram_nojit_bank, (BLIZZARD_RAM_BASE_68 + i) >> 16, cpuboard_size >> 16, 0);
-                                       }
-                                       if (mapromconfigured() && !is_blizzardppc()) {
-                                               for (int i = 0; i < 0x08000000; i += cpuboard_size) {
-                                                       map_banks_nojitdirect(&blizzardmaprom_bank, (BLIZZARD_RAM_BASE_48 + i + cpuboard_size - 524288) >> 16, 524288 >> 16, 0);
-                                                       map_banks_nojitdirect(&blizzardmaprom_bank, (BLIZZARD_RAM_BASE_68 + i + cpuboard_size - 524288) >> 16, 524288 >> 16, 0);
-                                               }
-                                       }
-                               }
-                       } else {
-                               map_banks(&blizzardram_bank, blizzardram_bank.start >> 16, cpuboard_size >> 16, 0);
-                       }
-               }
-               if (!is_blizzardppc()) {
+       if (is_blizzard(&currprefs) || is_blizzardppc(&currprefs)) {
+               map_banks(&blizzardram_bank, blizzardram_bank.start >> 16, cpuboard_size >> 16, 0);
+               if (!is_blizzardppc(&currprefs)) {
+                       if (cpuboard_size < 256 * 1024 * 1024)
+                               map_banks(&blizzardmaprom_bank, BLIZZARDMK4_MAPROM_BASE >> 16, 524288 >> 16, 0);
                        map_banks(&blizzardf0_bank, 0xf00000 >> 16, 65536 >> 16, 0);
                        map_banks(&blizzardio_bank, BLIZZARD_MAPROM_ENABLE >> 16, 65536 >> 16, 0);
                        map_banks(&blizzardio_bank, BLIZZARD_BOARD_DISABLE >> 16, 65536 >> 16, 0);
@@ -1375,45 +1449,45 @@ void cpuboard_map(void)
                        blizzardppc_maprom();
                }
        }
-       if (is_csmk3()) {
+       if (is_csmk3(&currprefs)) {
                map_banks(&blizzardf0_bank, 0xf00000 >> 16, 0x40000 >> 16, 0);
                map_banks(&blizzardio_bank, 0xf50000 >> 16, (3 * 65536) >> 16, 0);
                cyberstorm_maprom();
        }
-       if (is_csmk2()) {
+       if (is_csmk2(&currprefs)) {
                map_banks(&blizzardio_bank, 0x88000000 >> 16, 65536 >> 16, 0);
                map_banks(&blizzardio_bank, 0x83000000 >> 16, 65536 >> 16, 0);
                map_banks(&blizzardf0_bank, 0xf00000 >> 16, 65536 >> 16, 0);
                cyberstormmk2_maprom();
        }
-       if (is_csmk1()) {
+       if (is_csmk1(&currprefs)) {
                map_banks(&blizzardio_bank, 0x80f80000 >> 16, 65536 >> 16, 0);
                map_banks(&blizzardf0_bank, 0xf00000 >> 16, 65536 >> 16, 0);
                map_banks(&blizzardmaprom_bank, 0x07f80000 >> 16, 524288 >> 16, 0);
        }
-       if (is_blizzard2060()) {
+       if (is_blizzard2060(&currprefs)) {
                map_banks(&blizzardf0_bank, 0xf00000 >> 16, 65536 >> 16, 0);
                map_banks(&blizzardio_bank, 0x80000000 >> 16, 0x10000000 >> 16, 0);
                if (mapromconfigured())
                        map_banks_nojitdirect(&blizzardmaprom_bank, (a3000hmem_bank.start + a3000hmem_bank.allocated - 524288) >> 16, 524288 >> 16, 0);
        }
-       if (is_tekmagic()) {
+       if (is_tekmagic(&currprefs)) {
                map_banks(&blizzardf0_bank, 0xf00000 >> 16, 131072 >> 16, 0);
                map_banks(&blizzardea_bank, 0xf40000 >> 16, 65536 >> 16, 0);
        }
-       if (is_fusionforty()) {
+       if (is_fusionforty(&currprefs)) {
                map_banks(&blizzardf0_bank, 0x00f40000 >> 16, 131072 >> 16, 0);
                map_banks(&blizzardf0_bank, 0x05000000 >> 16, 131072 >> 16, 0);
                map_banks(&blizzardio_bank, 0x021d0000 >> 16, 65536 >> 16, 0);
                map_banks(&blizzardram_bank, blizzardram_bank.start >> 16, cpuboard_size >> 16, 0);
        }
-       if (is_apollo()) {
+       if (is_apollo(&currprefs)) {
                map_banks(&blizzardf0_bank, 0xf00000 >> 16, 131072 >> 16, 0);
        }
-       if (is_dkb_wildfire()) {
+       if (is_dkb_wildfire(&currprefs)) {
                map_banks(&blizzardf0_bank, 0xf00000 >> 16, 0x80000 >> 16, 0);
        }
-       if (is_dkb_12x0()) {
+       if (is_dkb_12x0(&currprefs)) {
                if (cpuboard_size >= 4 * 1024 * 1024) {
                        if (cpuboard_size <= 0x4000000) {
                                map_banks(&blizzardram_bank, blizzardram_bank.start >> 16, 0x4000000 >> 16, cpuboard_size >> 16);
@@ -1422,7 +1496,7 @@ void cpuboard_map(void)
                        }
                }
        }
-       if (is_aca500()) {
+       if (is_aca500(&currprefs)) {
                map_banks(&blizzardf0_bank, 0xf00000 >> 16, 524288 >> 16, 0);
                map_banks(&blizzardf0_bank, 0xa00000 >> 16, 524288 >> 16, 0);
                map_banks(&blizzardio_bank, 0xb00000 >> 16, 262144 >> 16, 0);
@@ -1432,14 +1506,17 @@ void cpuboard_map(void)
 void cpuboard_reset(void)
 {
        bool hardreset = is_hardreset();
+#if 0
        if (is_blizzard() || is_blizzardppc())
                canbang = 0;
+#endif
        configured = false;
        delayed_rom_protect = 0;
        currprefs.cpuboardmem1_size = changed_prefs.cpuboardmem1_size;
-       if (hardreset || (!mapromconfigured() && (is_blizzard() || is_blizzard2060())))
+       maprom_unwriteprotect();
+       if (hardreset || (!mapromconfigured() && (is_blizzard(&currprefs) || is_blizzard2060(&currprefs))))
                maprom_state = 0;
-       if (is_csmk3() || is_blizzardppc()) {
+       if (is_csmk3(&currprefs) || is_blizzardppc(&currprefs)) {
                if (hardreset)
                        memset(io_reg, 0x7f, sizeof io_reg);
                io_reg[CSIII_REG_RESET] = 0x7f;
@@ -1472,9 +1549,10 @@ void cpuboard_cleanup(void)
        zfile_fclose(flashrom_file);
        flashrom_file = NULL;
 
-       if (blizzard_jit) {
+//     if (blizzard_jit) {
                mapped_free(&blizzardram_bank);
-       } else {
+#if 0
+} else {
                if (blizzardram_nojit_bank.baseaddr) {
 #ifdef CPU_64_BIT
                        uae_vm_free(blizzardram_nojit_bank.baseaddr, blizzardram_nojit_bank.allocated);
@@ -1483,13 +1561,15 @@ void cpuboard_cleanup(void)
 #endif
                }
        }
+#endif
        if (blizzardmaprom_bank_mapped)
                mapped_free(&blizzardmaprom_bank);
        if (blizzardmaprom2_bank_mapped)
                mapped_free(&blizzardmaprom2_bank);
+       maprom_unwriteprotect();
 
        blizzardram_bank.baseaddr = NULL;
-       blizzardram_nojit_bank.baseaddr = NULL;
+//     blizzardram_nojit_bank.baseaddr = NULL;
        blizzardmaprom_bank.baseaddr = NULL;
        blizzardmaprom2_bank.baseaddr = NULL;
        blizzardmaprom_bank_mapped = false;
@@ -1507,32 +1587,27 @@ void cpuboard_cleanup(void)
        blizzardmaprom2_bank.flags &= ~(ABFLAG_INDIRECT | ABFLAG_NOALLOC);
 }
 
-void cpuboard_init(void)
+static void cpuboard_init_2(void)
 {
        if (!currprefs.cpuboard_type)
                return;
 
-       if (cpuboard_size == currprefs.cpuboardmem1_size)
-               return;
-
-       cpuboard_cleanup();
-
        cpuboard_size = currprefs.cpuboardmem1_size;
 
-       if (is_kupke() || is_mtec_ematrix530() || is_sx32pro()) {
+       if (is_kupke(&currprefs) || is_mtec_ematrix530(&currprefs) || is_sx32pro(&currprefs)) {
                // plain 64k autoconfig, nothing else.
                blizzardea_bank.allocated = 65536;
                blizzardea_bank.mask = blizzardea_bank.allocated - 1;
                mapped_malloc(&blizzardea_bank);
 
-       } else if (is_aca500()) {
+       } else if (is_aca500(&currprefs)) {
 
                blizzardf0_bank.start = 0x00f00000;
                blizzardf0_bank.allocated = 524288;
                blizzardf0_bank.mask = blizzardf0_bank.allocated - 1;
                mapped_malloc(&blizzardf0_bank);
 
-       } else if (is_a2630()) {
+       } else if (is_a2630(&currprefs)) {
 
                blizzardf0_bank.start = 0x00f00000;
                blizzardf0_bank.allocated = 131072;
@@ -1544,7 +1619,7 @@ void cpuboard_init(void)
                mapped_malloc(&blizzardea_bank);
 
        }
-       else if (is_dkb_12x0()) {
+       else if (is_dkb_12x0(&currprefs)) {
 
                blizzardram_bank.start = 0x10000000;
                blizzardram_bank.allocated = cpuboard_size;
@@ -1553,21 +1628,21 @@ void cpuboard_init(void)
                blizzardram_bank.label = _T("dkb");
                mapped_malloc(&blizzardram_bank);
 
-       } else if (is_dkb_wildfire()) {
+       } else if (is_dkb_wildfire(&currprefs)) {
 
                blizzardf0_bank.start = 0x00f00000;
                blizzardf0_bank.allocated = 65536;
                blizzardf0_bank.mask = blizzardf0_bank.allocated - 1;
                mapped_malloc(&blizzardf0_bank);
 
-       } else if (is_apollo()) {
+       } else if (is_apollo(&currprefs)) {
 
                blizzardf0_bank.start = 0x00f00000;
                blizzardf0_bank.allocated = 131072;
                blizzardf0_bank.mask = blizzardf0_bank.allocated - 1;
                mapped_malloc(&blizzardf0_bank);
 
-       } else if (is_fusionforty()) {
+       } else if (is_fusionforty(&currprefs)) {
 
                blizzardf0_bank.start = 0x00f40000;
                blizzardf0_bank.allocated = 262144;
@@ -1581,7 +1656,7 @@ void cpuboard_init(void)
                blizzardram_bank.label = _T("fusionforty");
                mapped_malloc(&blizzardram_bank);
 
-       } else if (is_tekmagic()) {
+       } else if (is_tekmagic(&currprefs)) {
 
                blizzardf0_bank.start = 0x00f00000;
                blizzardf0_bank.allocated = 131072;
@@ -1592,7 +1667,7 @@ void cpuboard_init(void)
                blizzardea_bank.mask = blizzardea_bank.allocated - 1;
                mapped_malloc(&blizzardea_bank);
 
-       } else if (is_blizzard1230mk2()) {
+       } else if (is_blizzard1230mk2(&currprefs)) {
 
                blizzardea_bank.allocated = 2 * 65536;
                blizzardea_bank.mask = blizzardea_bank.allocated - 1;
@@ -1616,7 +1691,7 @@ void cpuboard_init(void)
 
                maprom_base = blizzardram_bank.allocated - 524288;
 
-       } else if (is_blizzard1230mk3()) {
+       } else if (is_blizzard1230mk3(&currprefs)) {
 
                blizzardea_bank.allocated = 2 * 65536;
                blizzardea_bank.mask = blizzardea_bank.allocated - 1;
@@ -1641,72 +1716,23 @@ void cpuboard_init(void)
                maprom_base = blizzardram_bank.allocated - 524288;
 
 
-       } else if (is_blizzard() || is_blizzardppc()) {
-retry:
-               cpuboard_size = currprefs.cpuboardmem1_size;
-               if (cpuboard_size < 256 * 1024 * 1024) {
-                       blizzardram_bank.start = BLIZZARD_RAM_BASE_48;
-                       blizzardram_bank.allocated = cpuboard_size;
-                       blizzardram_bank.mask = blizzardram_bank.allocated - 1;
-                       blizzardram_bank.startmask = BLIZZARD_RAM_BASE_68;
-               } else if (currprefs.z3autoconfig_start <= 0x10000000) {
-                       blizzardram_bank.start = BLIZZARD_RAM_256M_BASE_40;
-                       blizzardram_bank.allocated = cpuboard_size;
-                       blizzardram_bank.mask = blizzardram_bank.allocated - 1;
-                       blizzardram_bank.startmask = BLIZZARD_RAM_256M_BASE_40;
-               } else {
-                       blizzardram_bank.start = BLIZZARD_RAM_256M_BASE_70;
-                       blizzardram_bank.allocated = cpuboard_size;
-                       blizzardram_bank.mask = blizzardram_bank.allocated - 1;
-                       blizzardram_bank.startmask = BLIZZARD_RAM_256M_BASE_70;
-               }
-
-               blizzardram_nojit_bank.start = blizzardram_bank.start;
-               blizzardram_nojit_bank.allocated = blizzardram_bank.allocated;
-               blizzardram_nojit_bank.mask = blizzardram_bank.mask;
-               blizzardram_nojit_bank.startmask = blizzardram_bank.startmask;
-
-               blizzard_jit = cpuboard_jitdirectompatible(&currprefs);
-               if (blizzard_jit) {
-                       if (cpuboard_size) {
-                               if (cpuboard_size < 256 * 1024 * 1024)
-                                       blizzardram_bank.label = _T("blizzard");
-                               else
-                                       blizzardram_bank.label = _T("blizzard_70");
-                               mapped_malloc(&blizzardram_bank);
-                       }
-               } else {
-                       if (cpuboard_size) {
-#ifdef CPU_64_BIT
-                               blizzardram_bank.baseaddr = (uae_u8 *) uae_vm_alloc(
-                                       blizzardram_bank.allocated, UAE_VM_32BIT, UAE_VM_READ_WRITE);
-#else
-                               blizzardram_bank.baseaddr = xmalloc(uae_u8, blizzardram_bank.allocated);
-                               if (!blizzardram_bank.baseaddr) {
-                                       write_log(_T("MMAN: blizzardram_bank %d MB allocation failed\n"), blizzardram_bank.allocated / (1024 * 1024));
-                                       if (currprefs.cpuboardmem1_size > 16 * 1024 * 1024) {
-                                               currprefs.cpuboardmem1_size /= 2;
-                                               changed_prefs.cpuboardmem1_size = currprefs.cpuboardmem1_size;
-                                               goto retry;
-                                       }
-                               }
-#endif
-                               write_log(_T("MMAN: Allocated %d bytes (%d MB) for blizzardram_bank at %p\n"),
-                                                 blizzardram_bank.allocated,
-                                                 blizzardram_bank.allocated / (1024 * 1024),
-                                                 blizzardram_bank.baseaddr);
-                       }
-               }
-               blizzardram_nojit_bank.baseaddr = blizzardram_bank.baseaddr;
+       } else if (is_blizzard(&currprefs) || is_blizzardppc(&currprefs)) {
 
-               maprom_base = blizzardram_bank.allocated - 524288;
+               blizzard_jit = 1;
+               blizzardram_bank.start = BLIZZARDMK4_RAM_BASE_48 - cpuboard_size / 2;
+               blizzardram_bank.allocated = cpuboard_size;
+               blizzardram_bank.mask = blizzardram_bank.allocated - 1;
+               if (cpuboard_size) {
+                       blizzardram_bank.label = _T("*");
+                       mapped_malloc(&blizzardram_bank);
+               }
 
                blizzardf0_bank.start = 0x00f00000;
                blizzardf0_bank.allocated = 524288;
                blizzardf0_bank.mask = blizzardf0_bank.allocated - 1;
                mapped_malloc(&blizzardf0_bank);
 
-               if (!is_blizzardppc()) {
+               if (!is_blizzardppc(&currprefs)) {
                        blizzardea_bank.allocated = 2 * 65536;
                        blizzardea_bank.mask = blizzardea_bank.allocated - 1;
                        // Blizzard 12xx autoconfig ROM must be mapped at $ea0000-$ebffff, board requires it.
@@ -1714,33 +1740,20 @@ retry:
                }
 
                if (cpuboard_size > 2 * 524288) {
-                       if (!is_blizzardppc()) {
+                       if (!is_blizzardppc(&currprefs)) {
                                blizzardmaprom_bank.baseaddr = blizzardram_bank.baseaddr + cpuboard_size - 524288;
-                               blizzardmaprom_bank.start = BLIZZARD_MAPROM_BASE;
+                               blizzardmaprom_bank.start = BLIZZARDMK4_MAPROM_BASE;
                                blizzardmaprom_bank.allocated = 524288;
                                blizzardmaprom_bank.mask = 524288 - 1;
                                blizzardmaprom_bank.flags |= ABFLAG_INDIRECT | ABFLAG_NOALLOC;
                                mapped_malloc(&blizzardmaprom_bank);
                                blizzardmaprom_bank_mapped = true;
-                       } else {
-                               blizzardmaprom_bank.baseaddr = blizzardram_bank.baseaddr + cpuboard_size - 524288;
-                               blizzardmaprom_bank.start = CYBERSTORM_MAPROM_BASE;
-                               blizzardmaprom_bank.allocated = 524288;
-                               blizzardmaprom_bank.mask = 524288 - 1;
-                               blizzardmaprom_bank.flags |= ABFLAG_INDIRECT | ABFLAG_NOALLOC;
-                               mapped_malloc(&blizzardmaprom_bank);
-                               blizzardmaprom_bank_mapped = true;
-                               blizzardmaprom2_bank.baseaddr = blizzardram_bank.baseaddr + cpuboard_size - 2 * 524288;
-                               blizzardmaprom2_bank.start = CYBERSTORM_MAPROM_BASE;
-                               blizzardmaprom2_bank.allocated = 524288;
-                               blizzardmaprom2_bank.mask = 524288 - 1;
-                               blizzardmaprom2_bank.flags |= ABFLAG_INDIRECT | ABFLAG_NOALLOC;
-                               mapped_malloc(&blizzardmaprom2_bank);
-                               blizzardmaprom2_bank_mapped = true;
                        }
                }
 
-       } else if (is_csmk1()) {
+               maprom_base = blizzardram_bank.allocated - 524288;
+
+       } else if (is_csmk1(&currprefs)) {
 
                blizzardf0_bank.start = 0x00f00000;
                blizzardf0_bank.allocated = 65536;
@@ -1757,7 +1770,7 @@ retry:
                blizzardmaprom_bank_mapped = true;
                mapped_malloc(&blizzardmaprom_bank);
 
-       } else if (is_csmk2() || is_blizzard2060()) {
+       } else if (is_csmk2(&currprefs) || is_blizzard2060(&currprefs)) {
 
                blizzardea_bank.allocated = 2 * 65536;
                blizzardea_bank.mask = blizzardea_bank.allocated - 1;
@@ -1775,43 +1788,32 @@ retry:
                blizzardmaprom_bank.flags |= ABFLAG_INDIRECT | ABFLAG_NOALLOC;
                mapped_malloc(&blizzardmaprom_bank);
 
-       } else if (is_csmk3()) {
-
-               blizzardram_bank.start = CS_RAM_BASE;
-               blizzardram_bank.allocated = cpuboard_size;
-               blizzardram_bank.mask = blizzardram_bank.allocated - 1;
-               if (cpuboard_size) {
-                       blizzardram_bank.label = _T("cyberstorm");
-                       mapped_malloc(&blizzardram_bank);
-               }
+       } else if (is_csmk3(&currprefs)) {
 
                blizzardf0_bank.start = 0x00f00000;
                blizzardf0_bank.allocated = 524288;
                blizzardf0_bank.mask = blizzardf0_bank.allocated - 1;
                mapped_malloc(&blizzardf0_bank);
 
-               if (a3000hmem_bank.allocated > 2 * 524288) {
-                       blizzardmaprom_bank.flags |= ABFLAG_INDIRECT | ABFLAG_NOALLOC;
-                       blizzardmaprom_bank.baseaddr = a3000hmem_bank.baseaddr + a3000hmem_bank.allocated - 1 * 524288;
-                       blizzardmaprom_bank.start = CYBERSTORM_MAPROM_BASE;
-                       blizzardmaprom_bank.allocated = 524288;
-                       blizzardmaprom_bank.mask = 524288 - 1;
-                       mapped_malloc(&blizzardmaprom_bank);
-                       blizzardmaprom_bank_mapped = true;
-                       blizzardmaprom2_bank.flags |= ABFLAG_INDIRECT | ABFLAG_NOALLOC;
-                       blizzardmaprom2_bank.baseaddr = a3000hmem_bank.baseaddr + a3000hmem_bank.allocated - 2 * 524288;
-                       blizzardmaprom2_bank.start = CYBERSTORM_MAPROM_BASE;
-                       blizzardmaprom2_bank.allocated = 524288;
-                       blizzardmaprom2_bank.mask = 524288 - 1;
-                       mapped_malloc(&blizzardmaprom2_bank);
-                       blizzardmaprom2_bank_mapped = true;
-               }
        }
 }
 
+void cpuboard_init(void)
+{
+       if (!currprefs.cpuboard_type)
+               return;
+
+       if (cpuboard_size == currprefs.cpuboardmem1_size)
+               return;
+
+       cpuboard_cleanup();
+       cpuboard_init_2();
+}
+
+
 void cpuboard_overlay_override(void)
 {
-       if (is_a2630()) {
+       if (is_a2630(&currprefs)) {
                if (!(a2630_io & 2))
                        map_banks(&blizzardf0_bank, 0xf80000 >> 16, f0rom_size >> 16, 0);
                if (mem25bit_bank.allocated)
@@ -1827,7 +1829,7 @@ void cpuboard_clear(void)
                memset(blizzardmaprom_bank.baseaddr, 0, 524288);
        if (blizzardmaprom2_bank.baseaddr)
                memset(blizzardmaprom2_bank.baseaddr, 0, 524288);
-       if (is_csmk3()) // SCSI RAM
+       if (is_csmk3(&currprefs)) // SCSI RAM
                memset(blizzardf0_bank.baseaddr + 0x40000, 0, 0x10000);
 }
 
@@ -1858,17 +1860,17 @@ static void makefakeppcrom(uae_u8 *rom, int type)
 
 bool is_ppc_cpu(struct uae_prefs *p)
 {
-       return is_ppc();
+       return is_ppc(p);
 }
 
 bool cpuboard_maprom(void)
 {
        if (!currprefs.cpuboard_type || !cpuboard_size)
                return false;
-       if (is_blizzard() || is_blizzardppc()) {
+       if (is_blizzard(&currprefs) || is_blizzardppc(&currprefs)) {
                if (maprom_state)
                        blizzard_copymaprom();
-       } else if (is_csmk3()) {
+       } else if (is_csmk3(&currprefs)) {
                if (maprom_state)
                        cyberstorm_copymaprom();
        }
@@ -1927,7 +1929,7 @@ void cpuboard_setboard(struct uae_prefs *p, int type, int subtype)
 
 uaecptr cpuboard_get_reset_pc(uaecptr *stack)
 {
-       if (is_aca500()) {
+       if (is_aca500(&currprefs)) {
                *stack = get_long(0xa00000);
                return get_long(0xa00004);
        } else {
@@ -1941,7 +1943,7 @@ bool cpuboard_io_special(int addr, uae_u32 *val, int size, bool write)
        addr &= 65535;
        if (write) {
                uae_u16 w = *val;
-               if (is_a2630()) {
+               if (is_a2630(&currprefs)) {
                        if ((addr == 0x0040 && size == 2) || (addr == 0x0041 && size == 1)) {
                                write_log(_T("A2630 write %04x PC=%08x\n"), w, M68K_GETPC);
                                a2630_io = w;
@@ -1971,7 +1973,7 @@ bool cpuboard_io_special(int addr, uae_u32 *val, int size, bool write)
                }
                return false;
        } else {
-               if (is_a2630()) {
+               if (is_a2630(&currprefs)) {
                        // osmode (j304)
                        if (addr == 0x0c && (a2630_io & 4) == 0) {
                                (*val) |= 0x80;
@@ -1984,7 +1986,7 @@ bool cpuboard_io_special(int addr, uae_u32 *val, int size, bool write)
        return false;
 }
 
-static void fixserial(uae_u8 *rom, int size)
+static void fixserial(struct uae_prefs *p, uae_u8 *rom, int size)
 {
        uae_u8 value1 = rom[16];
        uae_u8 value2 = rom[17];
@@ -1994,7 +1996,7 @@ static void fixserial(uae_u8 *rom, int size)
        char serial[10];
        int type = -1;
 
-       if (ISCPUBOARD(BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_PPC)) {
+       if (ISCPUBOARDP(p, BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_PPC)) {
                value1 = 'I';
                value2 = 'D';
                if (currprefs.cpu_model == 68060)
@@ -2006,14 +2008,14 @@ static void fixserial(uae_u8 *rom, int size)
                seroffset = 19;
                sprintf(serial, "%04X", serialnum);
                type = 1;
-       } else if (ISCPUBOARD(BOARD_CYBERSTORM, BOARD_CYBERSTORM_SUB_PPC)) {
+       } else if (ISCPUBOARDP(p, BOARD_CYBERSTORM, BOARD_CYBERSTORM_SUB_PPC)) {
                value1 = 'D';
                value2 = 'B';
                sprintf(serial, "%05X", serialnum);
                value3 = 0;
                seroffset = 18;
                type = 0;
-       } else if (ISCPUBOARD(BOARD_CYBERSTORM, BOARD_CYBERSTORM_SUB_MK3)) {
+       } else if (ISCPUBOARDP(p, BOARD_CYBERSTORM, BOARD_CYBERSTORM_SUB_MK3)) {
                value1 = 'F';
                sprintf(serial, "%05X", serialnum);
                value2 = value3 = 0;
@@ -2113,11 +2115,11 @@ static void ew(uae_u8 *p, int addr, uae_u8 value)
        }
 }
 
-addrbank *cpuboard_autoconfig_init(struct romconfig *rc)
+bool cpuboard_autoconfig_init(struct autoconfig_info *aci)
 {
        struct zfile *autoconfig_rom = NULL;
        struct boardromconfig *brc;
-       int roms[3], roms2[3];
+       int roms[4], roms2[4];
        bool autoconf = true;
        bool autoconf_stop = false;
        const TCHAR *defaultromname = NULL;
@@ -2125,39 +2127,40 @@ addrbank *cpuboard_autoconfig_init(struct romconfig *rc)
        bool isflashrom = false;
        struct romdata *rd = NULL;
        const TCHAR *boardname;
-       
-       boardname = cpuboards[currprefs.cpuboard_type].subtypes[currprefs.cpuboard_subtype].name;
+       struct uae_prefs *p = aci->prefs;
+
+       boardname = cpuboards[p->cpuboard_type].subtypes[p->cpuboard_subtype].name;
+       aci->label = boardname;
 
        int idx;
-       brc = get_device_rom(&currprefs, ROMTYPE_CPUBOARD, 0, &idx);
+       brc = get_device_rom(p, ROMTYPE_CPUBOARD, 0, &idx);
        if (brc)
                romname = brc->roms[idx].romfile;
 
-       roms[0] = -1;
-       roms[1] = -1;
-       roms[2] = -1;
-       roms2[0] = -1;
-       roms2[1] = -1;
-       roms2[2] = -1;
+       for (int i = 0; i < 4; i++) {
+               roms[i] = -1;
+               roms2[i] = -1;
+       }
        cpuboard_non_byte_ea = false;
-       int boardid = cpuboards[currprefs.cpuboard_type].id;
+       int boardid = cpuboards[p->cpuboard_type].id;
        switch (boardid)
        {
                case BOARD_IC:
                break;
 
                case BOARD_COMMODORE:
-               switch(currprefs.cpuboard_subtype)
+               switch(p->cpuboard_subtype)
                {
                        case BOARD_COMMODORE_SUB_A26x0:
                        roms[0] = 105;
                        roms[1] = 106;
+                       roms[2] = 164;
                        break;
                }
                break;
 
                case BOARD_ACT:
-               switch(currprefs.cpuboard_subtype)
+               switch(p->cpuboard_subtype)
                {
                        case BOARD_ACT_SUB_APOLLO:
                        roms[0] = 119;
@@ -2166,7 +2169,7 @@ addrbank *cpuboard_autoconfig_init(struct romconfig *rc)
                break;
 
                case BOARD_MTEC:
-               switch (currprefs.cpuboard_subtype)
+               switch (p->cpuboard_subtype)
                {
                        case BOARD_MTEC_SUB_EMATRIX530:
                        roms[0] = 144;
@@ -2175,18 +2178,20 @@ addrbank *cpuboard_autoconfig_init(struct romconfig *rc)
                break;
 
                case BOARD_MACROSYSTEM:
-               switch(currprefs.cpuboard_subtype)
+               switch(p->cpuboard_subtype)
                {
                        case BOARD_MACROSYSTEM_SUB_WARPENGINE_A4000:
-                       return &expamem_null;
+                       aci->addrbank = &expamem_null;
+                       return true;
                }
                break;
 
                case BOARD_DKB:
-               switch(currprefs.cpuboard_subtype)
+               switch(p->cpuboard_subtype)
                {
                        case BOARD_DKB_SUB_12x0:
-                       return &expamem_null;
+                       aci->addrbank = &expamem_null;
+                       return true;
                        case BOARD_DKB_SUB_WILDFIRE:
                        roms[0] = 143;
                        break;
@@ -2194,7 +2199,7 @@ addrbank *cpuboard_autoconfig_init(struct romconfig *rc)
                break;
 
                case BOARD_RCS:
-               switch(currprefs.cpuboard_subtype)
+               switch(p->cpuboard_subtype)
                {
                        case BOARD_RCS_SUB_FUSIONFORTY:
                        roms[0] = 113;
@@ -2203,14 +2208,16 @@ addrbank *cpuboard_autoconfig_init(struct romconfig *rc)
                break;
        
                case BOARD_GVP:
-               switch(currprefs.cpuboard_subtype)
+               switch(p->cpuboard_subtype)
                {
                        case BOARD_GVP_SUB_A530:
                        case BOARD_GVP_SUB_GFORCE030:
-                               return &expamem_null;
+                               aci->addrbank = &expamem_null;
+                               return true;
                        case BOARD_GVP_SUB_A3001SI:
                        case BOARD_GVP_SUB_A3001SII:
-                               return &expamem_null;
+                               aci->addrbank = &expamem_null;
+                               return true;
                        case BOARD_GVP_SUB_TEKMAGIC:
                                roms[0] = 104;
                        break;
@@ -2218,10 +2225,10 @@ addrbank *cpuboard_autoconfig_init(struct romconfig *rc)
                break;
 
                case BOARD_CYBERSTORM:
-               switch(currprefs.cpuboard_subtype)
+               switch(p->cpuboard_subtype)
                {
                        case BOARD_CYBERSTORM_SUB_MK1:
-                               roms[0] = currprefs.cpu_model == 68040 ? 95 : 101;
+                               roms[0] = p->cpu_model == 68040 ? 95 : 101;
                                isflashrom = true;
                                break;
                        case BOARD_CYBERSTORM_SUB_MK2:
@@ -2240,7 +2247,7 @@ addrbank *cpuboard_autoconfig_init(struct romconfig *rc)
                break;
 
                case BOARD_BLIZZARD:
-               switch(currprefs.cpuboard_subtype)
+               switch(p->cpuboard_subtype)
                {
                        case BOARD_BLIZZARD_SUB_1230II:
                                roms[0] = 163;
@@ -2260,7 +2267,7 @@ addrbank *cpuboard_autoconfig_init(struct romconfig *rc)
                                roms[0] = 92;
                                break;
                        case BOARD_BLIZZARD_SUB_PPC:
-                               roms[0] = currprefs.cpu_model == 68040 ? 99 : 100;
+                               roms[0] = p->cpu_model == 68040 ? 99 : 100;
                                isflashrom = true;
                                break;
                }
@@ -2275,7 +2282,7 @@ addrbank *cpuboard_autoconfig_init(struct romconfig *rc)
                break;
 
                default:
-                       return &expamem_null;
+                       return false;
        }
 
        struct romlist *rl = NULL;
@@ -2284,7 +2291,7 @@ addrbank *cpuboard_autoconfig_init(struct romconfig *rc)
                if (!rl) {
                        rd = getromdatabyids(roms);
                        if (!rd)
-                               return &expamem_null;
+                               return false;
                } else {
                        rd = rl->rd;
                }
@@ -2316,27 +2323,37 @@ addrbank *cpuboard_autoconfig_init(struct romconfig *rc)
                                autoconfig_rom = flashfile_open(defaultromname);
                }
                if (!autoconfig_rom) {
-                       romwarning(roms);
+                       if (aci->doinit)
+                               romwarning(roms);
                        write_log(_T("Couldn't open CPUBoard '%s' rom '%s'\n"), boardname, defaultromname);
-                       return &expamem_null;
+                       return false;
                }
        }
        
        if (!autoconfig_rom && roms[0] != -1) {
-               romwarning(roms);
+               if (aci->doinit)
+                       romwarning(roms);
                write_log (_T("ROM id %d not found for CPUBoard '%s' emulation\n"), roms[0], boardname);
-               return &expamem_null;
+               return false;
        }
        if (!autoconfig_rom) {
                write_log(_T("Couldn't open CPUBoard '%s' rom '%s'\n"), boardname, defaultromname);
-               return &expamem_null;
+               return false;
        }
 
        write_log(_T("CPUBoard '%s' ROM '%s' %lld loaded\n"), boardname, zfile_getname(autoconfig_rom), zfile_size(autoconfig_rom));
 
-       protect_roms(false);
+       uae_u8 *blizzardea_tmp = blizzardea_bank.baseaddr;
+       uae_u8 *blizzardf0_tmp = blizzardf0_bank.baseaddr;
+       if (!aci->doinit) {
+               blizzardea_bank.baseaddr = xcalloc(uae_u8, 65536 * 2);
+               blizzardf0_bank.baseaddr = xcalloc(uae_u8, 524288);
+       } else {
+               protect_roms(false);
+       }
+
        cpuboard_non_byte_ea = true;
-       if (is_sx32pro()) {
+       if (is_sx32pro(p)) {
                earom_size = 65536;
                for (int i = 0; i < 32768; i++) {
                        uae_u8 b = 0xff;
@@ -2344,7 +2361,7 @@ addrbank *cpuboard_autoconfig_init(struct romconfig *rc)
                        blizzardea_bank.baseaddr[i * 2 + 0] = b;
                        blizzardea_bank.baseaddr[i * 2 + 1] = 0xff;
                }
-       } else if (is_mtec_ematrix530()) {
+       } else if (is_mtec_ematrix530(p)) {
                earom_size = 65536;
                for (int i = 0; i < 32768; i++) {
                        uae_u8 b = 0xff;
@@ -2352,13 +2369,13 @@ addrbank *cpuboard_autoconfig_init(struct romconfig *rc)
                        blizzardea_bank.baseaddr[i * 2 + 0] = b;
                        blizzardea_bank.baseaddr[i * 2 + 1] = 0xff;
                }
-       } else if (is_dkb_wildfire()) {
+       } else if (is_dkb_wildfire(p)) {
                f0rom_size = 65536;
                zfile_fread(blizzardf0_bank.baseaddr, 1, f0rom_size, autoconfig_rom);
                flashrom = flash_new(blizzardf0_bank.baseaddr + 0, 32768, 65536, 0x20, flashrom_file, FLASHROM_EVERY_OTHER_BYTE | FLASHROM_PARALLEL_EEPROM);
                flashrom2 = flash_new(blizzardf0_bank.baseaddr + 1, 32768, 65536, 0x20, flashrom_file, FLASHROM_EVERY_OTHER_BYTE | FLASHROM_EVERY_OTHER_BYTE_ODD | FLASHROM_PARALLEL_EEPROM);
                autoconf = false;
-       } else if (is_aca500()) {
+       } else if (is_aca500(p)) {
                f0rom_size = 524288;
                zfile_fread(blizzardf0_bank.baseaddr, f0rom_size, 1, autoconfig_rom);
                autoconf = false;
@@ -2367,12 +2384,12 @@ addrbank *cpuboard_autoconfig_init(struct romconfig *rc)
                        autoconfig_rom = NULL;
                }
                flashrom = flash_new(blizzardf0_bank.baseaddr, f0rom_size, f0rom_size, 0xa4, flashrom_file, 0);
-       } else if (is_a2630()) {
-               f0rom_size = 131072;
+       } else if (is_a2630(p)) {
+               f0rom_size = 65536;
                zfile_fread(blizzardf0_bank.baseaddr, 1, f0rom_size, autoconfig_rom);
                autoconf = false;
                autoconf_stop = true;
-       } else if (is_kupke()) {
+       } else if (is_kupke(p)) {
                earom_size = 65536;
                for (int i = 0; i < 8192; i++) {
                        uae_u8 b = 0xff;
@@ -2380,21 +2397,21 @@ addrbank *cpuboard_autoconfig_init(struct romconfig *rc)
                        blizzardea_bank.baseaddr[i * 2 + 0] = b;
                        blizzardea_bank.baseaddr[i * 2 + 1] = 0xff;
                }
-       } else if (is_apollo()) {
+       } else if (is_apollo(p)) {
                f0rom_size = 131072;
                zfile_fread(blizzardf0_bank.baseaddr, 1, 131072, autoconfig_rom);
                autoconf = false;
-       } else if (is_fusionforty()) {
+       } else if (is_fusionforty(p)) {
                f0rom_size = 262144;
                zfile_fread(blizzardf0_bank.baseaddr, 1, 131072, autoconfig_rom);
                autoconf = false;
-       } else if (is_tekmagic()) {
+       } else if (is_tekmagic(p)) {
                earom_size = 65536;
                f0rom_size = 131072;
                zfile_fread(blizzardf0_bank.baseaddr, 1, f0rom_size, autoconfig_rom);
                autoconf = false;
                cpuboard_non_byte_ea = false;
-       } else if (is_blizzard2060()) {
+       } else if (is_blizzard2060(p)) {
                f0rom_size = 65536;
                earom_size = 131072;
                // 2060 = 2x32k
@@ -2409,7 +2426,7 @@ addrbank *cpuboard_autoconfig_init(struct romconfig *rc)
                        zfile_fread(&b, 1, 1, autoconfig_rom);
                        blizzardea_bank.baseaddr[i * 2 + 0] = b;
                }
-       } else if (is_csmk1()) {
+       } else if (is_csmk1(p)) {
                earom_size = 131072;
                f0rom_size = 65536;
                for (int i = 0; i < 32768; i++) {
@@ -2425,7 +2442,7 @@ addrbank *cpuboard_autoconfig_init(struct romconfig *rc)
                }
                flashrom = flash_new(blizzardea_bank.baseaddr, earom_size, earom_size, 0x20, flashrom_file, 0);
                memcpy(blizzardf0_bank.baseaddr, blizzardea_bank.baseaddr + 65536, 65536);
-       } else if (is_csmk2()) {
+       } else if (is_csmk2(p)) {
                earom_size = 131072;
                f0rom_size = 65536;
                zfile_fread(blizzardea_bank.baseaddr, earom_size, 1, autoconfig_rom);
@@ -2435,12 +2452,13 @@ addrbank *cpuboard_autoconfig_init(struct romconfig *rc)
                }
                flashrom = flash_new(blizzardea_bank.baseaddr, earom_size, earom_size, 0x20, flashrom_file, 0);
                memcpy(blizzardf0_bank.baseaddr, blizzardea_bank.baseaddr + 65536, 65536);
-       } else if (is_csmk3() || is_blizzardppc()) {
+       } else if (is_csmk3(p) || is_blizzardppc(p)) {
                uae_u8 flashtype;
                earom_size = 0;
-               if (is_blizzardppc()) {
+               if (is_blizzardppc(p)) {
                        flashtype = 0xa4;
                        f0rom_size = 524288;
+                       aci->last_high_ram = BLIZZARDMK4_RAM_BASE_48 + p->cpuboardmem1_size / 2;
                } else {
                        flashtype = 0x20;
                        f0rom_size = 131072;
@@ -2459,9 +2477,11 @@ addrbank *cpuboard_autoconfig_init(struct romconfig *rc)
                        flashrom_file = autoconfig_rom;
                        autoconfig_rom = NULL;
                }
-               fixserial(blizzardf0_bank.baseaddr, f0rom_size);
+               fixserial(p, blizzardf0_bank.baseaddr, f0rom_size);
                flashrom = flash_new(blizzardf0_bank.baseaddr, f0rom_size, f0rom_size, flashtype, flashrom_file, 0);
-       } else if (is_blizzard()) {
+               aci->start = 0xf00000;
+               aci->size = 0x80000;
+       } else if (is_blizzard(p)) {
                // 1230 MK IV / 1240/60
                f0rom_size = 65536;
                earom_size = 131072;
@@ -2477,7 +2497,7 @@ addrbank *cpuboard_autoconfig_init(struct romconfig *rc)
                autoconfig_rom = NULL;
                if (roms2[0] != -1) {
                        int idx2;
-                       struct boardromconfig *brc2 = get_device_rom(&currprefs, ROMTYPE_BLIZKIT4, 0, &idx2);
+                       struct boardromconfig *brc2 = get_device_rom(p, ROMTYPE_BLIZKIT4, 0, &idx2);
                        if (brc2 && brc2->roms[idx2].romfile[0])
                                autoconfig_rom = board_rom_open(roms2, brc2->roms[idx2].romfile);
                        if (autoconfig_rom) {
@@ -2485,7 +2505,8 @@ addrbank *cpuboard_autoconfig_init(struct romconfig *rc)
                                zfile_fread(blizzardea_bank.baseaddr + 0x10000, 32768, 1, autoconfig_rom);
                        }
                }
-       } else if (is_blizzard1230mk3() || is_blizzard1230mk2()) {
+               aci->last_high_ram = BLIZZARDMK4_RAM_BASE_48 + p->cpuboardmem1_size / 2;
+       } else if (is_blizzard1230mk3(p) || is_blizzard1230mk2(p)) {
                earom_size = 131072;
                for (int i = 0; i < 32768; i++) {
                        uae_u8 b = 0xff;
@@ -2496,16 +2517,37 @@ addrbank *cpuboard_autoconfig_init(struct romconfig *rc)
                zfile_fclose(autoconfig_rom);
                autoconfig_rom = NULL;
        }
-       protect_roms(true);
+
+       if (autoconf_stop) {
+               aci->addrbank = &expamem_none;
+       } else if (!autoconf) {
+               aci->addrbank = &expamem_nonautoconfig;
+       } else {
+               aci->addrbank = &blizzarde8_bank;
+               memcpy(aci->autoconfig_raw, blizzardea_bank.baseaddr, sizeof aci->autoconfig_raw);
+       }
+
        zfile_fclose(autoconfig_rom);
 
+       if (!aci->doinit) {
+               xfree(blizzardea_bank.baseaddr);
+               xfree(blizzardf0_bank.baseaddr);
+               blizzardea_bank.baseaddr = blizzardea_tmp;
+               blizzardf0_bank.baseaddr = blizzardf0_tmp;
+               flash_free(flashrom);
+               flashrom = NULL;
+               return true;
+       } else {
+               protect_roms(true);
+       }
+
        if (f0rom_size) {
-               if (is_a2630()) {
+               if (is_a2630(p)) {
                        if (!(a2630_io & 2))
                                map_banks(&blizzardf0_bank, 0xf80000 >> 16, f0rom_size >> 16, 0);
                        if (!(a2630_io & 1))
                                map_banks(&blizzardf0_bank, 0x000000 >> 16, f0rom_size >> 16, 0);
-               } else if (is_fusionforty()) {
+               } else if (is_fusionforty(p)) {
                        map_banks(&blizzardf0_bank, 0x00f40000 >> 16, f0rom_size >> 16, 0);
                        map_banks(&blizzardf0_bank, 0x05000000 >> 16, f0rom_size >> 16, 0);
                        map_banks(&blizzardf0_bank, 0x00000000 >> 16, f0rom_size >> 16, 0);
@@ -2513,9 +2555,5 @@ addrbank *cpuboard_autoconfig_init(struct romconfig *rc)
                        map_banks(&blizzardf0_bank, 0xf00000 >> 16, (f0rom_size > 262144 ? 262144 : f0rom_size) >> 16, 0);
                }
        }
-       if (autoconf_stop)
-               return &expamem_none;
-       if (!autoconf)
-               return &expamem_null;
-       return &blizzarde8_bank;
+       return true;
 }
index e73526652a75bf046b25f6f9892edb84dac25db0..9df242ff815c09b5301893147519697c86833a67 100644 (file)
@@ -106,6 +106,9 @@ uae_u16 customhack_get (struct customhack *ch, int hpos)
 static unsigned int n_consecutive_skipped = 0;
 static unsigned int total_skipped = 0;
 
+extern int cpu_last_stop_vpos, cpu_stopped_lines;
+static int cpu_sleepmode, cpu_sleepmode_cnt;
+
 STATIC_INLINE void sync_copper (int hpos);
 
 
@@ -991,7 +994,8 @@ static int toscr_res, toscr_res2p;
 static int toscr_nr_planes, toscr_nr_planes2, toscr_nr_planes_agnus, toscr_nr_planes_shifter;
 static int fetchwidth;
 static int toscr_delay[2], toscr_delay_adjusted[2], toscr_delay_sh[2];
-static int delay_cycles, delay_lastcycle[2];
+static bool shdelay_disabled;
+static int delay_cycles, delay_lastcycle[2], hack_delay_shift;
 static bool bplcon1_written;
 
 #define PLANE_RESET_HPOS 8
@@ -1739,9 +1743,17 @@ static void hack_shres_delay(int hpos)
        int o1 = toscr_delay_sh[1];
        int shdelay1 = (bplcon1 >> 8) & 3;
        int shdelay2 = (bplcon1 >> 12) & 3;
-       toscr_delay_sh[0] = (shdelay1 & 3) >> toscr_res;
-       toscr_delay_sh[1] = (shdelay2 & 3) >> toscr_res;
-       if (hpos >= 0 && toscr_delay_sh[0] != o0 || toscr_delay_sh[1] != o1) {
+       if (shdelay1 != shdelay2) {
+               shdelay_disabled = true;
+       }
+       if (shdelay_disabled) {
+               toscr_delay_sh[0] = 0;
+               toscr_delay_sh[1] = 0;
+       } else {
+               toscr_delay_sh[0] = (shdelay1 & 3) >> toscr_res;
+               toscr_delay_sh[1] = (shdelay2 & 3) >> toscr_res;
+       }
+       if (hpos >= 0 && (toscr_delay_sh[0] != o0 || toscr_delay_sh[1] != o1)) {
                record_color_change(hpos, 0, COLOR_CHANGE_SHRES_DELAY | toscr_delay_sh[0]);
                current_colors.extra &= ~(1 << CE_SHRES_DELAY);
                current_colors.extra &= ~(1 << (CE_SHRES_DELAY + 1));
@@ -3133,10 +3145,8 @@ static void do_sprite_collisions (void)
        hwres_t hw_diwlast = coord_window_to_diw_x (thisline_decision.diwlastword);
        hwres_t hw_diwfirst = coord_window_to_diw_x (thisline_decision.diwfirstword);
 
-       if (clxcon_bpl_enable == 0) {
-               clxdat |= 0x1FE;
+       if (clxcon_bpl_enable == 0 && !nr_sprites)
                return;
-       }
 
        for (i = 0; i < nr_sprites; i++) {
                struct sprite_entry *e = curr_sprite_entries + first + i;
@@ -3744,6 +3754,7 @@ static void reset_decisions (void)
        ddfstop_written_hpos = -1;
        bitplane_maybe_start_hpos = -1;
        bitplane_off_delay = -1;
+       hack_delay_shift = 0;
 
        if (line_cyclebased) {
                line_cyclebased--;
@@ -4614,37 +4625,16 @@ static void VHPOSW (uae_u16 v)
                write_log (_T("VHPOSW %04X PC=%08x\n"), v, M68K_GETPC);
 #endif
 
-#if 0
-       /* This is not that easy, need to decouple denise and paula hpos counters
-        * from master counter.
-        * All this just to fix Upfront-CoolFridge Smooth Copper part..
-        */
-       if (oldhpos != newhpos) {
-               oldhpos = current_hpos();
-               int newhpos = v & 0xff;
-               if (newhpos >= maxhpos)
-                       newhpos = maxhpos - 1;
-               hpos_offset = newhpos - oldhpos;
-               eventtab[ev_hsync].evtime = get_cycles() + HSYNCTIME - (newhpos * CYCLE_UNIT);
-               eventtab[ev_hsync].oldcycles = get_cycles() - newhpos * CYCLE_UNIT;
-               events_schedule();
-               newhpos2 = current_hpos();
-#ifdef CPUEMU_13
-               if (currprefs.cpu_cycle_exact || currprefs.blitter_cycle_exact) {
-                       memset(cycle_line + newhpos, 0, maxhpos - newhpos);
-                       int hp = maxhpos - 1, i;
-                       for (i = 0; i < 4; i++) {
-                               alloc_cycle (hp, i == 0 ? CYCLE_STROBE : CYCLE_REFRESH);
-                       hp += 2;
-                       if (hp >= maxhpos)
-                               hp -= maxhpos;
+       if (currprefs.cpu_cycle_exact && currprefs.cpu_model == 68000) {
+               /* Special hack for Smooth Copper in CoolFridge / Upfront demo */
+               int chp = current_hpos_safe();
+               int hp = v & 0xff;
+               if (chp >= 0x21 && chp <= 0x29 && hp == 0x2d) {
+                       hack_delay_shift = 4;
+                       record_color_change(chp, 0, COLOR_CHANGE_HSYNC_HACK | 6);
+                       thisline_changed = true;
                }
        }
-#endif
-               vposw_change++;
-               changed = true;
-       }
-#endif
 
        v >>= 8;
        vpos &= 0xff00;
@@ -6208,6 +6198,7 @@ static int custom_wput_copper (int hpos, uaecptr addr, uae_u32 value, int noget)
 {
        int v;
 
+       hpos += hack_delay_shift;
        value = debug_wputpeekdma_chipset (0xdff000 + addr, value, MW_MASK_COPPER, 0x08c);
        copper_access = 1;
        v = custom_wput_1 (hpos, addr, value, noget);
@@ -7076,6 +7067,11 @@ static void rtg_vsynccheck (void)
 }
 
 
+static void maybe_process_pull_audio(void)
+{
+       audio_finish_pull();
+}
+
 // moving average algorithm
 #define MAVG_MAX_SIZE 128
 struct mavg_data
@@ -7181,7 +7177,7 @@ static bool framewait (void)
        } else if (vs < 0) {
 
                int freetime;
-               extern int extraframewait;
+               extern int extraframewait, extraframewait2;
 
                if (!vblank_hz_state)
                        return status != 0;
@@ -7275,8 +7271,22 @@ static bool framewait (void)
 
                        now = read_processor_time ();
 
-                       if (extraframewait && !currprefs.turbo_emulation)
-                               cpu_sleep_millis(extraframewait);
+                       maybe_process_pull_audio();
+                       if (extraframewait && !currprefs.turbo_emulation) {
+                               cpu_sleep_millis(-extraframewait);
+                               maybe_process_pull_audio();
+                       } else if (extraframewait2 && !currprefs.turbo_emulation) {
+                               uae_time_t add = ((uae_s64)extraframewait2) * syncbase / (1000 * 1000);
+                               frame_time_t efw = read_processor_time() + add;
+                               for (;;) {
+                                       frame_time_t nfw = read_processor_time();
+                                       if (audio_is_pull_event())
+                                               break;
+                                       if ((int)efw - (int)nfw <= 0)
+                                               break;
+                               }
+                               maybe_process_pull_audio();
+                       }
 
                        adjust = (int)now - (int)curr_time;
                        int adjustx = adjust;
@@ -7329,7 +7339,7 @@ static bool framewait (void)
        int clockadjust = 0;
        int vstb = vsynctimebase;
 
-       if (currprefs.m68k_speed < 0 && !currprefs.cpu_memory_cycle_exact) {
+       if (currprefs.m68k_speed < 0 && !cpu_sleepmode && !currprefs.cpu_memory_cycle_exact) {
 
 #if 0
                static uae_u32 prevtick;
@@ -7366,7 +7376,10 @@ static bool framewait (void)
                                if ((int)vsyncwaittime  - (int)curr_time <= 0 || (int)vsyncwaittime  - (int)curr_time > 2 * vsynctimebase)
                                        break;
                                rtg_vsynccheck ();
-                               cpu_sleep_millis(1);
+                               if (cpu_sleep_millis(1) < 0) {
+                                       curr_time = read_processor_time();
+                                       break;
+                               }
                        }
                } else {
                        curr_time = read_processor_time ();
@@ -7396,21 +7409,25 @@ static bool framewait (void)
 
                int t = 0;
 
+               start = read_processor_time();
                if (!frame_rendered && !picasso_on) {
-                       start = read_processor_time ();
                        frame_rendered = render_screen (false);
                        t = read_processor_time () - start;
                }
                while (!currprefs.turbo_emulation) {
                        double v = rpt_vsync (clockadjust) / (syncbase / 1000.0);
-                       if (v >= -4)
+                       if (v >= -2)
                                break;
                        rtg_vsynccheck ();
-                       cpu_sleep_millis(2);
+                       maybe_process_pull_audio();
+                       if (cpu_sleep_millis(1) < 0)
+                               break;
                }
-               curr_time = start = read_processor_time ();
-               while (rpt_vsync (clockadjust) < 0)
+               while (rpt_vsync (clockadjust) < 0) {
                        rtg_vsynccheck ();
+                       if (audio_is_pull_event())
+                               break;
+               }
                idletime += read_processor_time() - start;
                curr_time = read_processor_time ();
                vsyncmintime = curr_time;
@@ -7432,6 +7449,15 @@ static bool framewait (void)
        return status != 0;
 }
 
+static void reset_cpu_idle(void)
+{
+       cpu_sleepmode_cnt = 0;
+       if (cpu_sleepmode) {
+               cpu_sleepmode = 0;
+               //write_log(_T("woken\n"));
+       }
+}
+
 #define FPSCOUNTER_MAVG_SIZE 10
 static struct mavg_data fps_mavg, idle_mavg;
 
@@ -7444,7 +7470,6 @@ void fpscounter_reset (void)
        idletime = 0;
 }
 
-
 static void fpscounter (bool frameok)
 {
        frame_time_t now, last;
@@ -7466,8 +7491,8 @@ static void fpscounter (bool frameok)
        if ((timeframes & 7) == 0) {
                double idle = 1000 - (idle_mavg.mavg == 0 ? 0.0 : (double)idle_mavg.mavg * 1000.0 / vsynctimebase);
                int fps = fps_mavg.mavg == 0 ? 0 : syncbase * 10 / fps_mavg.mavg;
-               if (fps > 9999)
-                       fps = 9999;
+               if (fps > 99999)
+                       fps = 99999;
                if (idle < 0)
                        idle = 0;
                if (idle > 100 * 10)
@@ -7490,25 +7515,34 @@ static void fpscounter (bool frameok)
 // vsync functions that are not hardware timing related
 static void vsync_handler_pre (void)
 {
-       if (bogusframe > 0)
-               bogusframe--;
-
-       while (handle_events ()) {
-               // we are paused, do all config checks but don't do any emulation
-               if (vsync_handle_check ()) {
-                       redraw_frame ();
-                       render_screen (true);
-                       show_screen (0);
+#if 1
+       if (currprefs.m68k_speed < 0) {
+               if (regs.stopped) {
+                       cpu_stopped_lines += maxvpos - cpu_last_stop_vpos;
+               }
+               int mv = 12 - currprefs.cpu_idle / 15;
+               if (mv >= 1 && mv <= 11) {
+                       mv = 11 - mv;
+                       if (cpu_stopped_lines >= maxvpos * (mv * 10) / 100) {
+                               cpu_sleepmode_cnt++;
+                               if (cpu_sleepmode_cnt >= 50) {
+                                       cpu_sleepmode_cnt = 50;
+                                       if (!cpu_sleepmode) {
+                                               cpu_sleepmode = 1;
+                                               //write_log(_T("sleep\n"));
+                                       }
+                               }
+                       } else {
+                               reset_cpu_idle();
+                       }
                }
-               config_check_vsync ();
        }
+       cpu_last_stop_vpos = 0;
+       cpu_stopped_lines = 0;
+#endif
 
-       if (quit_program > 0) {
-               /* prevent possible infinite loop at wait_cycles().. */
-               framecnt = 0;
-               reset_decisions ();
-               return;
-       }
+       if (bogusframe > 0)
+               bogusframe--;
 
        config_check_vsync ();
        if (timehack_alive > 0)
@@ -7542,6 +7576,29 @@ static void vsync_handler_pre (void)
 
        fpscounter (frameok);
 
+       bool waspaused = false;
+       while (handle_events()) {
+               if (!waspaused) {
+                       render_screen(true);
+                       show_screen(0);
+                       waspaused = true;
+               }
+               // we are paused, do all config checks but don't do any emulation
+               if (vsync_handle_check()) {
+                       redraw_frame();
+                       render_screen(true);
+                       show_screen(0);
+               }
+               config_check_vsync();
+       }
+
+       if (quit_program > 0) {
+               /* prevent possible infinite loop at wait_cycles().. */
+               framecnt = 0;
+               reset_decisions();
+               return;
+       }
+
        vsync_rendered = false;
        frame_shown = false;
        frame_rendered = false;
@@ -7994,11 +8051,12 @@ static void hsync_handler_post (bool onvsync)
        bool ciahsyncs = !(bplcon0 & 2) || ((bplcon0 & 2) && currprefs.genlock && (!currprefs.ntscmode || genlockhtoggle));
        bool ciavsyncs = !(bplcon0 & 2) || ((bplcon0 & 2) && currprefs.genlock && genlockvtoggle);
 
+       CIA_hsync_posthandler(false, false);
        if (currprefs.cs_cd32cd) {
-               CIA_hsync_posthandler(true);
+               CIA_hsync_posthandler(true, true);
                CIAB_tod_handler(18);
        } else if (ciahsyncs) {
-               CIA_hsync_posthandler(ciahsyncs);
+               CIA_hsync_posthandler(true, ciahsyncs);
                if (beamcon0 & (0x80 | 0x100)) {
                        if (hsstop < (maxhpos & ~1) && hsstrt < maxhpos)
                                CIAB_tod_handler(hsstop);
@@ -8127,7 +8185,7 @@ static void hsync_handler_post (bool onvsync)
                port_get_custom (1, out);
        }
 #endif
-       if (!currprefs.cpu_thread && currprefs.m68k_speed < 0 && !currprefs.cpu_memory_cycle_exact) {
+       if (!currprefs.cpu_thread && !cpu_sleepmode && currprefs.m68k_speed < 0 && !currprefs.cpu_memory_cycle_exact) {
                static int sleeps_remaining;
                if (is_last_line ()) {
                        sleeps_remaining = (165 - currprefs.cpu_idle) / 6;
@@ -8138,17 +8196,22 @@ static void hsync_handler_post (bool onvsync)
                                // CPU in STOP state: sleep if enough time left.
                                frame_time_t rpt = read_processor_time ();
                                while (!vsync_isdone () && (int)vsyncmintime - (int)(rpt + vsynctimebase / 10) > 0 && (int)vsyncmintime - (int)rpt < vsynctimebase) {
-                                       if (!execute_other_cpu(rpt + vsynctimebase / 10))
-                                               cpu_sleep_millis(1);
+                                       maybe_process_pull_audio();
+                                       if (!execute_other_cpu(rpt + vsynctimebase / 10)) {
+                                               if (cpu_sleep_millis(1) < 0)
+                                                       break;
+                                       }
                                        rpt = read_processor_time ();
                                }
                        } else if (currprefs.m68k_speed_throttle) {
                                vsyncmintime = read_processor_time (); /* end of CPU emulation time */
                                is_syncline = 0;
+                               maybe_process_pull_audio();
                        } else {
                                vsyncmintime = vsyncmaxtime; /* emulate if still time left */
                                is_syncline_end = read_processor_time () + vsynctimebase; /* far enough in future, we never wait that long */
                                is_syncline = 2;
+                               maybe_process_pull_audio();
                        }
                } else {
                        static int linecounter;
@@ -8166,6 +8229,7 @@ static void hsync_handler_post (bool onvsync)
                                                                // STOP STATE: sleep.
                                                                cpu_sleep_millis(1);
                                                                sleeps_remaining--;
+                                                               maybe_process_pull_audio();
                                                        } else {
                                                                is_syncline = 1;
                                                                /* limit extra time */
@@ -8184,16 +8248,30 @@ static void hsync_handler_post (bool onvsync)
                                        }
                                }
                        }
+                       maybe_process_pull_audio();
                }
        } else if (!currprefs.cpu_thread) {
-               if (vpos + 1 < maxvpos + lof_store && (vpos == maxvpos_display * 1 / 3 || vpos == maxvpos_display * 2 / 3)) {
+               static int nextwaitvpos;
+               if (vpos == 0)
+                       nextwaitvpos = maxvpos_display * 1 / 4;
+               if (audio_is_pull()) {
+                       while (audio_pull_buffer() > 1) {
+                               cpu_sleep_millis(1);
+                               maybe_process_pull_audio();
+                       }
+               }
+               if (vpos + 1 < maxvpos + lof_store && vpos >= nextwaitvpos && (!audio_is_pull() || (audio_is_pull() && audio_pull_buffer()))) {
+                       nextwaitvpos += maxvpos_display * 1 / 4;
                        vsyncmintime += vsynctimeperline;
                        if (!vsync_isdone () && !currprefs.turbo_emulation) {
                                frame_time_t rpt = read_processor_time ();
                                // sleep if more than 2ms "free" time
                                while (!vsync_isdone () && (int)vsyncmintime - (int)(rpt + vsynctimebase / 10) > 0 && (int)vsyncmintime - (int)rpt < vsynctimebase) {
-                                       if (!execute_other_cpu(rpt + vsynctimebase / 10))
-                                               cpu_sleep_millis(1);
+                                       maybe_process_pull_audio();
+                                       if (!execute_other_cpu(rpt + vsynctimebase / 10)) {
+                                               if (cpu_sleep_millis(1) < 0)
+                                                       break;
+                                       }
                                        rpt = read_processor_time ();
                                        //write_log (_T("*"));
                                }
@@ -8415,6 +8493,8 @@ void custom_reset (bool hardreset, bool keyboardreset)
                                }
        #endif
                        }
+                       lof_store = lof_current = 0;
+                       lof_lace = false;
                }
 
                clxdat = 0;
@@ -8446,8 +8526,6 @@ void custom_reset (bool hardreset, bool keyboardreset)
                beamcon0 = new_beamcon0 = currprefs.ntscmode ? 0x00 : 0x20;
                bltstate = BLT_done;
                blit_interrupt = 1;
-               lof_store = lof_current = 0;
-               lof_lace = false;
                init_sprites ();
        }
 
@@ -8561,6 +8639,7 @@ void custom_reset (bool hardreset, bool keyboardreset)
        sprres = expand_sprres (bplcon0, bplcon3);
        sprite_width = GET_SPRITEWIDTH (fmode);
        setup_fmodes (0);
+       shdelay_disabled = false;
 
 #ifdef ACTION_REPLAY
        /* Doing this here ensures we can use the 'reset' command from within AR */
@@ -9842,13 +9921,13 @@ static int dma_cycle (void)
 
        blitter_nasty = 1;
        if (cpu_tracer  < 0)
-               return current_hpos ();
+               return current_hpos_safe();
        if (!currprefs.cpu_memory_cycle_exact)
-               return current_hpos ();
+               return current_hpos_safe();
        while (currprefs.cpu_memory_cycle_exact) {
                int bpldma;
                int blitpri = dmacon & DMA_BLITPRI;
-               hpos_old = current_hpos ();
+               hpos_old = current_hpos_safe ();
                hpos = hpos_old + 1;
                decide_line (hpos);
                sync_copper (hpos);
index 31d03f67c5fbbb18dd0a0765c1f583439b8f163f..a27f100e4d867fc985ffc32859d41d536e2d6682 100644 (file)
--- a/debug.cpp
+++ b/debug.cpp
@@ -916,10 +916,10 @@ int notinrom (void)
 
 static uae_u32 lastaddr (void)
 {
-       if (currprefs.z3fastmem2_size)
-               return z3fastmem2_bank.start + currprefs.z3fastmem2_size;
-       if (currprefs.z3fastmem_size)
-               return z3fastmem_bank.start + currprefs.z3fastmem_size;
+       for (int i = MAX_RAM_BOARDS - 1; i >= 0; i--) {
+               if (currprefs.z3fastmem[i].size)
+                       return z3fastmem_bank[i].start + currprefs.z3fastmem[i].size;
+       }
        if (currprefs.z3chipmem_size)
                return z3chipmem_bank.start + currprefs.z3chipmem_size;
        if (currprefs.mbresmem_high_size)
@@ -928,8 +928,10 @@ static uae_u32 lastaddr (void)
                return a3000lmem_bank.start + currprefs.mbresmem_low_size;
        if (currprefs.bogomem_size)
                return bogomem_bank.start + currprefs.bogomem_size;
-       if (currprefs.fastmem_size)
-               return fastmem_bank.start + currprefs.fastmem_size;
+       for (int i = MAX_RAM_BOARDS - 1; i >= 0; i--) {
+               if (currprefs.fastmem[i].size)
+                       return fastmem_bank[i].start + currprefs.fastmem[i].size;
+       }
        return currprefs.chipmem_size;
 }
 
@@ -942,14 +944,14 @@ static uaecptr nextaddr2 (uaecptr addr, int *next)
                *next = -1;
                return 0xffffffff;
        }
-       prev = currprefs.z3autoconfig_start + currprefs.z3fastmem_size;
-       size = currprefs.z3fastmem2_size;
+       prev = currprefs.z3autoconfig_start + currprefs.z3fastmem[0].size;
+       size = currprefs.z3fastmem[1].size;
 
-       if (currprefs.z3fastmem_size) {
+       if (currprefs.z3fastmem[0].size) {
                prevx = prev;
                sizex = size;
-               size = currprefs.z3fastmem_size;
-               prev = z3fastmem_bank.start;
+               size = currprefs.z3fastmem[0].size;
+               prev = z3fastmem_bank[0].start;
                if (addr == prev + size) {
                        *next = prevx + sizex;
                        return prevx;
@@ -995,11 +997,11 @@ static uaecptr nextaddr2 (uaecptr addr, int *next)
                        return prevx;
                }
        }
-       if (currprefs.fastmem_size) {
+       if (currprefs.fastmem[0].size) {
                sizex = size;
                prevx = prev;
-               size = currprefs.fastmem_size;
-               prev = fastmem_bank.start;
+               size = currprefs.fastmem[0].size;
+               prev = fastmem_bank[0].start;
                if (addr == prev + size) {
                        *next = prevx + sizex;
                        return prevx;
@@ -2353,8 +2355,10 @@ static void illg_init (void)
                }
                addr = end - 1;
        }
-       if (currprefs.rtgboards[0].rtgmem_size)
-               memset (illghdebug + (gfxmem_bank.start >> 16), 3, currprefs.rtgboards[0].rtgmem_size >> 16);
+       for (int i = 0; i < MAX_RTG_BOARDS; i++) {
+               if (currprefs.rtgboards[i].rtgmem_size)
+                       memset (illghdebug + (gfxmem_banks[i]->start >> 16), 3, currprefs.rtgboards[i].rtgmem_size >> 16);
+       }
 
        i = 0;
        while (custd[i].name) {
@@ -2479,8 +2483,8 @@ static void smc_detect_init (TCHAR **c)
        v = readint (c);
        smc_free ();
        smc_size = 1 << 24;
-       if (currprefs.z3fastmem_size)
-               smc_size = currprefs.z3autoconfig_start + currprefs.z3fastmem_size;
+       if (currprefs.z3fastmem[0].size)
+               smc_size = currprefs.z3autoconfig_start + currprefs.z3fastmem[0].size;
        smc_size += 4;
        smc_table = xmalloc (struct smc_item, smc_size);
        if (!smc_table)
@@ -3920,6 +3924,7 @@ static void show_exec_lists (TCHAR *t)
                                list = get_long_debug(list);
                        }
                }
+               return;
        } else if (c == 'R') { // residents
                list = get_long_debug(execbase + 300);
                while (list) {
index 3d14d382a635da327fce00ecdad44ad498130d26..a444047d85d1b0bc4e1cff5d27fa1607feccc31c 100644 (file)
@@ -91,6 +91,7 @@ void devices_reset(int hardreset)
 #endif
 #ifdef WITH_TOCCATA
        sndboard_reset();
+       uaesndboard_reset();
 #endif
 #ifdef NCR
        ncr_reset();
@@ -367,6 +368,7 @@ void do_leave_program (void)
 #endif
 #ifdef WITH_TOCCATA
        sndboard_free();
+       uaesndboard_free();
 #endif
        gfxboard_free();
        savestate_free ();
@@ -433,9 +435,10 @@ void devices_restore_start(void)
        restore_blkdev_start();
        changed_prefs.bogomem_size = 0;
        changed_prefs.chipmem_size = 0;
-       changed_prefs.fastmem_size = 0;
-       changed_prefs.z3fastmem_size = 0;
-       changed_prefs.z3fastmem2_size = 0;
+       for (int i = 0; i < MAX_RAM_BOARDS; i++) {
+               changed_prefs.fastmem[i].size = 0;
+               changed_prefs.z3fastmem[i].size = 0;
+       }
        changed_prefs.mbresmem_low_size = 0;
        changed_prefs.mbresmem_high_size = 0;
 }
index 0778849a0078b16e5f8d11a27d0e7c78213cfbb2..726cde0769a4d80363ad55b22191289a03cc8a26 100644 (file)
@@ -120,8 +120,9 @@ public:
 
 
 extern void write_log(const char*,...);
-extern void vga_ram_put(int offset, uint8_t v);
-extern uint8_t vga_ram_get(int offset);
+extern void vga_ram_put(int board, int offset, uint8_t v);
+extern uint8_t vga_ram_get(int board, int offset);
+extern int x86_vga_board;
 
 
 class VGA_Handler : public PageHandler {
@@ -130,11 +131,11 @@ public:
                flags = PFLAG_NOCODE;
        }
        Bitu readb(PhysPt addr) {
-               return vga_ram_get(addr);
+               return vga_ram_get(x86_vga_board, addr);
        }
        Bitu readw(PhysPt addr) {
-               Bitu v = vga_ram_get(addr) << 0;
-               v |= vga_ram_get(addr + 1) << 8;
+               Bitu v = vga_ram_get(x86_vga_board,addr) << 0;
+               v |= vga_ram_get(x86_vga_board, addr + 1) << 8;
                return v;
        }
        Bitu readd(PhysPt addr) {
@@ -143,11 +144,11 @@ public:
                return v;
        }
        void writeb(PhysPt addr, Bitu val) {
-               vga_ram_put(addr, val);
+               vga_ram_put(x86_vga_board, addr, val);
        }
        void writew(PhysPt addr, Bitu val) {
-               vga_ram_put(addr, val);
-               vga_ram_put(addr + 1, val >> 8);
+               vga_ram_put(x86_vga_board, addr, val);
+               vga_ram_put(x86_vga_board, addr + 1, val >> 8);
                return;
        }
        void writed(PhysPt addr, Bitu val) {
index 001ce47110ffa5367fc05ef4c61c536272a76129..0b50ac3e7348a5776719605d45ae797b140e1697 100644 (file)
@@ -50,6 +50,7 @@ happening, all ports should restrict window widths to be multiples of 16 pixels.
 #include "debug.h"
 #include "cd32_fmv.h"
 #include "specialmonitors.h"
+#include "devices.h"
 
 #define BG_COLOR_DEBUG 0
 //#define XLINECHECK
@@ -260,6 +261,7 @@ static bool specialmonitoron;
 static bool ecs_genlock_features_active;
 static uae_u8 ecs_genlock_features_mask;
 static bool ecs_genlock_features_colorkey;
+static int hsync_shift_hack;
 
 bool picasso_requested_on, picasso_requested_forced_on, picasso_on;
 
@@ -331,7 +333,7 @@ static void reset_decision_table (void)
 STATIC_INLINE void count_frame (void)
 {
        framecnt++;
-       if (framecnt >= currprefs.gfx_framerate)
+       if (framecnt >= currprefs.gfx_framerate || currprefs.monitoremu == MONITOREMU_A2024)
                framecnt = 0;
        if (inhibit_frame)
                framecnt = 1;
@@ -861,6 +863,8 @@ static void pfield_init_linetoscr (bool border)
        int leftborderhidden;
        int native_ddf_left2;
 
+       hsync_shift_hack = 0;
+       
        if (border)
                ddf_left = DISPLAY_LEFT_SHIFT;
 
@@ -2168,16 +2172,18 @@ STATIC_INLINE void draw_sprites_1 (struct sprite_entry *e, int dualpf, int has_a
        uae_u16 *buf = spixels + e->first_pixel;
        uae_u8 *stbuf = spixstate.bytes + e->first_pixel;
        int spr_pos, pos;
+       int epos = e->pos;
+       int emax = e->max;
 
-       buf -= e->pos;
-       stbuf -= e->pos;
+       buf -= epos;
+       stbuf -= epos;
 
-       spr_pos = e->pos + ((DIW_DDF_OFFSET - DISPLAY_LEFT_SHIFT) << sprite_buffer_res);
+       spr_pos = epos + ((DIW_DDF_OFFSET - DISPLAY_LEFT_SHIFT) << sprite_buffer_res);
 
        if (spr_pos < sprite_first_x)
                sprite_first_x = spr_pos;
 
-       for (pos = e->pos; pos < e->max; pos++, spr_pos++) {
+       for (pos = epos; pos < emax; pos++, spr_pos++) {
                if (spr_pos >= 0 && spr_pos < MAX_PIXELS_PER_LINE) {
                        spritepixels[spr_pos].data = buf[pos];
                        spritepixels[spr_pos].stdata = stbuf[pos];
@@ -2812,6 +2818,8 @@ static void do_color_changes (line_draw_func worker_border, line_draw_func worke
                                colors_for_drawing.extra &= ~(1 << (CE_SHRES_DELAY + 1));
                                colors_for_drawing.extra |= (value & 3) << CE_SHRES_DELAY;
                                pfield_expand_dp_bplcon();
+                       } else if (regno == 0 && (value & COLOR_CHANGE_HSYNC_HACK)) {
+                               hsync_shift_hack = (uae_s8)value;
                        } else {
                                color_reg_set (&colors_for_drawing, regno, value);
                                colors_for_drawing.acolors[regno] = getxcolor (value);
@@ -2828,6 +2836,16 @@ static void do_color_changes (line_draw_func worker_border, line_draw_func worke
                (*worker_border) (visible_left_border, visible_left_border + gfxvidinfo.drawbuffer.inwidth, true);
        }
 #endif
+       if (hsync_shift_hack > 0) {
+               // hpos shift hack
+               int shift = (hsync_shift_hack << lores_shift) * gfxvidinfo.drawbuffer.pixbytes;
+               if (shift) {
+                       int firstpos = visible_left_border * gfxvidinfo.drawbuffer.pixbytes;
+                       int lastpos = (visible_left_border + gfxvidinfo.drawbuffer.inwidth) * gfxvidinfo.drawbuffer.pixbytes;
+                       memmove(xlinebuffer + firstpos, xlinebuffer + firstpos + shift, lastpos - firstpos - shift);
+                       memset(xlinebuffer + lastpos - shift, 0, shift);
+               }
+       }
 }
 
 STATIC_INLINE bool is_color_changes(struct draw_info *di)
@@ -3816,7 +3834,7 @@ void hardware_line_completed (int lineno)
 #endif
 }
 
-static void check_picasso (void)
+void check_prefs_picasso(void)
 {
 #ifdef PICASSO96
        if (picasso_on && picasso_redraw_necessary)
@@ -3826,6 +3844,15 @@ static void check_picasso (void)
        if (picasso_requested_on == picasso_on && !picasso_requested_forced_on)
                return;
 
+       if (picasso_requested_on) {
+               if (!toggle_rtg(-2)) {
+                       picasso_requested_forced_on = false;
+                       picasso_on = false;
+                       picasso_requested_on = false;
+                       return;
+               }
+       }
+
        picasso_requested_forced_on = false;
        picasso_on = picasso_requested_on;
 
@@ -3867,11 +3894,7 @@ bool vsync_handle_check (void)
                notice_screen_contents_lost ();
                notice_new_xcolors ();
        }
-       check_prefs_changed_cd ();
-       check_prefs_changed_audio ();
-       check_prefs_changed_custom ();
-       check_prefs_changed_cpu ();
-       check_picasso ();
+       device_check_config();
        return changed != 0;
 }
 
@@ -4124,6 +4147,7 @@ void reset_drawing (void)
        center_reset = true;
        specialmonitoron = false;
        bplcolorburst_field = 1;
+       hsync_shift_hack = 0;
 }
 
 static void gen_direct_drawing_table(void)
@@ -4164,7 +4188,7 @@ void drawing_init (void)
 
 int isvsync_chipset (void)
 {
-       if (picasso_on || currprefs.gfx_apmode[0].gfx_vsync <= 0 || (currprefs.gfx_apmode[0].gfx_vsync <= 0 && !currprefs.gfx_apmode[0].gfx_fullscreen))
+       if (picasso_on || currprefs.gfx_apmode[0].gfx_vsync <= 0)
                return 0;
        if (currprefs.gfx_apmode[0].gfx_vsyncmode == 0)
                return 1;
@@ -4175,7 +4199,7 @@ int isvsync_chipset (void)
 
 int isvsync_rtg (void)
 {
-       if (!picasso_on || currprefs.gfx_apmode[1].gfx_vsync <= 0 || (currprefs.gfx_apmode[1].gfx_vsync <= 0 && !currprefs.gfx_apmode[1].gfx_fullscreen))
+       if (!picasso_on || currprefs.gfx_apmode[1].gfx_vsync <= 0)
                return 0;
        if (currprefs.gfx_apmode[1].gfx_vsyncmode == 0)
                return 1;
index 93dcc51bc1a564348c3d7e8672704108c4387e9e..2790f4caeff71012ff1d6d54573ef73f4df44233 100644 (file)
@@ -23,6 +23,7 @@
 #include "zfile.h"
 #include "catweasel.h"
 #include "cdtv.h"
+#include "cdtvcr.h"
 #include "threaddep/thread.h"
 #include "a2091.h"
 #include "a2065.h"
 #include "x86.h"
 #include "filesys.h"
 
+
+#define CARD_FLAG_CAN_Z3 1
+#define CARD_FLAG_CHILD 8
+
 // More information in first revision HRM Appendix_G
 #define BOARD_PROTOAUTOCONFIG 1
 
@@ -164,6 +169,7 @@ uaecptr ROM_hardfile_init;
 int uae_boot_rom_type;
 int uae_boot_rom_size; /* size = code size only */
 static bool chipdone;
+static int do_mount;
 
 #define FILESYS_DIAGPOINT 0x01e0
 #define FILESYS_BOOTPOINT 0x01e6
@@ -173,16 +179,23 @@ static bool chipdone;
 
 struct card_data
 {
-       addrbank *(*initrc)(struct romconfig*);
-       addrbank *(*initnum)(int);
-       addrbank *(*map)(void);
+       bool (*initrc)(struct autoconfig_info*);
+       bool (*initnum)(struct autoconfig_info*);
+       addrbank *(*map)(struct autoconfig_info*);
        struct romconfig *rc;
        const TCHAR *name;
        int flags;
        int zorro;
+       uaecptr base;
+       uae_u32 size;
+       // parsing updated fields
+       const struct expansionromtype *ert;
+       const struct cpuboardsubtype *cst;
+       struct autoconfig_info aci;
 };
 
-static struct card_data cards[MAX_EXPANSION_BOARD_SPACE];
+static struct card_data cards_set[MAX_EXPANSION_BOARD_SPACE];
+static struct card_data *cards[MAX_EXPANSION_BOARD_SPACE];
 
 static int ecard, cardno, z3num;
 static addrbank *expamem_bank_current;
@@ -230,32 +243,31 @@ static bool ks11orolder(void)
 
 /* Autoconfig address space at 0xE80000 */
 static uae_u8 expamem[65536];
+static addrbank*(*expamem_map)(struct autoconfig_info*);
 
 static uae_u8 expamem_lo;
 static uae_u16 expamem_hi;
-static uaecptr expamem_z3_sum;
-uaecptr expamem_z3_pointer;
-uaecptr expamem_z2_pointer;
-uae_u32 expamem_z3_size;
-uae_u32 expamem_z2_size;
-static uae_u32 expamem_board_size;
-static uae_u32 expamem_board_pointer;
-static bool z3hack_override;
+uaecptr expamem_z3_pointer_real, expamem_z3_pointer_uae;
+uaecptr expamem_highmem_pointer;
+uae_u32 expamem_board_size;
+uaecptr expamem_board_pointer;
+static uae_u8 slots_e8[8] = { 0 };
+static uae_u8 slots_20[(8 * 1024 * 1024) / 65536] = { 0 };
 
-void set_expamem_z3_hack_override(bool overridenoz3hack)
+static int z3hack_override;
+
+void set_expamem_z3_hack_mode(int mode)
 {
-       z3hack_override = overridenoz3hack;
+       z3hack_override = mode;
 }
 
 bool expamem_z3hack(struct uae_prefs *p)
 {
-       if (z3hack_override)
-               return false;
-#ifdef WITH_PPC
-       if (regs.halted && ppc_state)
+       if (z3hack_override == Z3MAPPING_UAE)
+               return true;
+       if (z3hack_override == Z3MAPPING_REAL)
                return false;
-#endif
-       return p->z3_mapping_mode == Z3MAPPING_AUTO || p->z3_mapping_mode == Z3MAPPING_UAE || cpuboard_memorytype(p) == BOARD_MEMORY_BLIZZARD_12xx;
+       return p->z3_mapping_mode == Z3MAPPING_UAE || cpuboard_memorytype(p) == BOARD_MEMORY_BLIZZARD_12xx;
 }
 
 /* Ugly hack for >2M chip RAM in single pool
@@ -312,7 +324,7 @@ static void addextrachip (uae_u32 sysbase)
        }
 }
 
-addrbank expamem_null, expamem_none;
+addrbank expamem_null, expamem_none, expamem_nonautoconfig;
 
 DECLARE_MEMORY_FUNCTIONS(expamem);
 addrbank expamem_bank = {
@@ -340,13 +352,20 @@ static addrbank *expamem_map_clear (void)
 static void expamem_init_clear (void)
 {
        memset (expamem, 0xff, sizeof expamem);
+       expamem_map = NULL;
 }
 /* autoconfig area is "non-existing" after last device */
 static void expamem_init_clear_zero (void)
 {
-       map_banks(&dummy_bank, 0xe8, 1, 0);
-       if (!currprefs.address_space_24)
-               map_banks(&dummy_bank, 0xff000000 >> 16, 1, 0);
+       if (currprefs.cpu_model < 68020) {
+               map_banks(&dummy_bank, 0xe8, 1, 0);
+               if (!currprefs.address_space_24)
+                       map_banks(&dummy_bank, 0xff000000 >> 16, 1, 0);
+       } else {
+               map_banks(&expamem_bank, 0xe8, 1, 0);
+               if (!currprefs.address_space_24)
+                       map_banks(&expamem_bank, 0xff000000 >> 16, 1, 0);
+       }
 }
 
 static void expamem_init_clear2 (void)
@@ -394,16 +413,31 @@ static int REGPARAM2 expamem_type (void)
 static void call_card_init(int index)
 {      
        addrbank *ab, *abe;
-       uae_u8 code;
-       uae_u32 expamem_z3_pointer_old;
-       card_data *cd = &cards[ecard];
+       card_data *cd = cards[ecard];
+       struct autoconfig_info *aci = &cd->aci;
+       bool ok = false;
 
        expamem_bank.name = cd->name ? cd->name : _T("None");
-       if (cd->initnum)
-               ab = cd->initnum(0);
-       else
-               ab = cd->initrc(cd->rc);
-       expamem_z3_size = 0;
+       aci->prefs = &currprefs;
+       aci->doinit = true;
+       aci->devnum = (cd->flags >> 16) & 255;
+       aci->ert = cd->ert;
+       aci->cst = cd->cst;
+       aci->rc = cd->rc;
+       memset(aci->autoconfig_raw, 0xff, sizeof aci->autoconfig_raw);
+       if (cd->initnum) {
+               ok = cd->initnum(aci);
+       } else {
+               ok = cd->initrc(aci);
+       }
+       if (ok) {
+               ab = NULL;
+               if (!cd->map)
+                       ab = aci->addrbank;
+       } else {
+               expamem_next(NULL, NULL);
+               return;
+       }
        if (ab == &expamem_none) {
                expamem_init_clear();
                expamem_init_clear_zero();
@@ -413,11 +447,14 @@ static void call_card_init(int index)
                expamem_bank_current = NULL;
                return;
        }
-       if (ab == &expamem_null) {
+       if (ab == &expamem_null || ab == &expamem_nonautoconfig) {
                expamem_next(NULL, NULL);
                return;
        }
 
+       expamem_board_pointer = cd->base;
+       expamem_board_size = cd->size;
+
        abe = ab;
        if (!abe)
                abe = &expamem_bank;
@@ -426,65 +463,10 @@ static void call_card_init(int index)
                        expamem[i] = abe->bget(i);
        }
 
-       code = expamem_read(0);
-       if ((code & 0xc0) == zorroII) {
-               // Z2
-               code &= 7;
-               if (code == 0)
-                       expamem_z2_size = 8 * 1024 * 1024;
-               else
-                       expamem_z2_size = 32768 << code;
-
-               expamem_board_size = expamem_z2_size;
-               expamem_board_pointer = expamem_z2_pointer;
-
-       } else if ((code & 0xc0) == zorroIII) {
-               // Z3
-               if (expamem_z3_sum < Z3BASE_UAE) {
-                       expamem_z3_sum = currprefs.z3autoconfig_start;
-                       if (currprefs.mbresmem_high_size >= 128 * 1024 * 1024 && expamem_z3_sum == Z3BASE_UAE)
-                               expamem_z3_sum += (currprefs.mbresmem_high_size - 128 * 1024 * 1024) + 16 * 1024 * 1024;
-                       if (!expamem_z3hack(&currprefs))
-                               expamem_z3_sum = Z3BASE_REAL;
-                       if (expamem_z3_sum == Z3BASE_UAE) {
-                               expamem_z3_sum += currprefs.z3chipmem_size;
-                       }
-               }
-
-               expamem_z3_pointer = expamem_z3_sum;
-
-               code &= 7;
-               if (expamem_read(8) & ext_size)
-                       expamem_z3_size = (16 * 1024 * 1024) << code;
-               else
-                       expamem_z3_size = 16 * 1024 * 1024;
-               expamem_z3_sum += expamem_z3_size;
-
-               expamem_z3_pointer_old = expamem_z3_pointer;
-               // align non-UAE 32M boards (FastLane is 32M and needs to be aligned)
-               if (expamem_z3_size <= 32 * 1024 * 1024 && !(cd->flags & 16))
-                       expamem_z3_pointer = (expamem_z3_pointer + expamem_z3_size - 1) & ~(expamem_z3_size - 1);
-
-               expamem_z3_sum += expamem_z3_pointer - expamem_z3_pointer_old;
-
-               expamem_board_size = expamem_z3_size;
-               expamem_board_pointer = expamem_z3_pointer;
-
-       } else if ((code & 0xc0) == 0x40) {
-               // 0x40 = "Box without init/diagnostic code"
-               // proto autoconfig "box" size.
-               //expamem_z2_size = (1 << ((code >> 3) & 7)) * 4096;
-               // much easier this way, all old-style boards were made for
-               // A1000 and didn't have passthrough connector.
-               expamem_z2_size = 65536;
-               expamem_board_size = expamem_z2_size;
-               expamem_board_pointer = expamem_z2_pointer;
-       }
-
        if (ab) {
                // non-NULL: not using expamem_bank
                expamem_bank_current = ab;
-               if ((cd->flags & 1) && currprefs.cs_z3autoconfig && !currprefs.address_space_24) {
+               if ((cd->flags & CARD_FLAG_CAN_Z3) && currprefs.cs_z3autoconfig && !currprefs.address_space_24) {
                        map_banks(&expamemz3_bank, 0xff000000 >> 16, 1, 0);
                        map_banks(&dummy_bank, 0xE8, 1, 0);
                } else {
@@ -493,7 +475,7 @@ static void call_card_init(int index)
                                map_banks(&dummy_bank, 0xff000000 >> 16, 1, 0);
                }
        } else {
-               if ((cd->flags & 1) && currprefs.cs_z3autoconfig && !currprefs.address_space_24) {
+               if ((cd->flags & CARD_FLAG_CAN_Z3) && currprefs.cs_z3autoconfig && !currprefs.address_space_24) {
                        map_banks(&expamemz3_bank, 0xff000000 >> 16, 1, 0);
                        map_banks(&dummy_bank, 0xE8, 1, 0);
                        expamem_bank_current = &expamem_bank;
@@ -522,7 +504,7 @@ static void boardmessage(addrbank *mapped, bool success)
                expamem_board_pointer, size, sizemod,
                type & rom_card ? _T("ROM") : (type & add_memory ? _T("RAM") : _T("IO ")),
                mapped->name,
-               success ? _T("") : _T(" SHUT UP"));
+               success ? _T("") : _T(" [SHUT UP]"));
 #if 0
        for (int i = 0; i < 16; i++) {
                write_log(_T("%s%02X"), i > 0 ? _T(".") : _T(""), expamem_read(i * 4));
@@ -533,14 +515,16 @@ static void boardmessage(addrbank *mapped, bool success)
 
 void expamem_shutup(addrbank *mapped)
 {
-       if (mapped)
+       if (mapped) {
+               mapped->start = 0xffffffff;
                boardmessage(mapped, false);
+       }
 }
 
-void expamem_next (addrbank *mapped, addrbank *next)
+void expamem_next(addrbank *mapped, addrbank *next)
 {
        if (mapped)
-               boardmessage(mapped, true);
+               boardmessage(mapped, mapped->start != 0xffffffff);
 
        expamem_init_clear();
        expamem_init_clear_zero();
@@ -548,9 +532,13 @@ void expamem_next (addrbank *mapped, addrbank *next)
                ++ecard;
                if (ecard >= cardno)
                        break;
-               struct card_data *ec = &cards[ecard];
+               struct card_data *ec = cards[ecard];
                if (ec->initrc && isnonautoconfig(ec->zorro)) {
-                       ec->initrc(cards[ecard].rc);
+                       struct autoconfig_info aci = { 0 };
+                       aci.doinit = true;
+                       aci.prefs = &currprefs;
+                       aci.rc = cards[ecard]->rc;
+                       ec->initrc(&aci);
                } else {
                        call_card_init(ecard);
                        break;
@@ -562,7 +550,6 @@ void expamem_next (addrbank *mapped, addrbank *next)
        }
 }
 
-
 static uae_u32 REGPARAM2 expamem_lget (uaecptr addr)
 {
        if (expamem_bank_current && expamem_bank_current != &expamem_bank)
@@ -632,6 +619,8 @@ static void REGPARAM2 expamem_wput (uaecptr addr, uae_u32 value)
        }
        if (ecard >= cardno)
                return;
+       if (!expamem_map)
+               expamem_map = cards[ecard]->map;
        if (expamem_type () != zorroIII) {
                write_log (_T("warning: WRITE.W to address $%08x : value $%x PC=%08x\n"), addr, value, M68K_GETPC);
        }
@@ -641,10 +630,9 @@ static void REGPARAM2 expamem_wput (uaecptr addr, uae_u32 value)
                if (expamem_type() == zorroII) {
                        expamem_lo = 0;
                        expamem_hi = (value >> 8) & 0xff;
-                       expamem_z2_pointer = (expamem_hi | (expamem_lo >> 4)) << 16; 
-                       expamem_board_pointer = expamem_z2_pointer;
-                       if (cards[ecard].map) {
-                               expamem_next(cards[ecard].map(), NULL);
+                       expamem_board_pointer = (expamem_hi | (expamem_lo >> 4)) << 16;
+                       if (expamem_map) {
+                               expamem_next(expamem_map(&cards[ecard]->aci), NULL);
                                return;
                        }
                        if (expamem_bank_current && expamem_bank_current != &expamem_bank) {
@@ -659,22 +647,21 @@ static void REGPARAM2 expamem_wput (uaecptr addr, uae_u32 value)
                        expamem_hi = value & 0xff00;
                        addr = (expamem_hi | (expamem_lo >> 4)) << 16;
                        if (!expamem_z3hack(&currprefs)) {
-                               expamem_z3_pointer = addr;
+                               expamem_board_pointer = addr;
                        } else {
-                               if (addr != expamem_z3_pointer) {
-                                       put_word (regs.regs[11] + 0x20, expamem_z3_pointer >> 16);
-                                       put_word (regs.regs[11] + 0x28, expamem_z3_pointer >> 16);
+                               if (addr != expamem_board_pointer) {
+                                       put_word (regs.regs[11] + 0x20, expamem_board_pointer >> 16);
+                                       put_word (regs.regs[11] + 0x28, expamem_board_pointer >> 16);
                                }
                        }
-                       expamem_board_pointer = expamem_z3_pointer;
                }
-               if (cards[ecard].map) {
-                       expamem_next(cards[ecard].map(), NULL);
+               if (expamem_map) {
+                       expamem_next(expamem_map(&cards[ecard]->aci), NULL);
                        return;
                }
                break;
        case 0x4c:
-               if (cards[ecard].map) {
+               if (expamem_map) {
                        expamem_next (NULL, NULL);
                        return;
                }
@@ -696,14 +683,15 @@ static void REGPARAM2 expamem_bput (uaecptr addr, uae_u32 value)
        }
        if (ecard >= cardno)
                return;
+       if (!expamem_map)
+               expamem_map = cards[ecard]->map;
        if (expamem_type() == protoautoconfig) {
                switch (addr & 0xff) {
                case 0x22:
                        expamem_hi = value & 0x7f;
-                       expamem_z2_pointer = 0xe80000 | (expamem_hi * 4096);
-                       expamem_board_pointer = expamem_z2_pointer;
-                       if (cards[ecard].map) {
-                               expamem_next(cards[ecard].map(), NULL);
+                       expamem_board_pointer = 0xe80000 | (expamem_hi * 4096);
+                       if (expamem_map) {
+                               expamem_next(expamem_map(&cards[ecard]->aci), NULL);
                                return;
                        }
                        break;
@@ -713,10 +701,9 @@ static void REGPARAM2 expamem_bput (uaecptr addr, uae_u32 value)
                case 0x48:
                        if (expamem_type() == zorroII) {
                                expamem_hi = value & 0xff;
-                               expamem_z2_pointer = (expamem_hi | (expamem_lo >> 4)) << 16; 
-                               expamem_board_pointer = expamem_z2_pointer;
-                               if (cards[ecard].map) {
-                                       expamem_next(cards[ecard].map(), NULL);
+                               expamem_board_pointer = (expamem_hi | (expamem_lo >> 4)) << 16;
+                               if (expamem_map) {
+                                       expamem_next(expamem_map(&cards[ecard]->aci), NULL);
                                        return;
                                }
                        } else {
@@ -730,8 +717,13 @@ static void REGPARAM2 expamem_bput (uaecptr addr, uae_u32 value)
                        break;
 
                case 0x4c:
-                       if (cards[ecard].map) {
-                               expamem_next(expamem_bank_current, NULL);
+                       if (expamem_map) {
+                               expamem_hi = expamem_lo = 0xff;
+                               expamem_board_pointer = 0xffffffff;
+                               addrbank *ab = expamem_map(&cards[ecard]->aci);
+                               if (ab)
+                                       ab->start = 0xffffffff;
+                               expamem_next(ab, NULL);
                                return;
                        }
                        break;
@@ -774,8 +766,7 @@ static void REGPARAM2 expamemz3_bput (uaecptr addr, uae_u32 value)
        if (reg == 0x48) {
                if (expamem_type() == zorroII) {
                        expamem_hi = value & 0xff;
-                       expamem_z2_pointer = (expamem_hi | (expamem_lo >> 4)) << 16; 
-                       expamem_board_pointer = expamem_z2_pointer;
+                       expamem_board_pointer = (expamem_hi | (expamem_lo >> 4)) << 16;
                } else {
                        expamem_lo = value & 0xff;
                }
@@ -799,14 +790,13 @@ static void REGPARAM2 expamemz3_wput (uaecptr addr, uae_u32 value)
                        expamem_hi = value & 0xff00;
                        addr = (expamem_hi | (expamem_lo >> 4)) << 16;;
                        if (!expamem_z3hack(&currprefs)) {
-                               expamem_z3_pointer = addr;
+                               expamem_board_pointer = addr;
                        } else {
-                               if (addr != expamem_z3_pointer) {
-                                       put_word (regs.regs[11] + 0x20, expamem_z3_pointer >> 16);
-                                       put_word (regs.regs[11] + 0x28, expamem_z3_pointer >> 16);
+                               if (addr != expamem_board_pointer) {
+                                       put_word (regs.regs[11] + 0x20, expamem_board_pointer >> 16);
+                                       put_word (regs.regs[11] + 0x28, expamem_board_pointer >> 16);
                                }
                        }
-                       expamem_board_pointer = expamem_z3_pointer;
                }
        }
        expamem_bank_current->wput(reg, value);
@@ -818,29 +808,13 @@ static void REGPARAM2 expamemz3_lput (uaecptr addr, uae_u32 value)
 
 #ifdef CD32
 
-static addrbank *expamem_map_cd32fmv (void)
+static bool expamem_init_cd32fmv (struct autoconfig_info *aci)
 {
-       return cd32_fmv_init (expamem_z2_pointer);
-}
-
-static addrbank *expamem_init_cd32fmv (int devnum)
-{
-       int ids[] = { 23, -1 };
-       struct romlist *rl = getromlistbyids (ids, NULL);
-       struct romdata *rd;
-       struct zfile *z;
-
        expamem_init_clear ();
-       if (!rl)
-               return NULL;
-       write_log (_T("CD32 FMV ROM '%s' %d.%d\n"), rl->path, rl->rd->ver, rl->rd->rev);
-       rd = rl->rd;
-       z = read_rom (rd);
-       if (z) {
-               zfile_fread (expamem, 128, 1, z);
-               zfile_fclose (z);
-       }
-       return NULL;
+       load_rom_rc(aci->rc, ROMTYPE_CD32CART, 262144, 0, expamem, 128, 0);
+       memcpy(aci->autoconfig_raw, expamem, sizeof aci->autoconfig_raw);
+       expamem_map = cd32_fmv_init;
+       return true;
 }
 
 #endif
@@ -852,46 +826,41 @@ static addrbank *expamem_init_cd32fmv (int devnum)
 */
 
 
-MEMORY_FUNCTIONS(fastmem);
-MEMORY_FUNCTIONS(fastmem_nojit);
-MEMORY_FUNCTIONS(fastmem2);
-MEMORY_FUNCTIONS(fastmem2_nojit);
-
-addrbank fastmem_bank = {
-       fastmem_lget, fastmem_wget, fastmem_bget,
-       fastmem_lput, fastmem_wput, fastmem_bput,
-       fastmem_xlate, fastmem_check, NULL, _T("fast"), _T("Fast memory"),
-       fastmem_lget, fastmem_wget,
-       ABFLAG_RAM | ABFLAG_THREADSAFE, 0, 0
-};
-addrbank fastmem_nojit_bank = {
-       fastmem_nojit_lget, fastmem_nojit_wget, fastmem_bget,
-       fastmem_nojit_lput, fastmem_nojit_wput, fastmem_bput,
-       fastmem_nojit_xlate, fastmem_nojit_check, NULL, NULL, _T("Fast memory (nojit)"),
-       fastmem_nojit_lget, fastmem_nojit_wget,
-       ABFLAG_RAM | ABFLAG_THREADSAFE, S_READ, S_WRITE
-};
-addrbank fastmem2_bank = {
-       fastmem2_lget, fastmem2_wget, fastmem2_bget,
-       fastmem2_lput, fastmem2_wput, fastmem2_bput,
-       fastmem2_xlate, fastmem2_check, NULL,_T("fast2"), _T("Fast memory 2"),
-       fastmem2_lget, fastmem2_wget,
-       ABFLAG_RAM | ABFLAG_THREADSAFE, 0, 0
-};
-addrbank fastmem2_nojit_bank = {
-       fastmem2_nojit_lget, fastmem2_nojit_wget, fastmem2_nojit_bget,
-       fastmem2_nojit_lput, fastmem2_nojit_wput, fastmem2_nojit_bput,
-       fastmem2_nojit_xlate, fastmem2_nojit_check, NULL, NULL, _T("Fast memory #2 (nojit)"),
-       fastmem2_nojit_lget, fastmem2_nojit_wget,
-       ABFLAG_RAM | ABFLAG_THREADSAFE, S_READ, S_WRITE
-};
+MEMORY_ARRAY_FUNCTIONS(fastmem, 0);
+MEMORY_ARRAY_FUNCTIONS(fastmem, 1);
+MEMORY_ARRAY_FUNCTIONS(fastmem, 2);
+MEMORY_ARRAY_FUNCTIONS(fastmem, 3);
 
-static addrbank *fastbanks[] = 
+addrbank fastmem_bank[MAX_RAM_BOARDS] =
 {
-       &fastmem_bank,
-       &fastmem_nojit_bank,
-       &fastmem2_bank,
-       &fastmem2_nojit_bank
+       {
+               fastmem0_lget, fastmem0_wget, fastmem0_bget,
+               fastmem0_lput, fastmem0_wput, fastmem0_bput,
+               fastmem0_xlate, fastmem0_check, NULL, _T("*"), _T("Fast memory"),
+               fastmem0_lget, fastmem0_wget,
+               ABFLAG_RAM | ABFLAG_THREADSAFE, 0, 0
+       },
+       {
+               fastmem1_lget, fastmem1_wget, fastmem1_bget,
+               fastmem1_lput, fastmem1_wput, fastmem1_bput,
+               fastmem1_xlate, fastmem1_check, NULL, _T("*"), _T("Fast memory 2"),
+               fastmem1_lget, fastmem1_wget,
+               ABFLAG_RAM | ABFLAG_THREADSAFE, 0, 0
+       },
+       {
+               fastmem2_lget, fastmem2_wget, fastmem2_bget,
+               fastmem2_lput, fastmem2_wput, fastmem2_bput,
+               fastmem2_xlate, fastmem2_check, NULL, _T("*"), _T("Fast memory 3"),
+               fastmem2_lget, fastmem2_wget,
+               ABFLAG_RAM | ABFLAG_THREADSAFE, 0, 0
+       },
+       {
+               fastmem3_lget, fastmem3_wget, fastmem3_bget,
+               fastmem3_lput, fastmem3_wput, fastmem3_bput,
+               fastmem3_xlate, fastmem3_check, NULL, _T("*"), _T("Fast memory 4"),
+               fastmem3_lget, fastmem3_wget,
+               ABFLAG_RAM | ABFLAG_THREADSAFE, 0, 0
+       }
 };
 
 #ifdef CATWEASEL
@@ -960,14 +929,14 @@ static addrbank catweasel_bank = {
        ABFLAG_IO, S_READ, S_WRITE
 };
 
-static addrbank *expamem_map_catweasel (void)
+static addrbank *expamem_map_catweasel (int devnum)
 {
-       catweasel_start = expamem_z2_pointer;
+       catweasel_start = expamem_board_pointer;
        map_banks_z2(&catweasel_bank, catweasel_start >> 16, 1);
        return &catweasel_bank;
 }
 
-static addrbank *expamem_init_catweasel (int devnum)
+static bool expamem_init_catweasel (struct autoconfig_info *aci)
 {
        uae_u8 productid = cwc.type >= CATWEASEL_TYPE_MK3 ? 66 : 200;
        uae_u16 vendorid = cwc.type >= CATWEASEL_TYPE_MK3 ? 4626 : 5001;
@@ -994,7 +963,10 @@ static addrbank *expamem_init_catweasel (int devnum)
        expamem_write (0x2c, 0x00); /* ROM-Offset lo */
 
        expamem_write (0x40, 0x00); /* Ctrl/Statusreg.*/
-       return NULL;
+
+       memcpy(aci->autoconfig_raw, expamem, sizeof aci->autoconfig_raw);
+
+       return true;
 }
 
 #endif
@@ -1106,7 +1078,7 @@ DECLARE_MEMORY_FUNCTIONS(uaeboard);
 addrbank uaeboard_bank = {
        uaeboard_lget, uaeboard_wget, uaeboard_bget,
        uaeboard_lput, uaeboard_wput, uaeboard_bput,
-       uaeboard_xlate, uaeboard_check, NULL, _T("uaeboard"), _T("UAE Board"),
+       uaeboard_xlate, uaeboard_check, NULL, _T("*"), _T("UAE Board"),
        dummy_lgeti, dummy_wgeti,
        ABFLAG_IO | ABFLAG_SAFE | ABFLAG_PPCIOSPACE, S_READ, S_WRITE
 };
@@ -1217,9 +1189,9 @@ static uae_u8 *REGPARAM2 uaeboard_xlate(uaecptr addr)
        return filesys_bank.baseaddr + addr;
 }
 
-static addrbank *expamem_map_uaeboard(void)
+static addrbank *expamem_map_uaeboard(struct autoconfig_info *aci)
 {
-       uaeboard_base = expamem_z2_pointer;
+       uaeboard_base = expamem_board_pointer;
        uaeboard_ram_start = UAEBOARD_WRITEOFFSET;
        uaeboard_bank.start = uaeboard_base;
        map_banks_z2(&uaeboard_bank, uaeboard_base >> 16, 1);
@@ -1230,14 +1202,31 @@ static addrbank *expamem_map_uaeboard(void)
        return &uaeboard_bank;
 }
 
-static addrbank* expamem_init_uaeboard(int devnum)
+static bool get_params_filesys(struct uae_prefs *prefs, struct expansion_params *p)
+{
+       p->device_order = prefs->uaeboard_order;
+       return true;
+}
+static bool set_params_filesys(struct uae_prefs *prefs, struct expansion_params *p)
+{
+       prefs->uaeboard_order = p->device_order;
+       return true;
+}
+
+static bool expamem_init_uaeboard(struct autoconfig_info *aci)
 {
        bool ks12 = ks12orolder();
-       bool hide = currprefs.uae_hide_autoconfig;
-       bool rom = currprefs.uaeboard > 1;
+       struct uae_prefs *p = aci->prefs;
+       bool hide = p->uae_hide_autoconfig;
+       bool rom = p->uaeboard > 1;
+
+       aci->label = _T("UAE Boot ROM");
+       aci->addrbank = &uaeboard_bank;
+       aci->get_params = get_params_filesys;
+       aci->set_params = set_params_filesys;
 
        expamem_init_clear();
-       expamem_write(0x00, (currprefs.uaeboard > 1 ? Z2_MEM_128KB : Z2_MEM_64KB) | zorroII | (ks12 || !rom ? 0 : rom_card));
+       expamem_write(0x00, (p->uaeboard > 1 ? Z2_MEM_128KB : Z2_MEM_64KB) | zorroII | (ks12 || !rom ? 0 : rom_card));
 
        expamem_write(0x08, no_shutup);
 
@@ -1247,10 +1236,10 @@ static addrbank* expamem_init_uaeboard(int devnum)
 
        expamem_write(0x18, 0x00); /* ser.no. Byte 0 */
        expamem_write(0x1c, 0x00); /* ser.no. Byte 1 */
-       expamem_write(0x20, currprefs.uaeboard); /* ser.no. Byte 2 */
+       expamem_write(0x20, p->uaeboard); /* ser.no. Byte 2 */
        expamem_write(0x24, 0x02); /* ser.no. Byte 3 */
 
-       uae_u8 *p = uaeboard_bank.baseaddr;
+       uae_u8 *ptr = uaeboard_bank.baseaddr;
 
        if (rom) {
 
@@ -1274,21 +1263,23 @@ static addrbank* expamem_init_uaeboard(int devnum)
                diagpoint += diagoffset;
                bootpoint += diagoffset;
 
-               if (currprefs.uaeboard > 2) {
-                       /* Call hwtrap_install */
-                       put_word_host(expamem + diagpoint + 0, 0x4EB9); /* JSR */
-                       put_long_host(expamem + diagpoint + 2, filesys_get_entry(9));
-                       diagpoint += 6;
-               }
-               /* Call DiagEntry */
-               put_word_host(expamem + diagpoint + 0, 0x4EF9); /* JMP */
-               put_long_host(expamem + diagpoint + 2, ROM_filesys_diagentry);
+               if (aci->doinit) {
+                       if (p->uaeboard > 2) {
+                               /* Call hwtrap_install */
+                               put_word_host(expamem + diagpoint + 0, 0x4EB9); /* JSR */
+                               put_long_host(expamem + diagpoint + 2, filesys_get_entry(9));
+                               diagpoint += 6;
+                       }
+                       /* Call DiagEntry */
+                       put_word_host(expamem + diagpoint + 0, 0x4EF9); /* JMP */
+                       put_long_host(expamem + diagpoint + 2, ROM_filesys_diagentry);
 
-               /* What comes next is a plain bootblock */
-               put_word_host(expamem + bootpoint + 0, 0x4EF9); /* JMP */
-               put_long_host(expamem + bootpoint + 2, EXPANSION_bootcode);
+                       /* What comes next is a plain bootblock */
+                       put_word_host(expamem + bootpoint + 0, 0x4EF9); /* JMP */
+                       put_long_host(expamem + bootpoint + 2, EXPANSION_bootcode);
 
-               put_long_host(rtarea_bank.baseaddr + RTAREA_FSBOARD, 0xea0000 + 0x2000);
+                       put_long_host(rtarea_bank.baseaddr + RTAREA_FSBOARD, uaeboard_bank.start + 0x2000);
+               }
 
        } else {
 
@@ -1297,33 +1288,43 @@ static addrbank* expamem_init_uaeboard(int devnum)
 
        }
 
-       memcpy(p, expamem, 0x100);
+       memcpy(aci->autoconfig_raw, expamem, sizeof aci->autoconfig_raw);
 
-       return NULL;
+       if (!aci->doinit)
+               return true;
+
+       memcpy(ptr, expamem, 0x100);
+
+       return true;
 }
 
 /*
 *  Z3fastmem Memory
 */
 
-MEMORY_FUNCTIONS(z3fastmem);
-MEMORY_FUNCTIONS(z3fastmem2);
+MEMORY_ARRAY_FUNCTIONS(z3fastmem, 0);
+MEMORY_ARRAY_FUNCTIONS(z3fastmem, 1);
+
 MEMORY_FUNCTIONS(z3chipmem);
 
-addrbank z3fastmem_bank = {
-       z3fastmem_lget, z3fastmem_wget, z3fastmem_bget,
-       z3fastmem_lput, z3fastmem_wput, z3fastmem_bput,
-       z3fastmem_xlate, z3fastmem_check, NULL, _T("z3"), _T("Zorro III Fast RAM"),
-       z3fastmem_lget, z3fastmem_wget,
-       ABFLAG_RAM | ABFLAG_THREADSAFE, 0, 0
-};
-addrbank z3fastmem2_bank = {
-       z3fastmem2_lget, z3fastmem2_wget, z3fastmem2_bget,
-       z3fastmem2_lput, z3fastmem2_wput, z3fastmem2_bput,
-       z3fastmem2_xlate, z3fastmem2_check, NULL, _T("z3_2"), _T("Zorro III Fast RAM #2"),
-       z3fastmem2_lget, z3fastmem2_wget,
-       ABFLAG_RAM | ABFLAG_THREADSAFE, 0, 0
+addrbank z3fastmem_bank[MAX_RAM_BOARDS] =
+{
+       {
+               z3fastmem0_lget, z3fastmem0_wget, z3fastmem0_bget,
+               z3fastmem0_lput, z3fastmem0_wput, z3fastmem0_bput,
+               z3fastmem0_xlate, z3fastmem0_check, NULL, _T("*"), _T("Zorro III Fast RAM"),
+               z3fastmem0_lget, z3fastmem0_wget,
+               ABFLAG_RAM | ABFLAG_THREADSAFE, 0, 0
+       },
+       {
+               z3fastmem1_lget, z3fastmem1_wget, z3fastmem1_bget,
+               z3fastmem1_lput, z3fastmem1_wput, z3fastmem1_bput,
+               z3fastmem1_xlate, z3fastmem1_check, NULL, _T("*"), _T("Zorro III Fast RAM #2"),
+               z3fastmem1_lget, z3fastmem1_wget,
+               ABFLAG_RAM | ABFLAG_THREADSAFE, 0, 0
+       }
 };
+
 addrbank z3chipmem_bank = {
        z3chipmem_lget, z3chipmem_wget, z3chipmem_bget,
        z3chipmem_lput, z3chipmem_wput, z3chipmem_bput,
@@ -1338,10 +1339,12 @@ addrbank z3chipmem_bank = {
 *     Expansion Card (ZORRO II) for 64/128/256/512KB 1/2/4/8MB of Fast Memory
 */
 
-static addrbank *expamem_map_fastcard_2 (int boardnum)
+static addrbank *expamem_map_fastcard(struct autoconfig_info *aci)
 {
        uae_u32 start = ((expamem_hi | (expamem_lo >> 4)) << 16);
-       addrbank *ab = fastbanks[boardnum * 2 + ((start < 0x00A00000) ? 0 : 1)];
+       addrbank *ab = &fastmem_bank[aci->devnum];
+       if (start == 0x00ff0000)
+               return ab;
        uae_u32 size = ab->allocated;
        ab->start = start;
        if (ab->start) {
@@ -1350,77 +1353,102 @@ static addrbank *expamem_map_fastcard_2 (int boardnum)
        return ab;
 }
 
-static void fastmem_autoconfig(int boardnum, int zorro, uae_u8 type, uae_u32 serial, int allocated)
+static void fastmem_autoconfig(struct uae_prefs *p, struct autoconfig_info *aci, int zorro, uae_u8 type, uae_u32 serial, int allocated)
 {
        uae_u16 mid = 0;
        uae_u8 pid;
-       uae_u8 flags = care_addr;
+       uae_u8 flags = 0;
        DEVICE_MEMORY_CALLBACK dmc = NULL;
        struct romconfig *dmc_rc = NULL;
        uae_u8 ac[16] = { 0 };
-
-       if (boardnum == 1) {
-               const struct cpuboardsubtype *cst = &cpuboards[currprefs.cpuboard_type].subtypes[currprefs.cpuboard_subtype];
-               if (cst->memory_mid) {
-                       mid = cst->memory_mid;
-                       pid = cst->memory_pid;
-                       serial = cst->memory_serial;
-               }
-       } else if (boardnum == 0) {
-               for (int i = 0; expansionroms[i].name; i++) {
-                       const struct expansionromtype *erc = &expansionroms[i];
-                       if (((erc->zorro == zorro) || (zorro < 0 && erc->zorro >= BOARD_NONAUTOCONFIG_BEFORE)) && cfgfile_board_enabled(&currprefs, erc->romtype, 0)) {
-                               struct romconfig *rc = get_device_romconfig(&currprefs, erc->romtype, 0);
-                               if (erc->subtypes) {
-                                       const struct expansionsubromtype *srt = &erc->subtypes[rc->subtype];
-                                       if (srt->memory_mid) {
-                                               mid = srt->memory_mid;
-                                               pid = srt->memory_pid;
-                                               serial = srt->memory_serial;
-                                               if (!srt->memory_after)
-                                                       type |= chainedconfig;
-                                       }
-                               } else {
-                                       if (erc->memory_mid) {
-                                               mid = erc->memory_mid;
-                                               pid = erc->memory_pid;
-                                               serial = erc->memory_serial;
-                                               if (!erc->memory_after)
-                                                       type |= chainedconfig;
-                                       }
-                               }
-                               dmc = erc->memory_callback;
-                               dmc_rc = rc;
-                               break;
+       int boardnum = aci->devnum;
+
+       if (aci->cst) {
+               mid = aci->cst->memory_mid;
+               pid = aci->cst->memory_pid;
+               serial = aci->cst->memory_serial;
+       } else if (aci->ert) {
+               const struct expansionromtype *ert = aci->ert;
+               struct romconfig *rc = get_device_romconfig(p, ert->romtype, 0);
+               if (ert->subtypes) {
+                       const struct expansionsubromtype *srt = &ert->subtypes[rc->subtype];
+                       if (srt->memory_mid) {
+                               mid = srt->memory_mid;
+                               pid = srt->memory_pid;
+                               serial = srt->memory_serial;
+                               if (!srt->memory_after)
+                                       type |= chainedconfig;
+                       }
+               } else {
+                       if (ert->memory_mid) {
+                               mid = ert->memory_mid;
+                               pid = ert->memory_pid;
+                               serial = ert->memory_serial;
+                               if (!ert->memory_after)
+                                       type |= chainedconfig;
                        }
                }
+               dmc = ert->memory_callback;
+               dmc_rc = rc;
        }
 
+       uae_u8 *forceac = NULL;
+
        if (!mid) {
                if (zorro <= 2) {
-                       pid = currprefs.maprom && !currprefs.cpuboard_type ? 1 : 81;
+                       struct ramboard *rb = &p->fastmem[boardnum];
+                       if (rb->autoconfig[0]) {
+                               forceac = rb->autoconfig;
+                       } else if (rb->manufacturer) {
+                               mid = rb->manufacturer;
+                               pid = rb->product;
+                               serial = 0;
+                       } else {
+                               pid = p->maprom && !p->cpuboard_type ? 1 : 81;
+                       }
                } else {
                        int subsize = (allocated == 0x100000 ? Z3_SS_MEM_1MB
                                                   : allocated == 0x200000 ? Z3_SS_MEM_2MB
                                                   : allocated == 0x400000 ? Z3_SS_MEM_4MB
                                                   : allocated == 0x800000 ? Z3_SS_MEM_8MB
                                                   : Z3_SS_MEM_SAME);
-                       pid = currprefs.maprom && !currprefs.cpuboard_type ? 3 : 83;
-                       flags |= force_z3 | (allocated > 0x800000 ? ext_size : subsize);
+                       struct ramboard *rb = &p->z3fastmem[boardnum];
+                       if (rb->autoconfig[0]) {
+                               forceac = rb->autoconfig;
+                       } else if (rb->manufacturer) {
+                               mid = rb->manufacturer;
+                               pid = rb->product;
+                               serial = 0;
+                       } else {
+                               pid = p->maprom && !p->cpuboard_type ? 3 : 83;
+                       }
+                       flags |= care_addr | force_z3 | (allocated > 0x800000 ? ext_size : subsize);
                }
+       }
+       if (!mid) {
                mid = uae_id;
                serial = 1;
        }
 
-       ac[0x00 / 4] = type;
-       ac[0x04 / 4] = pid;
-       ac[0x08 / 4] = flags;
-       ac[0x10 / 4] = mid >> 8;
-       ac[0x14 / 4] = (uae_u8)mid;
-       ac[0x18 / 4] = serial >> 24;
-       ac[0x1c / 4] = serial >> 16;
-       ac[0x20 / 4] = serial >> 8;
-       ac[0x24 / 4] = serial >> 0;
+       if (forceac) {
+               for (int i = 0; i < 16; i++) {
+                       ac[i] = forceac[i];
+                       ac[0] &= ~7;
+                       ac[0] |= type;
+                       if (flags)
+                               ac[0x08 / 4] = flags;
+               }
+       } else {
+               ac[0x00 / 4] = type;
+               ac[0x04 / 4] = pid;
+               ac[0x08 / 4] = flags;
+               ac[0x10 / 4] = mid >> 8;
+               ac[0x14 / 4] = (uae_u8)mid;
+               ac[0x18 / 4] = serial >> 24;
+               ac[0x1c / 4] = serial >> 16;
+               ac[0x20 / 4] = serial >> 8;
+               ac[0x24 / 4] = serial >> 0;
+       }
 
        if (dmc && dmc_rc)
                dmc(dmc_rc, ac, allocated);
@@ -1444,68 +1472,66 @@ static void fastmem_autoconfig(int boardnum, int zorro, uae_u8 type, uae_u32 ser
 
 static const uae_u8 a2630_autoconfig[] = { 0xe7, 0x51, 0x40, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
 
-static addrbank *expamem_init_fastcard_2(int boardnum)
+static bool megachipram_init(struct autoconfig_info *aci)
 {
+       aci->addrbank = &expamem_nonautoconfig;
+       aci->start = 0x10000000;
+       aci->size = aci->prefs->z3chipmem_size;
+       aci->label = _T("32-bit Chip RAM");
+       return true;
+}
+
+static bool expamem_init_fastcard(struct autoconfig_info *aci)
+{
+       struct uae_prefs *p = aci->prefs;
+       addrbank *bank = &fastmem_bank[aci->devnum];
        uae_u8 type = add_memory | zorroII;
-       int allocated = boardnum ? fastmem2_bank.allocated : fastmem_bank.allocated;
+       int size = p->fastmem[aci->devnum].size;
 
-       if (allocated == 0)
-               return &expamem_null;
+       aci->label = _T("Z2 Fast RAM");
 
        expamem_init_clear ();
-       if (allocated == 65536)
+       if (size == 65536)
                type |= Z2_MEM_64KB;
-       else if (allocated == 131072)
+       else if (size == 131072)
                type |= Z2_MEM_128KB;
-       else if (allocated == 262144)
+       else if (size == 262144)
                type |= Z2_MEM_256KB;
-       else if (allocated == 524288)
+       else if (size == 524288)
                type |= Z2_MEM_512KB;
-       else if (allocated == 0x100000)
+       else if (size == 0x100000)
                type |= Z2_MEM_1MB;
-       else if (allocated == 0x200000)
+       else if (size == 0x200000)
                type |= Z2_MEM_2MB;
-       else if (allocated == 0x400000)
+       else if (size == 0x400000)
                type |= Z2_MEM_4MB;
-       else if (allocated == 0x800000)
+       else if (size == 0x800000)
                type |= Z2_MEM_8MB;
 
-       if (boardnum == 1) {
-               if (ISCPUBOARD(BOARD_COMMODORE, BOARD_COMMODORE_SUB_A26x0)) {
-                       for (int i = 1; i < 16; i++)
+       aci->addrbank = bank;
+
+       if (aci->devnum == 0) {
+               if (ISCPUBOARDP(p, BOARD_COMMODORE, BOARD_COMMODORE_SUB_A26x0)) {
+                       expamem_write(1 * 4, p->cpu_model <= 68020 ? 0x50 : 0x51);
+                       for (int i = 2; i < 16; i++)
                                expamem_write(i * 4, a2630_autoconfig[i]);
                        type &= 7;
                        type |= a2630_autoconfig[0] & ~7;
                        expamem_write(0, type);
-                       return NULL;
+                       memcpy(aci->autoconfig_raw, expamem, sizeof aci->autoconfig_raw);
+                       return true;
                }
        }
 
-       fastmem_autoconfig(boardnum, BOARD_AUTOCONFIG_Z2, type, 1, allocated);
-
-       return NULL;
-}
+       fastmem_autoconfig(p, aci, BOARD_AUTOCONFIG_Z2, type, 1, size);
 
-static addrbank *expamem_init_fastcard(int boardnum)
-{
-       return expamem_init_fastcard_2(0);
-}
-static addrbank *expamem_init_fastcard2(int boardnum)
-{
-       return expamem_init_fastcard_2(1);
-}
-static addrbank *expamem_map_fastcard (void)
-{
-       return expamem_map_fastcard_2 (0);
-}
-static addrbank *expamem_map_fastcard2 (void)
-{
-       return expamem_map_fastcard_2 (1);
+       memcpy(aci->autoconfig_raw, expamem, sizeof aci->autoconfig_raw);
+       return true;
 }
 
 bool expansion_is_next_board_fastram(void)
 {
-       return ecard + 1 < MAX_EXPANSION_BOARD_SPACE && cards[ecard + 1].map == expamem_map_fastcard;
+       return ecard + 1 < MAX_EXPANSION_BOARD_SPACE && cards[ecard + 1] && cards[ecard + 1]->map == expamem_map_fastcard;
 }
 
 /* ********************************************************** */
@@ -1525,7 +1551,7 @@ static void expamem_map_filesys_update(void)
        org(a);
 }
 
-static addrbank *expamem_map_filesys (void)
+static addrbank *expamem_map_filesys (struct autoconfig_info *aci)
 {
        // Warn if PPC doing autoconfig and UAE expansion enabled
        static bool warned;
@@ -1536,7 +1562,7 @@ static addrbank *expamem_map_filesys (void)
        }
 
        uaeboard_ram_start = UAEBOARD_WRITEOFFSET;
-       filesys_start = expamem_z2_pointer;
+       filesys_start = expamem_board_pointer;
        map_banks_z2(&filesys_bank, filesys_start >> 16, 1);
        expamem_map_filesys_update();
        return &filesys_bank;
@@ -1576,11 +1602,15 @@ static void add_ks12_boot_hack(void)
 }
 #endif
 
-static addrbank* expamem_init_filesys (int devnum)
+static bool expamem_init_filesys(struct autoconfig_info *aci)
 {
        bool ks12 = ks12orolder();
        bool hide = currprefs.uae_hide_autoconfig;
 
+       aci->label = _T("UAE Boot ROM");
+       aci->get_params = get_params_filesys;
+       aci->set_params = set_params_filesys;
+
 #if 0
        FILE *f = fopen("d:\\amiga\\amiga\\source\\acap\\autoconf", "rb");
        fread(expamem, 1, 256, f);
@@ -1601,7 +1631,7 @@ static addrbank* expamem_init_filesys (int devnum)
        };
 
        expamem_init_clear ();
-       expamem_write (0x00, Z2_MEM_64KB | zorroII | (ks12 ? 0 : rom_card));
+       expamem_write (0x00, Z2_MEM_64KB | zorroII | (ks12 || !do_mount ? 0 : rom_card));
 
        expamem_write (0x08, no_shutup);
 
@@ -1620,6 +1650,11 @@ static addrbank* expamem_init_filesys (int devnum)
 
        expamem_write (0x40, 0x00); /* Ctrl/Statusreg.*/
 
+       if (!aci->doinit) {
+               memcpy(aci->autoconfig_raw, expamem, sizeof aci->autoconfig_raw);
+               return true;
+       }
+
        /* Build a DiagArea */
        memcpy (expamem + FILESYS_DIAGAREA, diagarea, sizeof diagarea);
 
@@ -1635,7 +1670,7 @@ static addrbank* expamem_init_filesys (int devnum)
                add_ks12_boot_hack();
 
        memcpy (filesys_bank.baseaddr, expamem, 0x3000);
-       return NULL;
+       return true;
 }
 
 #endif
@@ -1644,64 +1679,69 @@ static addrbank* expamem_init_filesys (int devnum)
 * Zorro III expansion memory
 */
 
-static addrbank * expamem_map_z3fastmem_2 (addrbank *bank, uaecptr *startp, uae_u32 size, uae_u32 allocated, int chip)
+static addrbank * expamem_map_z3fastmem (struct autoconfig_info *aci)
 {
-       int z3fs = expamem_z3_pointer;
+       int devnum = aci->devnum;
+       addrbank *ab = &z3fastmem_bank[devnum];
+       int z3fs = expamem_board_pointer;
+       uaecptr *startp = &ab->start;
        int start = *startp;
+       uae_u32 allocated = ab->allocated;
+       uae_u32 size = currprefs.z3fastmem[devnum].size;
 
        if (expamem_z3hack(&currprefs)) {
                if (z3fs && start != z3fs) {
                        write_log (_T("WARNING: Z3MEM mapping changed from $%08x to $%08x\n"), start, z3fs);
                        map_banks(&dummy_bank, start >> 16, size >> 16, allocated);
                        *startp = z3fs;
-                       map_banks_z3(bank, start >> 16, size >> 16);
+                       map_banks_z3(ab, start >> 16, size >> 16);
                }
        } else {
-               map_banks_z3(bank, z3fs >> 16, size >> 16);
+               map_banks_z3(ab, z3fs >> 16, size >> 16);
                start = z3fs;
                *startp = z3fs;
        }
-       return bank;
-}
-
-static addrbank *expamem_map_z3fastmem (void)
-{
-       return expamem_map_z3fastmem_2 (&z3fastmem_bank, &z3fastmem_bank.start, currprefs.z3fastmem_size, z3fastmem_bank.allocated, 0);
-}
-static addrbank *expamem_map_z3fastmem2 (void)
-{
-       return expamem_map_z3fastmem_2 (&z3fastmem2_bank, &z3fastmem2_bank.start, currprefs.z3fastmem2_size, z3fastmem2_bank.allocated, 0);
+       return ab;
 }
 
-static addrbank *expamem_init_z3fastmem_2(int boardnum, addrbank *bank, uae_u32 start, uae_u32 size, uae_u32 allocated)
+static bool expamem_init_z3fastmem(struct autoconfig_info *aci)
 {
-       int code = (allocated == 0x100000 ? Z2_MEM_1MB
-               : allocated == 0x200000 ? Z2_MEM_2MB
-               : allocated == 0x400000 ? Z2_MEM_4MB
-               : allocated == 0x800000 ? Z2_MEM_8MB
-               : allocated == 0x1000000 ? Z3_MEM_16MB
-               : allocated == 0x2000000 ? Z3_MEM_32MB
-               : allocated == 0x4000000 ? Z3_MEM_64MB
-               : allocated == 0x8000000 ? Z3_MEM_128MB
-               : allocated == 0x10000000 ? Z3_MEM_256MB
-               : allocated == 0x20000000 ? Z3_MEM_512MB
+       addrbank *bank = &z3fastmem_bank[aci->devnum];
+       
+       uae_u32 size = aci->prefs->z3fastmem[aci->devnum].size;
+
+       aci->label = _T("Z3 Fast RAM");
+
+       int code = (size == 0x100000 ? Z2_MEM_1MB
+               : size == 0x200000 ? Z2_MEM_2MB
+               : size == 0x400000 ? Z2_MEM_4MB
+               : size == 0x800000 ? Z2_MEM_8MB
+               : size == 0x1000000 ? Z3_MEM_16MB
+               : size == 0x2000000 ? Z3_MEM_32MB
+               : size == 0x4000000 ? Z3_MEM_64MB
+               : size == 0x8000000 ? Z3_MEM_128MB
+               : size == 0x10000000 ? Z3_MEM_256MB
+               : size == 0x20000000 ? Z3_MEM_512MB
                : Z3_MEM_1GB);
 
-       if (allocated < 0x1000000)
+       if (size < 0x1000000)
                code = Z3_MEM_16MB; /* Z3 physical board size is always at least 16M */
 
        expamem_init_clear ();
-       fastmem_autoconfig(boardnum, BOARD_AUTOCONFIG_Z3, add_memory | zorroIII | code, 1, allocated);
-       map_banks_z3(bank, start >> 16, size >> 16);
-       return NULL;
-}
-static addrbank *expamem_init_z3fastmem (int devnum)
-{
-       return expamem_init_z3fastmem_2 (0, &z3fastmem_bank, z3fastmem_bank.start, currprefs.z3fastmem_size, z3fastmem_bank.allocated);
-}
-static addrbank *expamem_init_z3fastmem2(int devnum)
-{
-       return expamem_init_z3fastmem_2 (1, &z3fastmem2_bank, z3fastmem2_bank.start, currprefs.z3fastmem2_size, z3fastmem2_bank.allocated);
+       fastmem_autoconfig(aci->prefs, aci, BOARD_AUTOCONFIG_Z3, add_memory | zorroIII | code, 1, size);
+
+       memcpy(aci->autoconfig_raw, expamem, sizeof aci->autoconfig_raw);
+       aci->addrbank = bank;
+
+       if (!aci->doinit)
+               return true;
+
+       uae_u32 start = bank->start;
+       bool alwaysmapz3 = aci->prefs->z3_mapping_mode != Z3MAPPING_REAL;
+       if (alwaysmapz3 || expamem_z3hack(aci->prefs)) {
+               map_banks_z3(bank, start >> 16, size >> 16);
+       }
+       return true;
 }
 
 #ifdef PICASSO96
@@ -1709,46 +1749,53 @@ static addrbank *expamem_init_z3fastmem2(int devnum)
 *  Fake Graphics Card (ZORRO III) - BDK
 */
 
-static addrbank *expamem_map_gfxcard_z3 (void)
+static addrbank *expamem_map_gfxcard_z3 (struct autoconfig_info *aci)
 {
-       gfxmem_bank.start = expamem_z3_pointer;
-       map_banks_z3(&gfxmem_bank, gfxmem_bank.start >> 16, gfxmem_bank.allocated >> 16);
-       return &gfxmem_bank;
+       int devnum = aci->devnum;
+       gfxmem_banks[devnum]->start = expamem_board_pointer;
+       map_banks_z3(gfxmem_banks[devnum], gfxmem_banks[devnum]->start >> 16, gfxmem_banks[devnum]->allocated >> 16);
+       return gfxmem_banks[devnum];
 }
 
-static addrbank *expamem_map_gfxcard_z2 (void)
+static addrbank *expamem_map_gfxcard_z2 (struct autoconfig_info *aci)
 {
-       gfxmem_bank.start = expamem_z2_pointer;
-       map_banks_z2(&gfxmem_bank, gfxmem_bank.start >> 16, gfxmem_bank.allocated >> 16);
-       return &gfxmem_bank;
+       int devnum = aci->devnum;
+       gfxmem_banks[devnum]->start = expamem_board_pointer;
+       map_banks_z2(gfxmem_banks[devnum], gfxmem_banks[devnum]->start >> 16, gfxmem_banks[devnum]->allocated >> 16);
+       return gfxmem_banks[devnum];
 }
 
-static addrbank *expamem_init_gfxcard (bool z3)
+static bool expamem_init_gfxcard (struct autoconfig_info *aci, bool z3)
 {
-       int code = (gfxmem_bank.allocated == 0x100000 ? Z2_MEM_1MB
-               : gfxmem_bank.allocated == 0x200000 ? Z2_MEM_2MB
-               : gfxmem_bank.allocated == 0x400000 ? Z2_MEM_4MB
-               : gfxmem_bank.allocated == 0x800000 ? Z2_MEM_8MB
-               : gfxmem_bank.allocated == 0x1000000 ? Z3_MEM_16MB
-               : gfxmem_bank.allocated == 0x2000000 ? Z3_MEM_32MB
-               : gfxmem_bank.allocated == 0x4000000 ? Z3_MEM_64MB
-               : gfxmem_bank.allocated == 0x8000000 ? Z3_MEM_128MB
-               : gfxmem_bank.allocated == 0x10000000 ? Z3_MEM_256MB
-               : gfxmem_bank.allocated == 0x20000000 ? Z3_MEM_512MB
+       int devnum = aci->devnum;
+       struct uae_prefs *p = aci->prefs;
+       int size = p->rtgboards[devnum].rtgmem_size;
+       int code = (size == 0x100000 ? Z2_MEM_1MB
+               : size == 0x200000 ? Z2_MEM_2MB
+               : size == 0x400000 ? Z2_MEM_4MB
+               : size == 0x800000 ? Z2_MEM_8MB
+               : size == 0x1000000 ? Z3_MEM_16MB
+               : size == 0x2000000 ? Z3_MEM_32MB
+               : size == 0x4000000 ? Z3_MEM_64MB
+               : size == 0x8000000 ? Z3_MEM_128MB
+               : size == 0x10000000 ? Z3_MEM_256MB
+               : size == 0x20000000 ? Z3_MEM_512MB
                : Z3_MEM_1GB);
-       int subsize = (gfxmem_bank.allocated == 0x100000 ? Z3_SS_MEM_1MB
-               : gfxmem_bank.allocated == 0x200000 ? Z3_SS_MEM_2MB
-               : gfxmem_bank.allocated == 0x400000 ? Z3_SS_MEM_4MB
-               : gfxmem_bank.allocated == 0x800000 ? Z3_SS_MEM_8MB
+       int subsize = (size == 0x100000 ? Z3_SS_MEM_1MB
+               : size == 0x200000 ? Z3_SS_MEM_2MB
+               : size == 0x400000 ? Z3_SS_MEM_4MB
+               : size == 0x800000 ? Z3_SS_MEM_8MB
                : Z3_SS_MEM_SAME);
 
-       if (gfxmem_bank.allocated < 0x1000000 && z3)
+       aci->label = _T("UAE RTG");
+
+       if (size < 0x1000000 && z3)
                code = Z3_MEM_16MB; /* Z3 physical board size is always at least 16M */
 
        expamem_init_clear ();
        expamem_write (0x00, (z3 ? zorroIII : zorroII) | code);
 
-       expamem_write (0x08, care_addr | (z3 ? (force_z3 | (gfxmem_bank.allocated > 0x800000 ? ext_size: subsize)) : 0));
+       expamem_write (0x08, care_addr | (z3 ? (force_z3 | (size > 0x800000 ? ext_size: subsize)) : 0));
        expamem_write (0x04, 96);
 
        expamem_write (0x10, uae_id >> 8);
@@ -1763,33 +1810,33 @@ static addrbank *expamem_init_gfxcard (bool z3)
        expamem_write (0x2c, 0x00); /* ROM-Offset lo */
 
        expamem_write (0x40, 0x00); /* Ctrl/Statusreg.*/
-       return NULL;
+
+       memcpy(aci->autoconfig_raw, expamem, sizeof aci->autoconfig_raw);
+       aci->addrbank = gfxmem_banks[devnum];
+       return true;
 }
-static addrbank *expamem_init_gfxcard_z3(int devnum)
+static bool expamem_init_gfxcard_z3(struct autoconfig_info *aci)
 {
-       return expamem_init_gfxcard (true);
+       return expamem_init_gfxcard (aci, true);
 }
-static addrbank *expamem_init_gfxcard_z2 (int devnum)
+static bool expamem_init_gfxcard_z2 (struct autoconfig_info *aci)
 {
-       return expamem_init_gfxcard (false);
+       return expamem_init_gfxcard (aci, false);
 }
 #endif
 
 
 #ifdef SAVESTATE
-static size_t fast_filepos, fast2_filepos, z3_filepos, z3_filepos2, z3_fileposchip, p96_filepos;
+static size_t fast_filepos[MAX_RAM_BOARDS], z3_filepos[MAX_RAM_BOARDS];
+static size_t z3_fileposchip, p96_filepos;
 #endif
 
 void free_fastmemory (int boardnum)
 {
-       if (!boardnum) {
-               mapped_free (&fastmem_bank);
-       } else {
-               mapped_free (&fastmem2_bank);
-       }
+       mapped_free (&fastmem_bank[boardnum]);
 }
 
-static bool mapped_malloc_dynamic (uae_u32 *currpsize, uae_u32 *changedpsize, addrbank *bank, int max, const TCHAR *name)
+static bool mapped_malloc_dynamic (uae_u32 *currpsize, uae_u32 *changedpsize, addrbank *bank, int max, const TCHAR *label)
 {
        int alloc = *currpsize;
 
@@ -1800,128 +1847,115 @@ static bool mapped_malloc_dynamic (uae_u32 *currpsize, uae_u32 *changedpsize, ad
        if (!alloc)
                return false;
 
-       while (alloc >= max * 1024 * 1024) {
-               bank->mask = alloc - 1;
-               bank->allocated = alloc;
-               bank->label = name;
-               if (mapped_malloc (bank)) {
-                       *currpsize = alloc;
-                       *changedpsize = alloc;
-                       return true;
-               }
-               write_log (_T("Out of memory for %s, %d bytes.\n"), name, alloc);
-               alloc /= 2;
+       bank->mask = alloc - 1;
+       bank->allocated = alloc;
+       bank->label = label ? label : _T("*");
+       if (mapped_malloc (bank)) {
+               *currpsize = alloc;
+               *changedpsize = alloc;
+               return true;
        }
+       write_log (_T("Out of memory for %s, %d bytes.\n"), label ? label : _T("?"), alloc);
 
        return false;
 }
 
-uaecptr expansion_startaddress(uaecptr addr, uae_u32 size)
+uaecptr expansion_startaddress(struct uae_prefs *p, uaecptr addr, uae_u32 size)
 {
        if (!size)
                return addr;
-       if (size < 16 * 1024 * 1024)
-               size = 16 * 1024 * 1024;
-       if (!expamem_z3hack(&currprefs))
+       if (addr < 0x10000000) {
                return (addr + size - 1) & ~(size - 1);
+       } else {
+               if (size < 16 * 1024 * 1024)
+                       size = 16 * 1024 * 1024;
+               if (!expamem_z3hack(p))
+                       return (addr + size - 1) & ~(size - 1);
+       }
        return addr;
 }
 
 static void allocate_expamem (void)
 {
-       currprefs.fastmem_size = changed_prefs.fastmem_size;
-       currprefs.fastmem2_size = changed_prefs.fastmem2_size;
-       currprefs.z3fastmem_size = changed_prefs.z3fastmem_size;
-       currprefs.z3fastmem2_size = changed_prefs.z3fastmem2_size;
        for (int i = 0; i < MAX_RTG_BOARDS; i++) {
                memcpy(&currprefs.rtgboards[i], &changed_prefs.rtgboards[i], sizeof(struct rtgboardconfig));
        }
        currprefs.z3chipmem_size = changed_prefs.z3chipmem_size;
 
+       for (int i = 0; i < MAX_RAM_BOARDS; i++) {
+               currprefs.fastmem[i].size = changed_prefs.fastmem[i].size;
+               currprefs.z3fastmem[i].size = changed_prefs.z3fastmem[i].size;
+       }
+
        z3chipmem_bank.start = Z3BASE_UAE;
-       z3fastmem_bank.start = currprefs.z3autoconfig_start;
+
+       z3fastmem_bank[0].start = currprefs.z3autoconfig_start;
        if (currprefs.mbresmem_high_size >= 128 * 1024 * 1024)
                z3chipmem_bank.start += (currprefs.mbresmem_high_size - 128 * 1024 * 1024) + 16 * 1024 * 1024;
        if (!expamem_z3hack(&currprefs))
-               z3fastmem_bank.start = Z3BASE_REAL;
-       if (z3fastmem_bank.start == Z3BASE_REAL) {
+               z3fastmem_bank[0].start = Z3BASE_REAL;
+       if (z3fastmem_bank[0].start == Z3BASE_REAL) {
                int z3off = cpuboards[currprefs.cpuboard_type].subtypes[currprefs.cpuboard_subtype].z3extra;
                if (z3off) {
-                       z3fastmem_bank.start += z3off;
-                       z3fastmem_bank.start = expansion_startaddress(z3fastmem_bank.start, currprefs.z3fastmem_size);
+                       z3fastmem_bank[0].start += z3off;
+                       z3fastmem_bank[0].start = expansion_startaddress(&currprefs, z3fastmem_bank[0].start, currprefs.z3fastmem[0].size);
                }
        }
-       if (z3fastmem_bank.start == Z3BASE_UAE) {
+       if (z3fastmem_bank[0].start == Z3BASE_UAE) {
                if (currprefs.mbresmem_high_size >= 128 * 1024 * 1024)
-                       z3fastmem_bank.start += (currprefs.mbresmem_high_size - 128 * 1024 * 1024) + 16 * 1024 * 1024;
-               z3fastmem_bank.start += currprefs.z3chipmem_size;
+                       z3fastmem_bank[0].start += (currprefs.mbresmem_high_size - 128 * 1024 * 1024) + 16 * 1024 * 1024;
+               z3fastmem_bank[0].start += currprefs.z3chipmem_size;
        }
-       z3fastmem2_bank.start = z3fastmem_bank.start + currprefs.z3fastmem_size;
 
-       if (currprefs.z3chipmem_size && z3fastmem_bank.start - z3chipmem_bank.start < currprefs.z3chipmem_size)
+       if (currprefs.z3chipmem_size && z3fastmem_bank[0].start - z3chipmem_bank.start < currprefs.z3chipmem_size)
                currprefs.z3chipmem_size = changed_prefs.z3chipmem_size = 0;    
 
-       if (fastmem_bank.allocated != currprefs.fastmem_size) {
-               free_fastmemory (0);
-
-               fastmem_bank.allocated = currprefs.fastmem_size;
-               fastmem_bank.mask = fastmem_bank.allocated - 1;
-
-               fastmem_nojit_bank.allocated = fastmem_bank.allocated;
-               fastmem_nojit_bank.mask = fastmem_bank.mask;
-
-               if (fastmem_bank.allocated) {
-                       mapped_malloc (&fastmem_bank);
-                       fastmem_nojit_bank.baseaddr = fastmem_bank.baseaddr;
-                       if (fastmem_bank.baseaddr == 0) {
-                               write_log (_T("Out of memory for fastmem card.\n"));
-                               fastmem_bank.allocated = 0;
-                               fastmem_nojit_bank.allocated = 0;
-                       }
-               }
-               memory_hardreset (1);
-       }
-
-       if (fastmem2_bank.allocated != currprefs.fastmem2_size) {
-               free_fastmemory (1);
-
-               fastmem2_bank.allocated = currprefs.fastmem2_size;
-               fastmem2_bank.mask = fastmem2_bank.allocated - 1;
-
-               fastmem2_nojit_bank.allocated = fastmem2_bank.allocated;
-               fastmem2_nojit_bank.mask = fastmem2_bank.mask;
+       for (int i = 0; i < MAX_RAM_BOARDS; i++) {
+               if (fastmem_bank[i].allocated != currprefs.fastmem[i].size) {
+                       free_fastmemory(i);
 
-               if (fastmem2_bank.allocated) {
-                       mapped_malloc (&fastmem2_bank);
-                       fastmem2_nojit_bank.baseaddr = fastmem2_bank.baseaddr;
-                       if (fastmem2_bank.baseaddr == 0) {
-                               write_log (_T("Out of memory for fastmem2 card.\n"));
-                               fastmem2_bank.allocated = 0;
-                               fastmem2_nojit_bank.allocated = 0;
+                       if (fastmem_bank[i].start == 0xffffffff) {
+                               fastmem_bank[i].allocated = 0;
+                       } else {
+                               fastmem_bank[i].allocated = currprefs.fastmem[i].size;
+                               fastmem_bank[i].mask = fastmem_bank[i].allocated - 1;
+
+                               if (fastmem_bank[i].allocated && fastmem_bank[i].start != 0xffffffff) {
+                                       mapped_malloc (&fastmem_bank[i]);
+                                       if (fastmem_bank[i].baseaddr == 0) {
+                                               write_log (_T("Out of memory for fastmem card.\n"));
+                                               fastmem_bank[i].allocated = 0;
+                                       }
+                               }
                        }
+                       memory_hardreset (1);
                }
-               memory_hardreset (1);
        }
 
-       if (z3fastmem_bank.allocated != currprefs.z3fastmem_size) {
-               mapped_free (&z3fastmem_bank);
-               mapped_malloc_dynamic (&currprefs.z3fastmem_size, &changed_prefs.z3fastmem_size, &z3fastmem_bank, 1, _T("z3"));
-               memory_hardreset (1);
+       if (z3fastmem_bank[0].allocated != currprefs.z3fastmem[0].size) {
+               mapped_free(&z3fastmem_bank[0]);
+               mapped_malloc_dynamic(&currprefs.z3fastmem[0].size, &changed_prefs.z3fastmem[0].size, &z3fastmem_bank[0], 1, _T("*"));
+               memory_hardreset(1);
        }
-       if (z3fastmem2_bank.allocated != currprefs.z3fastmem2_size) {
-               mapped_free (&z3fastmem2_bank);
+       for (int i = 1; i < MAX_RAM_BOARDS; i++) {
+               if (currprefs.z3fastmem[i].size) {
+                       z3fastmem_bank[i].start = expansion_startaddress(&currprefs, z3fastmem_bank[i - 1].start, currprefs.z3fastmem[i - 1].size);
+               }
+               if (z3fastmem_bank[i].allocated != currprefs.z3fastmem[i].size) {
+                       mapped_free (&z3fastmem_bank[i]);
 
-               z3fastmem2_bank.allocated = currprefs.z3fastmem2_size;
-               z3fastmem2_bank.mask = z3fastmem2_bank.allocated - 1;
+                       z3fastmem_bank[i].allocated = currprefs.z3fastmem[i].size;
+                       z3fastmem_bank[i].mask = z3fastmem_bank[i].allocated - 1;
 
-               if (z3fastmem2_bank.allocated) {
-                       mapped_malloc (&z3fastmem2_bank);
-                       if (z3fastmem2_bank.baseaddr == 0) {
-                               write_log (_T("Out of memory for 32 bit fast memory #2.\n"));
-                               z3fastmem2_bank.allocated = 0;
+                       if (z3fastmem_bank[i].allocated) {
+                               mapped_malloc(&z3fastmem_bank[i]);
+                               if (z3fastmem_bank[i].baseaddr == 0) {
+                                       write_log (_T("Out of memory for 32 bit fast memory #%d.\n"), i);
+                                       z3fastmem_bank[i].allocated = 0;
+                               }
                        }
+                       memory_hardreset (1);
                }
-               memory_hardreset (1);
        }
        if (z3chipmem_bank.allocated != currprefs.z3chipmem_size) {
                mapped_free (&z3chipmem_bank);
@@ -1931,39 +1965,31 @@ static void allocate_expamem (void)
 
 #ifdef PICASSO96
        struct rtgboardconfig *rbc = &currprefs.rtgboards[0];
-       if (gfxmem_bank.allocated != rbc->rtgmem_size) {
-               mapped_free (&gfxmem_bank);
+       if (gfxmem_banks[0]->allocated != rbc->rtgmem_size) {
+               mapped_free (gfxmem_banks[0]);
                if (rbc->rtgmem_type < GFXBOARD_HARDWARE)
-                       mapped_malloc_dynamic (&rbc->rtgmem_size, &changed_prefs.rtgboards[0].rtgmem_size, &gfxmem_bank, 1, rbc->rtgmem_type ? _T("z3_gfx") : _T("z2_gfx"));
+                       mapped_malloc_dynamic (&rbc->rtgmem_size, &changed_prefs.rtgboards[0].rtgmem_size, gfxmem_banks[0], 1, NULL);
                memory_hardreset (1);
        }
 #endif
 
 #ifdef SAVESTATE
        if (savestate_state == STATE_RESTORE) {
-               if (fastmem_bank.allocated > 0) {
-                       restore_ram (fast_filepos, fastmem_bank.baseaddr);
-                       if (!fastmem_bank.start) {
-                               // old statefile compatibility support
-                               fastmem_bank.start = 0x00200000;
+               for (int i = 0; i < MAX_RAM_BOARDS; i++) {
+                       if (fastmem_bank[i].allocated > 0) {
+                               restore_ram (fast_filepos[i], fastmem_bank[i].baseaddr);
+                               if (!fastmem_bank[i].start) {
+                                       // old statefile compatibility support
+                                       fastmem_bank[i].start = 0x00200000;
+                               }
+                               map_banks(&fastmem_bank[i], fastmem_bank[i].start >> 16, currprefs.fastmem[i].size >> 16,
+                                               fastmem_bank[i].allocated);
+                       }
+                       if (z3fastmem_bank[i].allocated > 0) {
+                               restore_ram (z3_filepos[i], z3fastmem_bank[i].baseaddr);
+                               map_banks(&z3fastmem_bank[i], z3fastmem_bank[i].start >> 16, currprefs.z3fastmem[i].size >> 16,
+                                       z3fastmem_bank[i].allocated);
                        }
-                       map_banks(&fastmem_bank, fastmem_bank.start >> 16, currprefs.fastmem_size >> 16,
-                                       fastmem_bank.allocated);
-               }
-               if (fastmem2_bank.allocated > 0) {
-                       restore_ram (fast2_filepos, fastmem2_bank.baseaddr);
-                       map_banks(&fastmem2_bank, fastmem2_bank.start >> 16, currprefs.fastmem2_size >> 16,
-                               fastmem2_bank.allocated);
-               }
-               if (z3fastmem_bank.allocated > 0) {
-                       restore_ram (z3_filepos, z3fastmem_bank.baseaddr);
-                       map_banks(&z3fastmem_bank, z3fastmem_bank.start >> 16, currprefs.z3fastmem_size >> 16,
-                               z3fastmem_bank.allocated);
-               }
-               if (z3fastmem2_bank.allocated > 0) {
-                       restore_ram (z3_filepos2, z3fastmem2_bank.baseaddr);
-                       map_banks(&z3fastmem2_bank, z3fastmem2_bank.start >> 16, currprefs.z3fastmem2_size >> 16,
-                               z3fastmem2_bank.allocated);
                }
                if (z3chipmem_bank.allocated > 0) {
                        restore_ram (z3_fileposchip, z3chipmem_bank.baseaddr);
@@ -1971,35 +1997,35 @@ static void allocate_expamem (void)
                                z3chipmem_bank.allocated);
                }
 #ifdef PICASSO96
-               if (gfxmem_bank.allocated > 0 && gfxmem_bank.start > 0) {
-                       restore_ram (p96_filepos, gfxmem_bank.baseaddr);
-                       map_banks(&gfxmem_bank, gfxmem_bank.start >> 16, currprefs.rtgboards[0].rtgmem_size >> 16,
-                               gfxmem_bank.allocated);
+               if (gfxmem_banks[0]->allocated > 0 && gfxmem_banks[0]->start > 0) {
+                       restore_ram (p96_filepos, gfxmem_banks[0]->baseaddr);
+                       map_banks(gfxmem_banks[0], gfxmem_banks[0]->start >> 16, currprefs.rtgboards[0].rtgmem_size >> 16,
+                               gfxmem_banks[0]->allocated);
                }
 #endif
        }
 #endif /* SAVESTATE */
 }
 
-static uaecptr check_boot_rom (int *boot_rom_type)
+static uaecptr check_boot_rom (struct uae_prefs *p, int *boot_rom_type)
 {
        uaecptr b = RTAREA_DEFAULT;
        addrbank *ab;
 
-       if (currprefs.uaeboard > 1) {
+       if (p->uaeboard > 1) {
                *boot_rom_type = 2;
-               return 0x00eb0000; // FIXME!
+               return uaeboard_bank.start ? uaeboard_bank.start + 0x10000 : 0x00eb0000;
        }
        *boot_rom_type = 0;
-       if (currprefs.boot_rom == 1)
+       if (p->boot_rom == 1)
                return 0;
        *boot_rom_type = 1;
-       if (currprefs.cs_cdtvcd || currprefs.cs_cdtvscsi || currprefs.uae_hide > 1)
+       if (p->cs_cdtvcd || is_device_rom(p, ROMTYPE_CDTVSCSI, 0) >= 0 || p->uae_hide > 1)
                b = RTAREA_BACKUP;
-       if (currprefs.cs_mbdmac == 1 || currprefs.cpuboard_type)
+       if (p->cs_mbdmac == 1 || p->cpuboard_type)
                b = RTAREA_BACKUP;
        // CSPPC enables MMU at boot and remaps 0xea0000->0xeffff.
-       if (ISCPUBOARD(BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_PPC))
+       if (ISCPUBOARDP(p, BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_PPC))
                b = RTAREA_BACKUP_2;
        ab = &get_mem_bank (RTAREA_DEFAULT);
        if (ab) {
@@ -2008,29 +2034,29 @@ static uaecptr check_boot_rom (int *boot_rom_type)
        }
        if (nr_directory_units (NULL))
                return b;
-       if (nr_directory_units (&currprefs))
+       if (nr_directory_units (p))
                return b;
-       if (currprefs.socket_emu)
+       if (p->socket_emu)
                return b;
-       if (currprefs.uaeserial)
+       if (p->uaeserial)
                return b;
-       if (currprefs.scsi == 1)
+       if (p->scsi == 1)
                return b;
-       if (currprefs.sana2)
+       if (p->sana2)
                return b;
-       if (currprefs.input_tablet > 0)
+       if (p->input_tablet > 0)
                return b;
-       if (currprefs.rtgboards[0].rtgmem_size && currprefs.rtgboards[0].rtgmem_type < GFXBOARD_HARDWARE)
+       if (p->rtgboards[0].rtgmem_size && p->rtgboards[0].rtgmem_type < GFXBOARD_HARDWARE)
                return b;
-       if (currprefs.win32_automount_removable)
+       if (p->win32_automount_removable)
                return b;
-       if (currprefs.chipmem_size > 2 * 1024 * 1024)
+       if (p->chipmem_size > 2 * 1024 * 1024)
                return b;
-       if (currprefs.z3chipmem_size)
+       if (p->z3chipmem_size)
                return b;
-       if (currprefs.boot_rom >= 3)
+       if (p->boot_rom >= 3)
                return b;
-       if (currprefs.boot_rom == 2 && b == 0xf00000) {
+       if (p->boot_rom == 2 && b == 0xf00000) {
                *boot_rom_type = -1;
                return b;
        }
@@ -2038,12 +2064,12 @@ static uaecptr check_boot_rom (int *boot_rom_type)
        return 0;
 }
 
-uaecptr need_uae_boot_rom (void)
+uaecptr need_uae_boot_rom (struct uae_prefs *p)
 {
        uaecptr v;
 
        uae_boot_rom_type = 0;
-       v = check_boot_rom (&uae_boot_rom_type);
+       v = check_boot_rom (p, &uae_boot_rom_type);
        if (!rtarea_base) {
                uae_boot_rom_type = 0;
                v = 0;
@@ -2051,324 +2077,1167 @@ uaecptr need_uae_boot_rom (void)
        return v;
 }
 
-static void add_cpu_expansions(int zorro)
+static void add_cpu_expansions(struct uae_prefs *p, int zorro, int *fastmem_nump)
 {
-       const struct cpuboardsubtype *cst = &cpuboards[currprefs.cpuboard_type].subtypes[currprefs.cpuboard_subtype];
+       int fastmem_num = MAX_RAM_BOARDS;
+       if (fastmem_nump)
+               fastmem_num = *fastmem_nump;
+
+       const struct cpuboardsubtype *cst = &cpuboards[p->cpuboard_type].subtypes[p->cpuboard_subtype];
        if (cst->init && cst->initzorro == zorro) {
                int idx;
-               struct boardromconfig *brc = get_device_rom(&currprefs, ROMTYPE_CPUBOARD, 0, &idx);
+               struct boardromconfig *brc = get_device_rom(p, ROMTYPE_CPUBOARD, 0, &idx);
                struct romconfig *rc = &brc->roms[idx];
-               cards[cardno].flags = cst->initflag;
-               cards[cardno].name = cst->name;
-               cards[cardno].initrc = cst->init;
-               cards[cardno].rc = rc;
-               cards[cardno].zorro = zorro;
-               cards[cardno++].map = NULL;
+               cards_set[cardno].flags = cst->initflag;
+               cards_set[cardno].name = cst->name;
+               cards_set[cardno].initrc = cst->init;
+               cards_set[cardno].rc = rc;
+               cards_set[cardno].zorro = zorro;
+               cards_set[cardno].cst = cst;
+               cards_set[cardno++].map = NULL;
                if (cst->init2) {
-                       cards[cardno].flags = cst->initflag;
-                       cards[cardno].name = cst->name;
-                       cards[cardno].initrc = cst->init2;
-                       cards[cardno].zorro = zorro;
-                       cards[cardno++].map = NULL;
+                       cards_set[cardno].flags = cst->initflag | CARD_FLAG_CHILD;
+                       cards_set[cardno].name = cst->name;
+                       cards_set[cardno].initrc = cst->init2;
+                       cards_set[cardno].zorro = zorro;
+                       cards_set[cardno].cst = cst;
+                       cards_set[cardno++].map = NULL;
                }
-       }
-}
-
-static bool add_fastram_after_expansion(int zorro)
-{
-       for (int i = 0; expansionroms[i].name; i++) {
-               const struct expansionromtype *ert = &expansionroms[i];
-               if (ert->zorro == zorro) {
-                       for (int j = 0; j < MAX_DUPLICATE_EXPANSION_BOARDS; j++) {
-                               struct romconfig *rc = get_device_romconfig(&currprefs, ert->romtype, j);
-                               if (rc) {
-                                       if (ert->subtypes) {
-                                               const struct expansionsubromtype *srt = &ert->subtypes[rc->subtype];
-                                               return srt->memory_after;
-                                       }
-                                       return ert->memory_after;
-                               }
-                       }
+               if (fastmem_num < MAX_RAM_BOARDS && zorro == 2 && cst->memory_mid && p->fastmem[fastmem_num].size) {
+                       cards_set[cardno].flags = (fastmem_num << 16) | CARD_FLAG_CHILD;
+                       cards_set[cardno].name = _T("Z2Fast");
+                       cards_set[cardno].initnum = expamem_init_fastcard;
+                       cards_set[cardno].zorro = zorro;
+                       cards_set[cardno].cst = cst;
+                       cards_set[cardno++].map = expamem_map_fastcard;
+                       fastmem_num++;
                }
        }
-       return false;
+       if (fastmem_nump)
+               *fastmem_nump = fastmem_num;
 }
 
-static void add_expansions(int zorro)
+static void add_expansions(struct uae_prefs *p, int zorro, int *fastmem_nump, int mode)
 {
+       int fastmem_num = MAX_RAM_BOARDS;
+       if (fastmem_nump)
+               fastmem_num = *fastmem_nump;
        for (int i = 0; expansionroms[i].name; i++) {
                const struct expansionromtype *ert = &expansionroms[i];
                if (ert->zorro == zorro) {
                        for (int j = 0; j < MAX_DUPLICATE_EXPANSION_BOARDS; j++) {
-                               struct romconfig *rc = get_device_romconfig(&currprefs, ert->romtype, j);
+                               struct romconfig *rc = get_device_romconfig(p, ert->romtype, j);
                                if (rc) {
                                        if (zorro == 1) {
-                                               ert->init(rc);
-                                               if (ert->init2)
-                                                       ert->init2(rc);
+                                               struct autoconfig_info aci = { 0 };
+                                               aci.prefs = p;
+                                               aci.doinit = true;
+                                               aci.rc = rc;
+                                               ert->init(&aci);
+                                               if (ert->init2) {
+                                                       ert->init2(&aci);
+                                               }
                                        } else {
-                                               cards[cardno].flags = 0;
-                                               cards[cardno].name = ert->name;
-                                               cards[cardno].initrc = ert->init;
-                                               cards[cardno].rc = rc;
-                                               cards[cardno].zorro = zorro;
-                                               cards[cardno++].map = NULL;
+                                               int mid = ert->memory_mid;
+                                               bool memory_after = ert->memory_after;
+                                               bool added = false;
+                                               if (ert->subtypes) {
+                                                       const struct expansionsubromtype *srt = &ert->subtypes[rc->subtype];
+                                                       mid = srt->memory_mid;
+                                                       memory_after = srt->memory_after;
+                                               }
+
+                                               if (mode == 1 && ert->memory_mid)
+                                                       continue;
+                                               if (mode == 2 && !ert->memory_mid)
+                                                       continue;
+                                               if (fastmem_num < MAX_RAM_BOARDS && zorro == 2 && mid && !memory_after && p->fastmem[fastmem_num].size) {
+                                                       cards_set[cardno].flags = (fastmem_num << 16);
+                                                       cards_set[cardno].name = _T("Z2Fast");
+                                                       cards_set[cardno].initnum = expamem_init_fastcard;
+                                                       cards_set[cardno].zorro = zorro;
+                                                       cards_set[cardno].ert = ert;
+                                                       cards_set[cardno++].map = expamem_map_fastcard;
+                                                       fastmem_num++;
+                                                       added = true;
+                                               }
+                                               if (fastmem_num < MAX_RAM_BOARDS && zorro == 3 && mid && !memory_after && p->z3fastmem[fastmem_num].size) {
+                                                       cards_set[cardno].flags = CARD_FLAG_CAN_Z3 | (fastmem_num << 16);
+                                                       cards_set[cardno].name = _T("Z3Fast");
+                                                       cards_set[cardno].initnum = expamem_init_z3fastmem;
+                                                       cards_set[cardno].zorro = zorro;
+                                                       cards_set[cardno].ert = ert;
+                                                       cards_set[cardno++].map = expamem_map_z3fastmem;
+                                                       fastmem_num++;
+                                                       added = true;
+                                               }
+                                               cards_set[cardno].flags = added ? CARD_FLAG_CHILD : 0;
+                                               cards_set[cardno].name = ert->name;
+                                               cards_set[cardno].initrc = ert->init;
+                                               cards_set[cardno].rc = rc;
+                                               cards_set[cardno].zorro = zorro;
+                                               cards_set[cardno++].map = NULL;
                                                if (ert->init2) {
-                                                       cards[cardno].flags = 0;
-                                                       cards[cardno].name = ert->name;
-                                                       cards[cardno].initrc = ert->init2;
-                                                       cards[cardno].rc = rc;
-                                                       cards[cardno].zorro = zorro;
-                                                       cards[cardno++].map = NULL;
+                                                       cards_set[cardno].flags = CARD_FLAG_CHILD;
+                                                       cards_set[cardno].name = ert->name;
+                                                       cards_set[cardno].initrc = ert->init2;
+                                                       cards_set[cardno].rc = rc;
+                                                       cards_set[cardno].zorro = zorro;
+                                                       cards_set[cardno++].map = NULL;
+                                               }
+                                               if (fastmem_num < MAX_RAM_BOARDS && zorro == 2 && mid && memory_after && p->fastmem[fastmem_num].size) {
+                                                       cards_set[cardno].flags = (fastmem_num << 16) | CARD_FLAG_CHILD;
+                                                       cards_set[cardno].name = _T("Z2Fast");
+                                                       cards_set[cardno].initnum = expamem_init_fastcard;
+                                                       cards_set[cardno].zorro = zorro;
+                                                       cards_set[cardno].ert = ert;
+                                                       cards_set[cardno++].map = expamem_map_fastcard;
+                                                       fastmem_num++;
+                                               }
+                                               if (fastmem_num < MAX_RAM_BOARDS && zorro == 3 && mid && memory_after && p->z3fastmem[fastmem_num].size) {
+                                                       cards_set[cardno].flags = CARD_FLAG_CAN_Z3 | (fastmem_num << 16) | CARD_FLAG_CHILD;
+                                                       cards_set[cardno].name = _T("Z3Fast");
+                                                       cards_set[cardno].initnum = expamem_init_z3fastmem;
+                                                       cards_set[cardno].zorro = zorro;
+                                                       cards_set[cardno].ert = ert;
+                                                       cards_set[cardno++].map = expamem_map_z3fastmem;
+                                                       fastmem_num++;
                                                }
                                        }
                                }
                        }
                }
        }
+       if (fastmem_nump)
+               *fastmem_nump = fastmem_num;
 }
 
-void expamem_reset (void)
+static uae_u8 autoconfig_read(const uae_u8 *autoconfig, int offset)
 {
-       int do_mount = 1;
+       uae_u8 b = (autoconfig[offset] & 0xf0) | (autoconfig[offset + 2] >> 4);
+       if (offset == 0 || offset == 2 || offset == 0x40 || offset == 0x42)
+               return b;
+       b = ~b;
+       return b;
+}
 
-       ecard = 0;
-       cardno = 0;
-       chipdone = false;
+static void expansion_parse_autoconfig(struct card_data *cd, const uae_u8 *autoconfig)
+{
+       uae_u8 code = autoconfig[0];
+       uae_u32 expamem_z3_size;
 
-       if (currprefs.uae_hide)
-               uae_id = commodore;
-       else
-               uae_id = hackers_id;
+       if ((code & 0xc0) == zorroII) {
+               int slotsize;
+               // Z2
+               cd->zorro = 2;
+               code &= 7;
+               if (code == 0)
+                       expamem_board_size = 8 * 1024 * 1024;
+               else
+                       expamem_board_size = 32768 << code;
+               slotsize = expamem_board_size / 65536;
+
+               expamem_board_pointer = 0xffffffff;
+
+               for (int slottype = 0; slottype < 2; slottype++)
+               {
+                       uae_u8 *slots = slots_e8;
+                       int numslots = sizeof slots_e8;
+                       uaecptr slotaddr = 0xe80000;
+                       if (slotsize >= 8 || slottype > 0) {
+                               slots = slots_20;
+                               numslots = sizeof slots_20;
+                               slotaddr = 0x200000;
+                       }
+                       for (int i = 0; i < numslots; i++) {
+                               if (((slotsize - 1) & i) == 0) {
+                                       bool free = true;
+                                       for (int j = 0; j < slotsize && j + i < numslots; j++) {
+                                               if (slots[i + j] != 0) {
+                                                       free = false;
+                                                       break;
+                                               }
+                                       }
+                                       if (free) {
+                                               for (int j = 0; j < slotsize; j++) {
+                                                       slots[i + j] = 1;
+                                               }
+                                               expamem_board_pointer = slotaddr + i * 65536;
+                                               break;
+                                       }
+                               }
+                       }
+                       if (expamem_board_pointer != 0xffffffff || slotsize >= 8)
+                               break;
+               }
 
-       allocate_expamem ();
-       expamem_bank.name = _T("Autoconfig [reset]");
+       } else if ((code & 0xc0) == zorroIII) {
+               // Z3
 
-       if (need_uae_boot_rom() == 0)
-               do_mount = 0;
-       if (uae_boot_rom_type <= 0)
-               do_mount = 0;
+               cd->zorro = 3;
+               code &= 7;
+               if (autoconfig[2] & ext_size)
+                       expamem_z3_size = (16 * 1024 * 1024) << code;
+               else
+                       expamem_z3_size = 16 * 1024 * 1024;
 
-       /* check if Kickstart version is below 1.3 */
-       if (ks12orolder() && do_mount && currprefs.uaeboard < 2) {
-               /* warn user */
+               expamem_z3_pointer_real = (expamem_z3_pointer_real + expamem_z3_size - 1) & ~(expamem_z3_size - 1);
+
+               expamem_board_pointer = expamem_z3hack(cd->aci.prefs) ? expamem_z3_pointer_uae : expamem_z3_pointer_real;
+               expamem_board_size = expamem_z3_size;
+
+       } else if ((code & 0xc0) == 0x40) {
+               cd->zorro = 1;
+               // 0x40 = "Box without init/diagnostic code"
+               // proto autoconfig "box" size.
+               //expamem_z2_size = (1 << ((code >> 3) & 7)) * 4096;
+               // much easier this way, all old-style boards were made for
+               // A1000 and didn't have passthrough connector.
+               expamem_board_size = 65536;
+               expamem_board_pointer = 0xe90000;
+       }
+
+}
+
+static void reset_ac_data(struct uae_prefs *p)
+{
+       expamem_z3_pointer_real = Z3BASE_REAL;
+       expamem_z3_pointer_uae = Z3BASE_UAE;
+
+       expamem_highmem_pointer = 0;
+       if (p->mbresmem_low_size)
+               expamem_highmem_pointer = 0x08000000;
+       if (p->mbresmem_high_size)
+               expamem_highmem_pointer = 0x08000000 + p->mbresmem_high_size;
+
+       if (p->mbresmem_high_size >= 128 * 1024 * 102)
+               expamem_z3_pointer_uae += (p->mbresmem_high_size - 128 * 1024 * 1024) + 16 * 1024 * 1024;
+       expamem_z3_pointer_uae += p->z3chipmem_size;
+       expamem_board_pointer = 0;
+       expamem_board_size = 0;
+       memset(slots_20, 0, sizeof slots_20);
+       memset(slots_e8, 0, sizeof slots_e8);
+       slots_e8[0] = 1;
+}
+
+static void reset_ac(struct uae_prefs *p)
+{
+       do_mount = 1;
+
+       if (need_uae_boot_rom(p) == 0)
+               do_mount = 0;
+       if (uae_boot_rom_type <= 0)
+               do_mount = 0;
+
+       /* check if Kickstart version is below 1.3 */
+       if (ks12orolder() && do_mount && p->uaeboard < 2) {
+               /* warn user */
 #if KS12_BOOT_HACK
                do_mount = -1;
-               if (ks11orolder()) {
-                       filesys_start = 0xe90000;
-                       map_banks_z2(&filesys_bank, filesys_start >> 16, 1);
-                       expamem_init_filesys(0);
-                       expamem_map_filesys_update();
-               }
 #else
                write_log(_T("Kickstart version is below 1.3!  Disabling automount devices.\n"));
                do_mount = 0;
 #endif
        }
 
-       if (currprefs.cpuboard_type) {
-               // This may require first 128k slot.
-               cards[cardno].flags = 1;
-               cards[cardno].name = _T("CPUBoard");
-               cards[cardno].initrc = cpuboard_autoconfig_init;
-               cards[cardno++].map = NULL;
+       if (p->uae_hide)
+               uae_id = commodore;
+       else
+               uae_id = hackers_id;
+
+       for (int i = 0; i < MAX_EXPANSION_BOARD_SPACE; i++) {
+               memset(&cards_set[i], 0, sizeof(struct card_data));
        }
 
-       // add possible non-autoconfig boards
-       add_cpu_expansions(BOARD_NONAUTOCONFIG_BEFORE);
-       add_expansions(BOARD_NONAUTOCONFIG_BEFORE);
-
-       bool fastmem_after = false;
-       if (currprefs.fastmem_autoconfig) {
-               fastmem_after = add_fastram_after_expansion(BOARD_AUTOCONFIG_Z2);
-               if (!fastmem_after && fastmem_bank.baseaddr != NULL && (fastmem_bank.allocated <= 262144 || currprefs.chipmem_size <= 2 * 1024 * 1024)) {
-                       cards[cardno].flags = 0;
-                       cards[cardno].name = _T("Z2Fast");
-                       cards[cardno].initnum = expamem_init_fastcard;
-                       cards[cardno++].map = expamem_map_fastcard;
-               }
-               if (fastmem2_bank.baseaddr != NULL && (fastmem2_bank.allocated <= 262144  || currprefs.chipmem_size <= 2 * 1024 * 1024)) {
-                       cards[cardno].flags = 0;
-                       cards[cardno].name = _T("Z2Fast2");
-                       cards[cardno].initnum = expamem_init_fastcard2;
-                       cards[cardno++].map = expamem_map_fastcard2;
+       ecard = 0;
+       cardno = 0;
+
+       reset_ac_data(p);
+}
+
+void expansion_generate_autoconfig_info(struct uae_prefs *p)
+{
+       expansion_scan_autoconfig(p, true);
+}
+
+bool alloc_expansion_bank(addrbank *bank, struct autoconfig_info *aci)
+{
+       bank->start = aci->start;
+       bank->allocated = aci->size;
+       aci->addrbank = bank;
+       return mapped_malloc(bank);
+}
+
+void free_expansion_bank(addrbank *bank)
+{
+       mapped_free(bank);
+       bank->start = NULL;
+       bank->allocated = 0;
+}
+
+struct autoconfig_info *expansion_get_autoconfig_data(struct uae_prefs *p, int index)
+{
+       if (index >= cardno)
+               return NULL;
+       struct card_data *cd = cards[index];
+       return &cd->aci;
+}
+
+struct autoconfig_info *expansion_get_autoconfig_by_address(struct uae_prefs *p, uaecptr addr)
+{
+       for (int i = 0; i < cardno; i++) {
+               struct card_data *cd = cards[i];
+               if (cd->base <= addr && cd->base + cd->size >= addr)
+                       return &cd->aci;
+       }
+       return NULL;
+}
+
+struct autoconfig_info *expansion_get_autoconfig_info(struct uae_prefs *p,int romtype, int devnum)
+{
+       for (int i = 0; i < cardno; i++) {
+               struct card_data *cd = cards[i];
+               if (cd->rc) {
+                       if (cd->rc->back->device_type == romtype && cd->rc->back->device_num == devnum) {
+                               return &cd->aci;
+                       }
+               } else if (cd->cst) {
+                       if ((romtype & ROMTYPE_CPUBOARD) && (cd->cst->romtype & ROMTYPE_CPUBOARD))
+                               return &cd->aci;
+               } else {
+                       // z2 and z3 ram boards are "fake"
+                       if ((romtype == ROMTYPE_RAMZ2 && !_tcsicmp(cd->name, _T("Z2Fast")))
+                               || (romtype == ROMTYPE_RAMZ3 && !_tcsicmp(cd->name, _T("Z3Fast")))
+                               || (romtype == ROMTYPE_MEGACHIP && !_tcsicmp(cd->name, _T("MegaChipRAM"))))
+                       {
+                               if (((cd->flags >> 16) & 255) == devnum)
+                                       return &cd->aci;
+                       }
                }
-       } else {
-               if (fastmem_bank.baseaddr) {
-                       fastmem_bank.name = _T("Fast memory (non-autoconfig)");
-                       map_banks(&fastmem_bank, 0x00200000 >> 16, fastmem_bank.allocated >> 16, 0);
+       }
+       return NULL;
+}
+
+static void expansion_init_cards(struct uae_prefs *p)
+{
+       reset_ac_data(p);
+       for (int i = 0; i < cardno; i++) {
+               bool ok;
+               struct card_data *cd = &cards_set[i];
+               struct autoconfig_info *aci = &cd->aci;
+               memset(aci->autoconfig_raw, 0xff, sizeof aci->autoconfig_raw);
+               cd->base = 0;
+               cd->size = 0;
+               aci->devnum = (cd->flags >> 16) & 255;
+               aci->prefs = p;
+               aci->ert = cd->ert;
+               aci->cst = cd->cst;
+               aci->start = 0xffffffff;
+               if (cd->initnum) {
+                       ok = cd->initnum(aci);
+               } else {
+                       aci->rc = cd->rc;
+                       ok = cd->initrc(aci);
                }
-               if (fastmem2_bank.baseaddr != NULL) {
-                       fastmem2_bank.name = _T("Fast memory 2 (non-autoconfig)");
-                       map_banks(&fastmem2_bank, (0x00200000 + fastmem_bank.allocated) >> 16, fastmem2_bank.allocated >> 16, 0);
+               if (cd->flags & CARD_FLAG_CHILD)
+                       aci->parent_of_previous = true;
+               
+               if (aci->addrbank != &expamem_nonautoconfig && aci->addrbank != &expamem_null && aci->addrbank != &expamem_none && (aci->autoconfig_raw[0] != 0xff || aci->autoconfigp)) {
+                       uae_u8 ac2[16];
+                       const uae_u8 *a = aci->autoconfigp;
+                       if (!a) {
+                               for (int i = 0; i < 16; i++) {
+                                       ac2[i] = autoconfig_read(aci->autoconfig_raw, i * 4);
+                               }
+                               a = ac2;
+                       }
+                       expansion_parse_autoconfig(cd, a);
+                       cd->size = expamem_board_size;
                }
        }
+}
+
+static void set_order(struct uae_prefs *p, struct card_data *cd, int order)
+{
+       if (!cd)
+               return;
+       if (cd->aci.set_params) {
+               struct expansion_params parms = { 0 };
+               parms.device_order = order;
+               if (cd->aci.set_params(p, &parms))
+                       return;
+       }
+       if (cd->zorro <= 0 || cd->zorro >= 4)
+               return;
+       if (cd->rc) {
+               cd->rc->back->device_order = order;
+               return;
+       }
+       int devnum = (cd->flags >> 16) & 255;
+       if (!_tcsicmp(cd->name, _T("Z2Fast"))) {
+               p->fastmem[devnum].device_order = order;
+               return;
+       }
+       if (!_tcsicmp(cd->name, _T("Z3Fast"))) {
+               p->z3fastmem[devnum].device_order = order;
+               return;
+       }
+       if (!_tcsicmp(cd->name, _T("Z3RTG")) || !_tcsicmp(cd->name, _T("Z2RTG"))) {
+               p->rtgboards[devnum].device_order = order;
+               return;
+       }
+
+}
 
-       // immediately after Z2Fast so that they can be emulated as A590/A2091 with fast ram.
-       add_cpu_expansions(BOARD_AUTOCONFIG_Z2);
-       add_expansions(BOARD_AUTOCONFIG_Z2);
+static int get_order(struct uae_prefs *p, struct card_data *cd)
+{
+       if (!cd)
+               return EXPANSION_ORDER_MAX - 1;
+       if (cd->cst)
+               return -3; // Accelerator must be always first
+       if (cd->aci.get_params) {
+               struct expansion_params parms;
+               if (cd->aci.get_params(p, &parms))
+                       return parms.device_order;
+       }
+       if (cd->zorro <= 0)
+               return -1;
+       if (cd->zorro >= 4)
+               return -2;
+       if (cd->rc)
+               return cd->rc->back->device_order;
+       int devnum = (cd->flags >> 16) & 255;
+       if (!_tcsicmp(cd->name, _T("Z2Fast")))
+               return p->fastmem[devnum].device_order;
+       if (!_tcsicmp(cd->name, _T("Z3Fast")))
+               return p->z3fastmem[devnum].device_order;
+       if (!_tcsicmp(cd->name, _T("Z3RTG")) || !_tcsicmp(cd->name, _T("Z2RTG")))
+               return p->rtgboards[devnum].device_order;
+       if (!_tcsicmp(cd->name, _T("MegaChipRAM")))
+               return -1;
+       return EXPANSION_ORDER_MAX - 1;
+}
+
+static void expansion_parse_cards(struct uae_prefs *p, bool log)
+{
+       if (log)
+               write_log(_T("Autoconfig board list:\n"));
+       reset_ac_data(p);
+       for (int i = 0; i < cardno; i++) {
+               bool ok;
+               struct card_data *cd = cards[i];
+               struct autoconfig_info *aci = &cd->aci;
+               memset(aci->autoconfig_raw, 0xff, sizeof aci->autoconfig_raw);
+               memset(aci->autoconfig_bytes, 0xff, sizeof aci->autoconfig_bytes);
+               cd->base = 0;
+               cd->size = 0;
+               aci->devnum = (cd->flags >> 16) & 255;
+               aci->prefs = p;
+               aci->ert = cd->ert;
+               aci->cst = cd->cst;
+               aci->start = 0xffffffff;
+               if (cd->initnum) {
+                       ok = cd->initnum(aci);
+               } else {
+                       aci->rc = cd->rc;
+                       ok = cd->initrc(aci);
+               }
+               if (aci->last_high_ram > expamem_highmem_pointer) {
+                       expamem_highmem_pointer = aci->last_high_ram;
+                       if (log)
+                               write_log(_T("Non-Autoconfig highmem increased to %08x\n"), expamem_highmem_pointer);
+               }
+               if (log)
+                       write_log(_T("Card %02d: "), i + 1);
+               if (ok) {
+                       TCHAR label[MAX_DPATH];
+                       label[0] = 0;
+                       if (aci->cst && !label[0]) {
+#if 0
+                               const TCHAR *man = NULL;
+                               for (int i = 0; cpuboards[i].name && man == NULL; i++) {
+                                       const struct cpuboardtype *cbt = &cpuboards[i];
+                                       if (cbt->subtypes) {
+                                               for (int j = 0; cbt->subtypes[j].name && man == NULL; j++) {
+                                                       if (&cbt->subtypes[j] == aci->cst)
+                                                               man = cpuboards[i].name;
+                                               }
+                                       }
+                               }
+                               _stprintf(label, _T("%s (%s)"), aci->cst->name, man);
+#endif
+                               _tcscpy(label, aci->cst->name);
+                       }
+                       if (cd->rc && !label[0]) {
+                               const struct expansionromtype *ert = get_device_expansion_rom(cd->rc->back->device_type);
+                               if (ert) {
+                                       _tcscpy(label, ert->friendlyname);
+                               }
+                       }
+                       if (!label[0]) {
+                               if (aci->label) {
+                                       _tcscpy(label, aci->label);
+                               } else if (aci->addrbank && aci->addrbank->label) {
+                                       _tcscpy(label, aci->addrbank->label);
+                               } else {
+                                       _tcscpy(label, _T("<no name>"));
+                               }
+                       }
+                       if (aci->addrbank != &expamem_nonautoconfig && aci->addrbank != &expamem_null && aci->addrbank != &expamem_none && (aci->autoconfig_raw[0] != 0xff || aci->autoconfigp)) {
+                               uae_u8 ac2[16];
+                               const uae_u8 *a = aci->autoconfigp;
+                               if (!a) {
+                                       for (int i = 0; i < 16; i++) {
+                                               ac2[i] = autoconfig_read(aci->autoconfig_raw, i * 4);
+                                       }
+                                       a = ac2;
+                               }
+                               if (log) {
+                                       write_log(_T("'%s'\n"), label);
+                                       write_log(_T("  %02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x\n"),
+                                               a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7],
+                                               a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]);
+                                       write_log(_T("  MID %u (%04x) PID %u (%02x) SER %08x\n"),
+                                               (a[4] << 8) | a[5], (a[4] << 8) | a[5],
+                                               a[1], a[1],
+                                               (a[6] << 24) | (a[7] << 16) | (a[8] << 8) | a[9]);
+                               }
+                               expansion_parse_autoconfig(cd, a);
+                               uae_u32 size = expamem_board_size;
+                               TCHAR sizemod = 'K';
+                               uae_u8 type = a[0];
+                               size /= 1024;
+                               if (size > 8 * 1024) {
+                                       sizemod = 'M';
+                                       size /= 1024;
+                               }
+                               bool z3 = (type & 0xc0) == zorroIII;
+                               if (log) {
+                                       write_log(_T("  Z%d 0x%08x 0x%08x %4d%c %s %d\n"),
+                                               (type & 0xc0) == zorroII ? 2 : (z3 ? 3 : 1),
+                                               z3 && !currprefs.z3autoconfig_start ? expamem_z3_pointer_real : expamem_board_pointer,
+                                               z3 && !currprefs.z3autoconfig_start ? expamem_z3_pointer_uae : expamem_board_pointer,
+                                               size, sizemod,
+                                               type & rom_card ? _T("ROM") : (type & add_memory ? _T("RAM") : _T("IO ")), get_order(p, cd));
+                               }
+                               cd->base = expamem_board_pointer;
+                               cd->size = expamem_board_size;
+                               if ((type & 0xc0) == zorroIII) {
+                                       aci->start = expamem_z3hack(p) ? expamem_z3_pointer_uae : expamem_z3_pointer_real;
+                               } else {
+                                       aci->start = expamem_board_pointer;
+                               }
+                               aci->size = cd->size;
+                               memcpy(aci->autoconfig_bytes, a, sizeof aci->autoconfig_bytes);
+                               if (aci->addrbank) {
+                                       aci->addrbank->start = expamem_board_pointer;
+                                       if (aci->addrbank->allocated == 0 && !(type & add_memory) && expamem_board_size < 524288) {
+                                               aci->addrbank->allocated = expamem_board_size;
+                                       }
+                               }
+                               aci->zorro = cd->zorro;
+                               if (cd->zorro == 3) {
+                                       expamem_z3_pointer_real += expamem_board_size;
+                                       expamem_z3_pointer_uae += expamem_board_size;
+                                       expamem_board_pointer += expamem_board_size;
+                               }
+                       } else {
+                               if (log)
+                                       write_log(_T("'%s' no autoconfig.\n"), aci->label ? aci->label : _T("<no name>"));
+                       }
+                       _tcscpy(aci->name, label);
+                       if (cd->flags & CARD_FLAG_CHILD)
+                               aci->parent_of_previous = true;
+               } else {
+                       if (log)
+                               write_log(_T("init failed.\n"), i);
+               }
+       }
+       if (log)
+               write_log(_T("END\n"));
+}
 
-       add_cpu_expansions(BOARD_NONAUTOCONFIG_AFTER_Z2);
-       add_expansions(BOARD_NONAUTOCONFIG_AFTER_Z2);
+int expansion_autoconfig_move(struct uae_prefs *p, int index, int dir)
+{
+       if (index < 0 || index >= cardno)
+               return -1;
+       if (!dir)
+               return -1;
+       struct card_data *cd1 = cards[index];
+       int order1 = get_order(p, cd1);
+       if (order1 < 0 || order1 >= EXPANSION_ORDER_MAX - 1)
+               return -1;
+       struct card_data *cd2;
+       int order2;
+       for (;;) {
+               if (index + dir < 0 || index + dir >= cardno)
+                       return -1;
+               cd2 = cards[index + dir];
+               if (cd1->aci.parent_of_previous && !cd2->aci.parent_of_previous)
+                       return -1;
+               order2 = get_order(p, cd2);
+               if (order2 >= 0 && order2 < EXPANSION_ORDER_MAX - 1) {
+                       if (!cd1->aci.parent_of_previous && !cd2->aci.parent_of_previous)
+                               break;
+               }
+               dir += dir < 0 ? -1 : 1;
+       }
+       set_order(p, cd1, order2);
+       set_order(p, cd2, order1);
+       if (p != &currprefs)
+               expansion_scan_autoconfig(p, false);
+       for (int i = 0; i < cardno; i++) {
+               if (cards[i] == cd1)
+                       return i;
+       }
+       return -1;
+}
 
-       if (fastmem_after && currprefs.fastmem_autoconfig) {
-               if (fastmem_bank.baseaddr != NULL && (fastmem_bank.allocated <= 262144 || currprefs.chipmem_size <= 2 * 1024 * 1024)) {
-                       cards[cardno].flags = 0;
-                       cards[cardno].name = _T("Z2Fast");
-                       cards[cardno].initnum = expamem_init_fastcard;
-                       cards[cardno++].map = expamem_map_fastcard;
+static void expansion_recalc_order(struct uae_prefs *p)
+{
+       int ordermin = 1;
+       for (;;) {
+               int order = EXPANSION_ORDER_MAX;
+               int idx = -1;
+               for (int i = 0; i < cardno; i++) {
+                       struct card_data *cdc = cards[i];
+                       int o = get_order(p, cdc);
+                       if (o >= ordermin && order > o) {
+                               order = o;
+                               idx = i;
+                       }
                }
+               if (idx < 0)
+                       break;
+               set_order(p, cards[idx], ordermin);
+               ordermin++;
        }
+}
 
-#ifdef CDTV
-       if (currprefs.cs_cdtvcd && !currprefs.cs_cdtvcr) {
-               cards[cardno].flags = 0;
-               cards[cardno].name = _T("CDTV DMAC");
-               cards[cardno].initrc = cdtv_init;
-               cards[cardno++].map = NULL;
+void expansion_set_autoconfig_sort(struct uae_prefs *p)
+{
+       if (!p->autoconfig_custom_sort)
+               return;
+       for (int i = 0; i < cardno; i++) {
+               set_order(p, cards[i], i + 1);
        }
-#endif
-#ifdef CD32
-       if (currprefs.cs_cd32cd && currprefs.fastmem_size == 0 && currprefs.chipmem_size <= 0x200000 && currprefs.cs_cd32fmv) {
-               cards[cardno].flags = 0;
-               cards[cardno].name = _T("CD32MPEG");
-               cards[cardno].initnum = expamem_init_cd32fmv;
-               cards[cardno++].map = expamem_map_cd32fmv;
+       expansion_recalc_order(p);
+}
+
+static bool ischild(struct card_data *cd)
+{
+       if (cd->aci.parent_name)
+               return true;
+       if (cd->aci.parent_address_space)
+               return true;
+       if (cd->aci.parent_of_previous)
+               return true;
+       if (cd->aci.parent_romtype)
+               return true;
+       return false;
+}
+
+static void check_card_child(int index, bool *inuse, int *new_cardnop)
+{
+       struct card_data *cd = &cards_set[index];
+       int new_cardno = *new_cardnop;
+       // address space "conflict" parent?
+       for (int i = 0; i < cardno; i++) {
+               struct card_data *cdc = &cards_set[i];
+               if (inuse[i])
+                       continue;
+               if (!cdc->aci.parent_address_space)
+                       continue;
+               if (cd->aci.start && cd->aci.size && cdc->aci.start >= cd->aci.start && cdc->aci.start < cd->aci.start + cd->aci.size) {
+                       cards[new_cardno++] = cdc;
+                       cdc->aci.parent_of_previous = true;
+                       inuse[i] = true;
+               }
        }
-#endif
-#ifdef A2065
-       if (currprefs.a2065name[0]) {
-               cards[cardno].flags = 0;
-               cards[cardno].name = _T("A2065");
-               cards[cardno].initnum = a2065_init;
-               cards[cardno++].map = NULL;
+       // romtype parent?
+       for (int i = 0; i < cardno; i++) {
+               struct card_data *cdc = &cards_set[i];
+               if (inuse[i])
+                       continue;
+               const int *parent = cdc->aci.parent_romtype;
+               if (!parent)
+                       continue;
+               for (int j = 0; parent[j]; j++) {
+                       if (cd->rc && parent[j] == (cd->rc->back->device_type & ROMTYPE_MASK)) {
+                               cards[new_cardno++] = cdc;
+                               cdc->aci.parent_of_previous = true;
+                               inuse[i] = true;
+                       }
+               }
        }
-#endif
-#ifdef FILESYS
-       if (do_mount && currprefs.uaeboard < 2) {
-               cards[cardno].flags = 0;
-               cards[cardno].name = _T("UAEFS");
-               cards[cardno].initnum = expamem_init_filesys;
-               cards[cardno++].map = expamem_map_filesys;
+       // named parent
+       for (int i = 0; i < cardno; i++) {
+               struct card_data *cdc = &cards_set[i];
+               if (inuse[i])
+                       continue;
+               if (cdc->aci.parent_name && cd->name && !_tcsicmp(cdc->aci.parent_name, cd->name)) {
+                       cards[new_cardno++] = cdc;
+                       cdc->aci.parent_of_previous = true;
+                       inuse[i] = true;
+               }
        }
-       if (currprefs.uaeboard) {
-               cards[cardno].flags = 0;
-               cards[cardno].name = _T("UAEBOARD");
-               cards[cardno].initnum = expamem_init_uaeboard;
-               cards[cardno++].map = expamem_map_uaeboard;
+       *new_cardnop = new_cardno;
+}
+
+static bool add_card_sort(int index, bool *inuse, int *new_cardnop)
+{
+       struct card_data *cd = &cards_set[index];
+       if (ischild(cd))
+               return false;
+       int new_cardno = *new_cardnop;
+       cards[new_cardno++] = cd;
+       inuse[index] = true;
+       int index2 = index + 1;
+       // any children?
+       while (index2 < cardno) {
+               struct card_data *cdc = &cards_set[index2];
+               struct autoconfig_info *aci = &cdc->aci;
+               if (inuse[index2])
+                       break;
+               if (!ischild(cdc))
+                       break;
+               if (aci->parent_of_previous) {
+                       cards[new_cardno++] = cdc;
+                       inuse[index2] = true;
+                       check_card_child(index2, inuse, &new_cardno);
+               }
+               index2++;
        }
-#endif
-#ifdef CATWEASEL
-       if (currprefs.catweasel && catweasel_init ()) {
-               cards[cardno].flags = 0;
-               cards[cardno].name = _T("CWMK2");
-               cards[cardno].initnum = expamem_init_catweasel;
-               cards[cardno++].map = expamem_map_catweasel;
+       check_card_child(index, inuse, &new_cardno);
+       *new_cardnop = new_cardno;
+       return true;
+}
+
+static void expansion_autoconfig_sort(struct uae_prefs *p)
+{
+       const int zs[] = { BOARD_NONAUTOCONFIG_BEFORE, 0, BOARD_PROTOAUTOCONFIG, BOARD_AUTOCONFIG_Z2, BOARD_NONAUTOCONFIG_AFTER_Z2, BOARD_AUTOCONFIG_Z3, BOARD_NONAUTOCONFIG_AFTER_Z3, -1 };
+       bool inuse[MAX_EXPANSION_BOARD_SPACE];
+       struct card_data *tcards[MAX_EXPANSION_BOARD_SPACE];
+       int new_cardno = 0;
+
+       // default sort first, sets correct parent/child order
+       for (int i = 0; i < cardno; i++) {
+               inuse[i] = false;
+               cards[i] = NULL;
+       }
+       cards[cardno] = NULL;
+       for (int type = 0; zs[type] >= 0; type++) {
+               bool changed = true;
+               int z = zs[type];
+               bool inuse2[MAX_EXPANSION_BOARD_SPACE];
+               memset(inuse2, 0, sizeof inuse2);
+               while (changed) {
+                       changed = false;
+                       // unmovables first
+                       int testorder = 0;
+                       int idx = -1;
+                       for (int i = 0; i < cardno; i++) {
+                               if (inuse[i])
+                                       continue;
+                               if (inuse2[i])
+                                       continue;
+                               struct card_data *cd = &cards_set[i];
+                               if (ischild(cd))
+                                       continue;
+                               if (cd->zorro != z)
+                                       continue;
+                               int order = get_order(p, cd);
+                               if (order >= 0)
+                                       continue;
+                               if (testorder > order) {
+                                       testorder = order;
+                                       idx = i;
+                               }
+                       }
+                       if (idx >= 0) {
+                               inuse2[idx] = true;
+                               add_card_sort(idx, inuse, &new_cardno);
+                               changed = true;
+                       }
+               }
+               changed = true;
+               memset(inuse2, 0, sizeof inuse2);
+               while (changed) {
+                       changed = false;
+                       for (int i = 0; i < cardno; i++) {
+                               if (inuse[i])
+                                       continue;
+                               if (inuse2[i])
+                                       continue;
+                               struct card_data *cd = &cards_set[i];
+                               if (ischild(cd))
+                                       continue;
+                               if (cd->zorro != z)
+                                       continue;
+                               if (get_order(p, cd) < EXPANSION_ORDER_MAX - 1)
+                                       continue;
+                               inuse2[i] = true;
+                               add_card_sort(i, inuse, &new_cardno);
+                               changed = true;
+                       }
+               }
+               changed = true;
+               memset(inuse2, 0, sizeof inuse2);
+               while (changed) {
+                       // the rest
+                       changed = false;
+                       for (int i = 0; i < cardno; i++) {
+                               if (inuse[i])
+                                       continue;
+                               if (inuse2[i])
+                                       continue;
+                               struct card_data *cd = &cards_set[i];
+                               if (ischild(cd))
+                                       continue;
+                               if (cd->zorro != z)
+                                       continue;
+                               inuse2[i] = true;
+                               add_card_sort(i, inuse, &new_cardno);
+                               changed = true;
+                       }
+               }
+       }
+       for (int i = 0; i < cardno; i++) {
+               if (inuse[i])
+                       continue;
+               cards[new_cardno++] = &cards_set[i];
+       }
+       for (int i = 0; i < cardno; i++) {
+               tcards[i] = cards[i];
+               tcards[i]->aci.can_sort = !cards[i]->aci.parent_of_previous && get_order(p, cards[i]) < EXPANSION_ORDER_MAX - 1 && get_order(p, cards[i]) >= 0;
+       }
+
+       if (!p->autoconfig_custom_sort) {
+
+               new_cardno = 0;
+
+               // accelerator first
+               for (int idx = 0; idx < cardno; idx++) {
+                       struct card_data *cd = tcards[idx];
+                       if (!cd)
+                               continue;
+                       if (cd->cst) {
+                               cards[new_cardno++] = cd;
+                               tcards[idx] = NULL;
+                               for (int j = idx + 1; j < cardno; j++) {
+                                       struct card_data *cdc = tcards[j];
+                                       if (!cdc || !ischild(cdc))
+                                               break;
+                                       cards[new_cardno++] = cdc;
+                                       tcards[j] = NULL;
+                               }
+                       }
+               }
+
+               // re-sort by board size
+               for (int idx = 0; idx < cardno; idx++) {
+                       struct card_data *cd = tcards[idx];
+                       if (!cd)
+                               continue;
+                       int z = cd->zorro;
+                       if ((z != 2 && z != 3 && !ischild(cd)) || cd->cst) {
+                               cards[new_cardno++] = cd;
+                               tcards[idx] = NULL;
+                               for (int j = idx + 1; j < cardno; j++) {
+                                       struct card_data *cdc = tcards[j];
+                                       if (!cdc || !ischild(cdc))
+                                               break;
+                                       cards[new_cardno++] = cdc;
+                                       tcards[j] = NULL;
+                               }
+                       }
+               }
+               for (int z = 2; z <= 3; z++) {
+                       for (;;) {
+                               int idx2 = -1;
+                               uae_u32 size = 0;
+                               for (int j = 0; j < cardno; j++) {
+                                       struct card_data *cdc = tcards[j];
+                                       if (cdc && cdc->size > size && cdc->zorro == z && !ischild(cdc)) {
+                                               size = cdc->size;
+                                               idx2 = j;
+                                       }
+                               }
+                               if (idx2 < 0)
+                                       break;
+                               cards[new_cardno++] = tcards[idx2];
+                               tcards[idx2] = NULL;
+                               for (int j = idx2 + 1; j < cardno; j++) {
+                                       struct card_data *cdc = tcards[j];
+                                       if (!cdc || !ischild(cdc))
+                                               break;
+                                       cards[new_cardno++] = cdc;
+                                       tcards[j] = NULL;
+                               }
+                       }
+               }
+
+       } else {
+
+               // re-sort by configuration data
+               new_cardno = 0;
+               for (;;) {
+                       int order = EXPANSION_ORDER_MAX;
+                       int idx = -1;
+                       for (int i = 0; i < cardno; i++) {
+                               struct card_data *cd = tcards[i];
+                               if (cd && get_order(p, cd) < order && !cd->aci.parent_of_previous) {
+                                       order = get_order(p, cd);
+                                       idx = i;
+                               }
+                       }
+                       if (idx >= 0) {
+                               struct card_data *cd = tcards[idx];
+                               struct autoconfig_info *aci = &cd->aci;
+                               cards[new_cardno++] = cd;
+                               tcards[idx] = NULL;
+                               // sort children, if any
+                               int child = 0;
+                               for (int j = idx + 1; j < cardno; j++) {
+                                       struct card_data *cdc = tcards[j];
+                                       if (!cdc || !cdc->aci.parent_of_previous)
+                                               break;
+                                       child++;
+                               }
+                               for (;;) {
+                                       order = EXPANSION_ORDER_MAX;
+                                       int cidx = -1;
+                                       for (int j = 0; j < child; j++) {
+                                               struct card_data *cdc = tcards[j + idx + 1];
+                                               if (cdc && get_order(p, cdc) < order) {
+                                                       order = get_order(p, cdc);
+                                                       cidx = j;
+                                               }
+                                       }
+                                       if (cidx < 0)
+                                               break;
+                                       cards[new_cardno++] = tcards[idx + 1 + cidx];
+                                       tcards[idx + 1 + cidx] = NULL;
+                               }
+                               for (int j = 0; j < child; j++) {
+                                       if (tcards[idx + 1 + j]) {
+                                               cards[new_cardno++] = tcards[idx + 1 +j];
+                                       }
+                               }
+                       }
+                       if (idx < 0)
+                               break;
+               }
+       }
+
+       for (int i = 0; i < cardno; i++) {
+               if (tcards[i]) {
+                       cards[new_cardno++] = tcards[i];
+               }
+       }
+
+}
+
+static void expansion_add_autoconfig(struct uae_prefs *p)
+{
+       int fastmem_num;
+
+       reset_ac(p);
+
+       if (p == &currprefs && do_mount < 0 && ks11orolder()) {
+               filesys_start = 0xe90000;
+               map_banks_z2(&filesys_bank, filesys_start >> 16, 1);
+               expamem_init_filesys(0);
+               expamem_map_filesys_update();
+       }
+
+       if (p->cpuboard_type) {
+               // This may require first 128k slot.
+               cards_set[cardno].flags = 1;
+               cards_set[cardno].name = _T("CPUBoard");
+               cards_set[cardno].initrc = cpuboard_autoconfig_init;
+               cards_set[cardno].zorro = BOARD_NONAUTOCONFIG_BEFORE;
+               cards_set[cardno].cst = &cpuboards[p->cpuboard_type].subtypes[p->cpuboard_subtype];;
+               cards_set[cardno++].map = NULL;
+       }
+
+       if (p->z3chipmem_size) {
+               cards_set[cardno].flags = 0;
+               cards_set[cardno].name = _T("MegaChipRAM");
+               cards_set[cardno].initrc = megachipram_init;
+               cards_set[cardno].zorro = BOARD_NONAUTOCONFIG_BEFORE;
+               cards_set[cardno++].map = NULL;
+       }
+
+       // add possible non-autoconfig boards
+       add_cpu_expansions(p, BOARD_NONAUTOCONFIG_BEFORE, NULL);
+       add_expansions(p, BOARD_NONAUTOCONFIG_BEFORE, NULL, 0);
+
+       fastmem_num = 0;
+       add_cpu_expansions(p, BOARD_AUTOCONFIG_Z2, &fastmem_num);
+       // immediately after Z2Fast so that it can be emulated as A590/A2091 with fast ram.
+       add_expansions(p, BOARD_AUTOCONFIG_Z2, &fastmem_num, 0);
+
+       add_cpu_expansions(p, BOARD_NONAUTOCONFIG_AFTER_Z2, NULL);
+       add_expansions(p, BOARD_NONAUTOCONFIG_AFTER_Z2, NULL, 0);
+
+       while (fastmem_num < MAX_RAM_BOARDS) {
+               if (p->fastmem[fastmem_num].size) {
+                       cards_set[cardno].flags = fastmem_num << 16;
+                       cards_set[cardno].name = _T("Z2Fast");
+                       cards_set[cardno].zorro = 2;
+                       cards_set[cardno].initnum = expamem_init_fastcard;
+                       cards_set[cardno++].map = expamem_map_fastcard;
+               }
+               fastmem_num++;
+       }
+
+#ifdef FILESYS
+       if (do_mount && p->uaeboard >= 0 && p->uaeboard < 2) {
+               cards_set[cardno].flags = 0;
+               cards_set[cardno].name = _T("UAEFS");
+               cards_set[cardno].zorro = 2;
+               cards_set[cardno].initnum = expamem_init_filesys;
+               cards_set[cardno++].map = expamem_map_filesys;
+       }
+       if (p->uaeboard > 0) {
+               cards_set[cardno].flags = 0;
+               cards_set[cardno].name = _T("UAEBOARD");
+               cards_set[cardno].zorro = 2;
+               cards_set[cardno].initnum = expamem_init_uaeboard;
+               cards_set[cardno++].map = expamem_map_uaeboard;
        }
 #endif
 #ifdef PICASSO96
        for (int i = 0; i < MAX_RTG_BOARDS; i++) {
-               struct rtgboardconfig *rbc = &currprefs.rtgboards[i];
-               if (rbc->rtgmem_size && rbc->rtgmem_type == GFXBOARD_UAE_Z2 && gfxmem_bank.baseaddr != NULL) {
-                       cards[cardno].flags = 4;
-                       cards[cardno].name = _T("Z2RTG");
-                       cards[cardno].initnum = expamem_init_gfxcard_z2;
-                       cards[cardno++].map = expamem_map_gfxcard_z2;
+               struct rtgboardconfig *rbc = &p->rtgboards[i];
+               if (rbc->rtgmem_size && rbc->rtgmem_type == GFXBOARD_UAE_Z2) {
+                       cards_set[cardno].flags = 4 | (i << 16);
+                       cards_set[cardno].zorro = 2;
+                       cards_set[cardno].name = _T("Z2RTG");
+                       cards_set[cardno].initnum = expamem_init_gfxcard_z2;
+                       cards_set[cardno++].map = expamem_map_gfxcard_z2;
                }
        }
 #endif
 #ifdef GFXBOARD
        for (int i = 0; i < MAX_RTG_BOARDS; i++) {
-               struct rtgboardconfig *rbc = &currprefs.rtgboards[i];
+               struct rtgboardconfig *rbc = &p->rtgboards[i];
                if (rbc->rtgmem_size && rbc->rtgmem_type >= GFXBOARD_HARDWARE && gfxboard_get_configtype(rbc) <= 2) {
-                       cards[cardno].flags = 4;
+                       cards_set[cardno].flags = 4 | (i << 16);
                        if (rbc->rtgmem_type == GFXBOARD_A2410) {
-                               cards[cardno].name = _T("Gfxboard A2410");
-                               cards[cardno++].initnum = tms_init;
+                               cards_set[cardno].name = _T("Z2RTG");
+                               cards_set[cardno].zorro = 2;
+                               cards_set[cardno++].initnum = tms_init;
                        } else {
-                               cards[cardno].name = _T("Gfxboard VRAM Zorro II");
-                               cards[cardno++].initnum = gfxboard_init_memory;
-                               if (gfxboard_num_boards (rbc) == 3) {
-                                       cards[cardno].flags = 0;
-                                       cards[cardno].name = _T("Gfxboard VRAM Zorro II Extra");
-                                       cards[cardno++].initnum = gfxboard_init_memory_p4_z2;
+                               cards_set[cardno].name = _T("Z2RTG");
+                               cards_set[cardno].zorro = 2;
+                               cards_set[cardno++].initnum = gfxboard_init_memory;
+                               if (gfxboard_num_boards(rbc) == 3) {
+                                       cards_set[cardno].flags = (i << 16) | CARD_FLAG_CHILD;
+                                       cards_set[cardno].name = _T("Gfxboard VRAM Zorro II Extra");
+                                       cards_set[cardno].zorro = 2;
+                                       cards_set[cardno++].initnum = gfxboard_init_memory_p4_z2;
                                }
-                               if (gfxboard_is_registers (rbc)) {
-                                       cards[cardno].flags = 0;
-                                       cards[cardno].name = _T ("Gfxboard Registers");
-                                       cards[cardno++].initnum = gfxboard_init_registers;
+                               if (gfxboard_is_registers(rbc)) {
+                                       cards_set[cardno].flags = (i << 16) | CARD_FLAG_CHILD;
+                                       cards_set[cardno].name = _T("Gfxboard Registers");
+                                       cards_set[cardno].zorro = 2;
+                                       cards_set[cardno++].initnum = gfxboard_init_registers;
                                }
                        }
                }
        }
 #endif
-#ifdef WITH_TOCCATA
-       if (currprefs.sound_toccata) {
-               cards[cardno].flags = 0;
-               cards[cardno].name = _T("Toccata");
-               cards[cardno++].initnum = sndboard_init;
-       }
-#endif
-       if (currprefs.monitoremu == MONITOREMU_FIRECRACKER24) {
-               cards[cardno].flags = 0;
-               cards[cardno].name = _T("FireCracker24");
-               cards[cardno++].initnum = specialmonitor_autoconfig_init;
+       if (p->monitoremu == MONITOREMU_FIRECRACKER24) {
+               cards_set[cardno].flags = 0;
+               cards_set[cardno].name = _T("FireCracker24");
+               cards_set[cardno].zorro = 2;
+               cards_set[cardno++].initnum = specialmonitor_autoconfig_init;
        }
 
        /* Z3 boards last */
-       if (!currprefs.address_space_24) {
 
-               add_cpu_expansions(BOARD_AUTOCONFIG_Z3);
+       fastmem_num = 0;
+
+       add_cpu_expansions(p, BOARD_AUTOCONFIG_Z3, &fastmem_num);
+
+       // add combo Z3 boards (something + Z3 RAM)
+       add_expansions(p, BOARD_AUTOCONFIG_Z3, &fastmem_num, 2);
 
-               if (z3fastmem_bank.baseaddr != NULL) {
-                       bool alwaysmapz3 = currprefs.z3_mapping_mode != Z3MAPPING_REAL;
+       // add remaining RAM boards
+       for (int i = fastmem_num; i < MAX_RAM_BOARDS; i++) {
+               if (p->z3fastmem[i].size) {
                        z3num = 0;
-                       cards[cardno].flags = 16 | 2 | 1;
-                       cards[cardno].name = _T("Z3Fast");
-                       cards[cardno].initnum = expamem_init_z3fastmem;
-                       cards[cardno++].map = expamem_map_z3fastmem;
-                       if (alwaysmapz3 || expamem_z3hack(&currprefs))
-                               map_banks_z3(&z3fastmem_bank, z3fastmem_bank.start >> 16, currprefs.z3fastmem_size >> 16);
-                       if (z3fastmem2_bank.baseaddr != NULL) {
-                               cards[cardno].flags = 16 | 2 | 1;
-                               cards[cardno].name = _T("Z3Fast2");
-                               cards[cardno].initnum = expamem_init_z3fastmem2;
-                               cards[cardno++].map = expamem_map_z3fastmem2;
-                               if (alwaysmapz3 || expamem_z3hack(&currprefs))
-                                       map_banks_z3(&z3fastmem2_bank, z3fastmem2_bank.start >> 16, currprefs.z3fastmem2_size >> 16);
-                       }
+                       cards_set[cardno].flags = (2 | CARD_FLAG_CAN_Z3) | (i << 16);
+                       cards_set[cardno].name = _T("Z3Fast");
+                       cards_set[cardno].zorro = 3;
+                       cards_set[cardno].initnum = expamem_init_z3fastmem;
+                       cards_set[cardno++].map = expamem_map_z3fastmem;
                }
-               if (z3chipmem_bank.baseaddr != NULL)
-                       map_banks_z3(&z3chipmem_bank, z3chipmem_bank.start >> 16, currprefs.z3chipmem_size >> 16);
+       }
 #ifdef PICASSO96
-               if (currprefs.rtgboards[0].rtgmem_size && currprefs.rtgboards[0].rtgmem_type == GFXBOARD_UAE_Z3 && gfxmem_bank.baseaddr != NULL) {
-                       cards[cardno].flags = 16 | 4 | 1;
-                       cards[cardno].name = _T("Z3RTG");
-                       cards[cardno].initnum = expamem_init_gfxcard_z3;
-                       cards[cardno++].map = expamem_map_gfxcard_z3;
+               for (int i = 0; i < MAX_RTG_BOARDS; i++) {
+               if (p->rtgboards[i].rtgmem_size && p->rtgboards[i].rtgmem_type == GFXBOARD_UAE_Z3) {
+                       cards_set[cardno].flags = 4 | CARD_FLAG_CAN_Z3 | (i << 16);
+                       cards_set[cardno].name = _T("Z3RTG");
+                       cards_set[cardno].zorro = 3;
+                       cards_set[cardno].initnum = expamem_init_gfxcard_z3;
+                       cards_set[cardno++].map = expamem_map_gfxcard_z3;
                }
+       }
 #endif
 #ifdef GFXBOARD
-               if (currprefs.rtgboards[0].rtgmem_size && currprefs.rtgboards[0].rtgmem_type >= GFXBOARD_HARDWARE && gfxboard_get_configtype(&currprefs.rtgboards[0]) == 3) {
-                       cards[cardno].flags = 4 | 1;
-                       cards[cardno].name = _T ("Gfxboard VRAM Zorro III");
-                       cards[cardno++].initnum = gfxboard_init_memory;
-                       cards[cardno].flags = 1;
-                       cards[cardno].name = _T ("Gfxboard Registers");
-                       cards[cardno++].initnum = gfxboard_init_registers;
+       for (int i = 0; i < MAX_RTG_BOARDS; i++) {
+               struct rtgboardconfig *rbc = &p->rtgboards[i];
+               if (rbc->rtgmem_size && rbc->rtgmem_type >= GFXBOARD_HARDWARE && gfxboard_get_configtype(rbc) == 3) {
+                       cards_set[cardno].flags = 4 | CARD_FLAG_CAN_Z3 | (i << 16);
+                       cards_set[cardno].name = _T("Z3RTG");
+                       cards_set[cardno].zorro = 3;
+                       cards_set[cardno++].initnum = gfxboard_init_memory;
+                       if (gfxboard_is_registers(rbc)) {
+                               cards_set[cardno].flags = 1 | (i << 16) | CARD_FLAG_CHILD;
+                               cards_set[cardno].zorro = 3;
+                               cards_set[cardno].name = _T("Gfxboard Registers");
+                               cards_set[cardno++].initnum = gfxboard_init_registers;
+                       }
                }
+       }
 #endif
 
-               add_expansions(BOARD_AUTOCONFIG_Z3);
+       // add non-memory Z3 boards
+       add_expansions(p, BOARD_AUTOCONFIG_Z3, NULL, 1);
 
-       }
+       add_cpu_expansions(p,BOARD_NONAUTOCONFIG_AFTER_Z3, NULL);
+       add_expansions(p, BOARD_NONAUTOCONFIG_AFTER_Z3, NULL, 0);
+}
+
+void expansion_scan_autoconfig(struct uae_prefs *p, bool log)
+{
+       cfgfile_compatibility_romtype(p);
+       expansion_add_autoconfig(p);
+       expansion_init_cards(p);
+       expansion_autoconfig_sort(p);
+       expansion_parse_cards(p, log);
+}
+
+void expamem_reset (void)
+{
+       reset_ac(&currprefs);
 
-       add_cpu_expansions(BOARD_NONAUTOCONFIG_AFTER_Z3);
-       add_expansions(BOARD_NONAUTOCONFIG_AFTER_Z3);
+       chipdone = false;
+
+       allocate_expamem ();
+       expamem_bank.name = _T("Autoconfig [reset]");
+
+       expansion_add_autoconfig(&currprefs);
+       expansion_init_cards(&currprefs);
+       expansion_autoconfig_sort(&currprefs);
+       expansion_parse_cards(&currprefs, true);
+
+       if (currprefs.z3chipmem_size)
+               map_banks_z3(&z3chipmem_bank, z3chipmem_bank.start >> 16, currprefs.z3chipmem_size >> 16);
 
-       expamem_z3_pointer = 0;
-       expamem_z3_sum = 0;
-       expamem_z2_pointer = 0;
        if (cardno == 0 || savestate_state)
                expamem_init_clear_zero ();
        else
@@ -2379,37 +3248,29 @@ void expansion_init (void)
 {
        if (savestate_state != STATE_RESTORE) {
 
-               fastmem_bank.allocated = 0;
-               fastmem_bank.mask = fastmem_bank.start = 0;
-               fastmem_bank.baseaddr = NULL;
-               fastmem_nojit_bank.allocated = 0;
-               fastmem_nojit_bank.mask = fastmem_nojit_bank.start = 0;
-               fastmem_nojit_bank.baseaddr = NULL;
-
-               fastmem2_bank.allocated = 0;
-               fastmem2_bank.mask = fastmem2_bank.start = 0;
-               fastmem2_bank.baseaddr = NULL;
-               fastmem2_nojit_bank.allocated = 0;
-               fastmem2_nojit_bank.mask = fastmem2_nojit_bank.start = 0;
-               fastmem2_nojit_bank.baseaddr = NULL;
+               for (int i = 0; i < MAX_RAM_BOARDS; i++) {
+                       fastmem_bank[i].allocated = 0;
+                       fastmem_bank[i].mask = 0;
+                       fastmem_bank[i].baseaddr = NULL;
+               }
 
 #ifdef PICASSO96
-               gfxmem_bank.allocated = 0;
-               gfxmem_bank.mask = gfxmem_bank.start = 0;
-               gfxmem_bank.baseaddr = NULL;
+               for (int i = 0; i < MAX_RTG_BOARDS; i++) {
+                       gfxmem_banks[i]->allocated = 0;
+                       gfxmem_banks[i]->mask = 0;
+                       gfxmem_banks[i]->baseaddr = NULL;
+               }
 #endif
 
 #ifdef CATWEASEL
                catweasel_mask = catweasel_start = 0;
 #endif
 
-               z3fastmem_bank.allocated = 0;
-               z3fastmem_bank.mask = z3fastmem_bank.start = 0;
-               z3fastmem_bank.baseaddr = NULL;
-
-               z3fastmem2_bank.allocated = 0;
-               z3fastmem2_bank.mask = z3fastmem2_bank.start = 0;
-               z3fastmem2_bank.baseaddr = NULL;
+               for (int i = 0; i < MAX_RAM_BOARDS; i++) {
+                       z3fastmem_bank[i].allocated = 0;
+                       z3fastmem_bank[i].mask = 0;
+                       z3fastmem_bank[i].baseaddr = NULL;
+               }
 
                z3chipmem_bank.allocated = 0;
                z3chipmem_bank.mask = z3chipmem_bank.start = 0;
@@ -2437,18 +3298,17 @@ void expansion_init (void)
 
 void expansion_cleanup (void)
 {
-       mapped_free (&fastmem_bank);
-       fastmem_nojit_bank.baseaddr = NULL;
-       mapped_free (&fastmem2_bank);
-       fastmem2_nojit_bank.baseaddr = NULL;
-       mapped_free (&z3fastmem_bank);
-       mapped_free (&z3fastmem2_bank);
+       for (int i = 0; i < MAX_RAM_BOARDS; i++) {
+               mapped_free (&fastmem_bank[i]);
+               mapped_free (&z3fastmem_bank[i]);
+       }
        mapped_free (&z3chipmem_bank);
 
 #ifdef PICASSO96
        for (int i = 0; i < MAX_RTG_BOARDS; i++) {
-               if (currprefs.rtgboards[i].rtgmem_type < GFXBOARD_HARDWARE)
-                       mapped_free (&gfxmem_bank);
+               if (currprefs.rtgboards[i].rtgmem_type < GFXBOARD_HARDWARE) {
+                       mapped_free (gfxmem_banks[i]);
+               }
        }
 #endif
 
@@ -2473,12 +3333,14 @@ static void clear_bank (addrbank *ab)
 
 void expansion_clear (void)
 {
-       clear_bank (&fastmem_bank);
-       clear_bank (&fastmem2_bank);
-       clear_bank (&z3fastmem_bank);
-       clear_bank (&z3fastmem2_bank);
+       for (int i = 0; i < MAX_RAM_BOARDS; i++) {
+               clear_bank (&fastmem_bank[i]);
+               clear_bank (&z3fastmem_bank[i]);
+       }
        clear_bank (&z3chipmem_bank);
-       clear_bank (&gfxmem_bank);
+       for (int i = 0; i < MAX_RTG_BOARDS; i++) {
+               clear_bank (gfxmem_banks[i]);
+       }
 }
 
 #ifdef SAVESTATE
@@ -2487,13 +3349,8 @@ void expansion_clear (void)
 
 uae_u8 *save_fram (int *len, int num)
 {
-       if (num) {
-               *len = fastmem2_bank.allocated;
-               return fastmem2_bank.baseaddr;
-       } else {
-               *len = fastmem_bank.allocated;
-               return fastmem_bank.baseaddr;
-       }
+       *len = fastmem_bank[num].allocated;
+       return fastmem_bank[num].baseaddr;
 }
 
 uae_u8 *save_zram (int *len, int num)
@@ -2502,31 +3359,20 @@ uae_u8 *save_zram (int *len, int num)
                *len = z3chipmem_bank.allocated;
                return z3chipmem_bank.baseaddr;
        }
-       *len = num ? z3fastmem2_bank.allocated : z3fastmem_bank.allocated;
-       return num ? z3fastmem2_bank.baseaddr : z3fastmem_bank.baseaddr;
+       *len = z3fastmem_bank[num].allocated;
+       return z3fastmem_bank[num].baseaddr;
 }
 
 uae_u8 *save_pram (int *len)
 {
-       *len = gfxmem_bank.allocated;
-       return gfxmem_bank.baseaddr;
+       *len = gfxmem_banks[0]->allocated;
+       return gfxmem_banks[0]->baseaddr;
 }
 
 void restore_fram (int len, size_t filepos, int num)
 {
-       if (num) {
-               fast2_filepos = filepos;
-               changed_prefs.fastmem2_size = len;
-       } else {
-               fast_filepos = filepos;
-               changed_prefs.fastmem_size = len;
-       }
-}
-
-static void restore_fram2 (int len, size_t filepos)
-{
-       fast2_filepos = filepos;
-       changed_prefs.fastmem2_size = len;
+       fast_filepos[num] = filepos;
+       changed_prefs.fastmem[num].size = len;
 }
 
 void restore_zram (int len, size_t filepos, int num)
@@ -2534,12 +3380,9 @@ void restore_zram (int len, size_t filepos, int num)
        if (num == -1) {
                z3_fileposchip = filepos;
                changed_prefs.z3chipmem_size = len;
-       } else if (num == 1) {
-               z3_filepos2 = filepos;
-               changed_prefs.z3fastmem2_size = len;
        } else {
-               z3_filepos = filepos;
-               changed_prefs.z3fastmem_size = len;
+               z3_filepos[num] = filepos;
+               changed_prefs.z3fastmem[num].size = len;
        }
 }
 
@@ -2556,27 +3399,79 @@ uae_u8 *save_expansion (int *len, uae_u8 *dstptr)
                dst = dstbak = dstptr;
        else
                dstbak = dst = xmalloc (uae_u8, 6 * 4);
-       save_u32 (fastmem_bank.start);
-       save_u32 (z3fastmem_bank.start);
-       save_u32 (gfxmem_bank.start);
+       save_u32 (fastmem_bank[0].start);
+       save_u32 (z3fastmem_bank[0].start);
+       save_u32 (gfxmem_banks[0]->start);
        save_u32 (rtarea_base);
-       save_u32 (fastmem_bank.start);
+       save_u32 (fastmem_bank[1].start);
        *len = 4 + 4 + 4 + 4 + 4;
        return dstbak;
 }
 
 uae_u8 *restore_expansion (uae_u8 *src)
 {
-       fastmem_bank.start = restore_u32 ();
-       z3fastmem_bank.start = restore_u32 ();
-       gfxmem_bank.start = restore_u32 ();
+       fastmem_bank[0].start = restore_u32 ();
+       z3fastmem_bank[0].start = restore_u32 ();
+       gfxmem_banks[0]->start = restore_u32 ();
        rtarea_base = restore_u32 ();
-       fastmem2_bank.start = restore_u32 ();
+       fastmem_bank[1].start = restore_u32 ();
        if (rtarea_base != 0 && rtarea_base != RTAREA_DEFAULT && rtarea_base != RTAREA_BACKUP && rtarea_base != RTAREA_BACKUP_2)
                rtarea_base = 0;
        return src;
 }
 
+uae_u8 *save_expansion_info(int *len, uae_u8 *dstptr)
+{
+       uae_u8 *dst, *dstbak;
+       if (dstptr)
+               dst = dstbak = dstptr;
+       else
+               dstbak = dst = xmalloc(uae_u8, 100 + MAX_EXPANSION_BOARD_SPACE * 100);
+       save_u32(1);
+       save_u32(0);
+       save_u32(cardno);
+       for (int i = 0; i < cardno; i++) {
+               struct card_data *ec = cards[i];
+               if (ec->rc) {
+                       save_u32(ec->rc->back->device_type);
+                       save_u32(ec->rc->back->device_num);
+                       save_string(ec->rc->romfile);
+                       save_string(ec->rc->romident);
+               } else {
+                       save_u32(0xffffffff);
+               }
+               save_u32(ec->base);
+               save_u32(ec->size);
+               save_u32(ec->flags);
+               save_string(ec->name);
+       }
+       save_u32(0);
+       *len = dst - dstbak;
+       return dstbak;
+}
+
+uae_u8 *restore_expansion_info(uae_u8 *src)
+{
+       if (restore_u32() != 1)
+               return src;
+       restore_u32();
+       int num = restore_u32();
+       for (int i = 0; i < num; i++) {
+               int romtype = restore_u32();
+               if (romtype != 0xffffffff) {
+                       restore_u32();
+                       restore_string();
+                       restore_string();
+               }
+               restore_u32();
+               restore_u32();
+               restore_u32();
+               restore_string();
+       }
+       restore_u32();
+       return src;
+}
+
 #endif /* SAVESTATE */
 
 #if 0
@@ -2907,6 +3802,16 @@ static const struct expansionboardsettings x86_bridge_sidecar_settings[] = {
        }
 };
 
+static const struct expansionboardsettings toccata_soundcard_settings[] = {
+       {
+               _T("Paula/CD audio mixer"),
+               _T("mixer"),
+       },
+       {
+               NULL
+       }
+};
+
 static const struct expansionboardsettings x86_athdxt_settings[] = {
        {
                _T("ROM Address\0") _T("0xCC000\0") _T("0xDC000\0") _T("0xEC000\0"),
@@ -3032,6 +3937,9 @@ const struct expansionromtype expansionroms[] = {
                NULL, 0,
                false, EXPANSIONTYPE_SCSI | EXPANSIONTYPE_IDE
        },
+
+       /* PCI Bridgeboards */
+
        {
                _T("grex"), _T("G-REX"), _T("DCE"),
                grex_init, NULL, NULL, ROMTYPE_GREX | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_BEFORE, true,
@@ -3040,7 +3948,7 @@ const struct expansionromtype expansionroms[] = {
        },
        {
                _T("mediator"), _T("Mediator"), _T("Elbox"),
-               mediator_init, mediator_init2, NULL, ROMTYPE_MEDIATOR | ROMTYPE_NOT, 0, 0, BOARD_AUTOCONFIG_Z3, false,
+               mediator_init, mediator_init2, NULL, ROMTYPE_MEDIATOR | ROMTYPE_NOT, 0, 0, BOARD_AUTOCONFIG_Z2, false,
                mediator_sub, 0,
                false, EXPANSIONTYPE_PCI_BRIDGE,
                0, 0, 0, false, NULL,
@@ -3056,6 +3964,9 @@ const struct expansionromtype expansionroms[] = {
                false,
                bridge_settings
        },
+
+       /* SCSI/IDE expansion */
+
        {
                _T("apollo"), _T("Apollo 500/2000"), _T("3-State"),
                apollo_init_hd, NULL, apollo_add_scsi_unit, ROMTYPE_APOLLOHD, 0, 0, BOARD_AUTOCONFIG_Z2, false,
@@ -3071,7 +3982,7 @@ const struct expansionromtype expansionroms[] = {
                8498, 27, 0, true, NULL
        },
        {
-               _T("blizzardscsikitiv"), _T("SCSI Kit IV"), _T("Blizzard"),
+               _T("blizzardscsikitiv"), _T("SCSI Kit IV"), _T("Phase 5"),
                NULL, NULL, cpuboard_ncr9x_add_scsi_unit, ROMTYPE_BLIZKIT4, 0, 0, 0, true,
                NULL, 0,
                false, EXPANSIONTYPE_SCSI
@@ -3116,7 +4027,7 @@ const struct expansionromtype expansionroms[] = {
                a2091_init, NULL, a2091_add_scsi_unit, ROMTYPE_A2091 | ROMTYPE_NONE, 0, 0, BOARD_AUTOCONFIG_Z2, false,
                a2091_sub, 1,
                true, EXPANSIONTYPE_SCSI | EXPANSIONTYPE_CUSTOM_SECONDARY,
-               0, 0, 0, true, NULL
+               commodore, commodore_a2091, 0, true, NULL
        },
        {
                _T("a4091"), _T("A4091"), _T("Commodore"),
@@ -3373,6 +4284,8 @@ const struct expansionromtype expansionroms[] = {
                x86_athdxt_settings
        },
 
+       /* PC Bridgeboards */
+
        {
                _T("a1060"), _T("A1060 Sidecar"), _T("Commodore"),
                a1060_init, NULL, NULL, ROMTYPE_A1060 | ROMTYPE_NONE, 0, 0, BOARD_AUTOCONFIG_Z2, true,
@@ -3424,13 +4337,133 @@ const struct expansionromtype expansionroms[] = {
                _T("picassoiv"), _T("Picasso IV"), _T("Village Tronic"),
                NULL, NULL, NULL, ROMTYPE_PICASSOIV | ROMTYPE_NONE, 0, 0, BOARD_IGNORE, true,
                NULL, 0,
-               false, EXPANSIONTYPE_RTG,
+               false, EXPANSIONTYPE_RTG
        },
        {
                _T("x86vga"), _T("x86 VGA"), _T("x86"),
                NULL, NULL, NULL, ROMTYPE_x86_VGA | ROMTYPE_NONE, 0, 0, BOARD_IGNORE, true,
                NULL, 0,
-               false, EXPANSIONTYPE_RTG,
+               false, EXPANSIONTYPE_RTG
+       },
+
+       /* Sound Cards */
+
+       {
+               _T("toccata"), _T("Toccata"), _T("MacroSystem"),
+               sndboard_init, NULL, NULL, ROMTYPE_TOCCATA | ROMTYPE_NOT, 0, 0, BOARD_AUTOCONFIG_Z2, true,
+               NULL, 0,
+               false, EXPANSIONTYPE_SOUND,
+               0, 0, 0, false, NULL,
+               false, toccata_soundcard_settings,
+               { 0xc1, 12, 0, 0, 18260 >> 8, 18260 & 255 }
+       },
+       {
+               _T("es1370"), _T("ES1370 PCI"), _T("Ensoniq"),
+               pci_expansion_init, NULL, NULL, ROMTYPE_ES1370 | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_BEFORE, true,
+               NULL, 0,
+               false, EXPANSIONTYPE_SOUND
+       },
+       {
+               _T("fm801"), _T("FM801 PCI"), _T("Fortemedia"),
+               pci_expansion_init, NULL, NULL, ROMTYPE_FM801 | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_BEFORE, true,
+               NULL, 0,
+               false, EXPANSIONTYPE_SOUND
+       },
+       {
+               _T("uaesnd_z2"), _T("UAESND Z2"), NULL,
+               uaesndboard_init_z2, NULL, NULL, ROMTYPE_UAESNDZ2 | ROMTYPE_NOT, 0, 0, BOARD_AUTOCONFIG_Z2, true,
+               NULL, 0,
+               false, EXPANSIONTYPE_SOUND,
+               0, 0, 0, false, NULL,
+               false, NULL,
+               { 0xc1, 2, 0x00, 0x00, 6502 >> 8, 6502 & 255, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
+       },
+       {
+               _T("uaesnd_z3"), _T("UAESND Z3"), NULL,
+               uaesndboard_init_z3, NULL, NULL, ROMTYPE_UAESNDZ3 | ROMTYPE_NOT, 0, 0, BOARD_AUTOCONFIG_Z3, true,
+               NULL, 0,
+               false, EXPANSIONTYPE_SOUND,
+               0, 0, 0, false, NULL,
+               false, NULL,
+               { 0x80, 2, 0x10, 0x00, 6502 >> 8, 6502 & 255, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
+       },
+
+               /* Network */
+       {
+               _T("a2065"), _T("A2065"), _T("Commodore"),
+               a2065_init, NULL, NULL, ROMTYPE_A2065 | ROMTYPE_NOT, 0, 0, BOARD_AUTOCONFIG_Z2, true,
+               NULL, 0,
+               false, EXPANSIONTYPE_NET
+       },
+       {
+               _T("ne2000_pcmcia"), _T("NE2000 PCMCIA"), NULL,
+               gayle_init_ne2000_pcmcia, NULL, NULL, ROMTYPE_NE2KPCMCIA | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_BEFORE, true,
+               NULL, 0,
+               false, EXPANSIONTYPE_NET
+       },
+       {
+               _T("ne2000_pci"), _T("NE2000 PCI"), NULL,
+               pci_expansion_init, NULL, NULL, ROMTYPE_NE2KPCI | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_BEFORE, true,
+               NULL, 0,
+               false, EXPANSIONTYPE_NET
+       },
+
+               /* Catweasel */
+       {
+               _T("catweasel"), _T("Catweasel"), _T("Individual Computers"),
+               expamem_init_catweasel, NULL, NULL, ROMTYPE_CATWEASEL | ROMTYPE_NOT, 0, 0, BOARD_AUTOCONFIG_Z2, true,
+               NULL, 0,
+               false, EXPANSIONTYPE_FLOPPY
+       },
+
+               /* built-in controllers */
+       {
+               _T("cd32fmv"), _T("CD32 FMV"), _T("Commodore"),
+               expamem_init_cd32fmv, NULL, NULL, ROMTYPE_CD32CART, 0, 0, BOARD_AUTOCONFIG_Z2, true,
+               NULL, 0,
+               false, EXPANSIONTYPE_INTERNAL
+       },
+       {
+               _T("cdtvdmac"), _T("CDTV DMAC"), _T("Commodore"),
+               cdtv_init, NULL, NULL, ROMTYPE_CDTVDMAC | ROMTYPE_NOT, 0, 0, BOARD_AUTOCONFIG_Z2, true,
+               NULL, 0,
+               false, EXPANSIONTYPE_INTERNAL
+       },
+       {
+               _T("cdtvscsi"), _T("CDTV SCSI"), _T("Commodore"),
+               cdtvscsi_init, NULL, cdtv_add_scsi_unit, ROMTYPE_CDTVSCSI | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_AFTER_Z2, true,
+               NULL, 0,
+               false, EXPANSIONTYPE_INTERNAL | EXPANSIONTYPE_SCSI
+       },
+       {
+               _T("cdtvcr"), _T("CDTV-CR"), _T("Commodore"),
+               cdtvcr_init, NULL, NULL, ROMTYPE_CDTVCR | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_AFTER_Z2, true,
+               NULL, 0,
+               false, EXPANSIONTYPE_INTERNAL
+       },
+       {
+               _T("scsi_a3000"), _T("A3000 SCSI"), _T("Commodore"),
+               a3000scsi_init, NULL, a3000_add_scsi_unit, ROMTYPE_SCSI_A3000 | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_AFTER_Z2, true,
+               NULL, 0,
+               false, EXPANSIONTYPE_INTERNAL | EXPANSIONTYPE_SCSI
+       },
+       {
+               _T("scsi_a4000t"), _T("A4000T SCSI"), _T("Commodore"),
+               a4000t_scsi_init, NULL, a4000t_add_scsi_unit, ROMTYPE_SCSI_A4000T | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_BEFORE, true,
+               NULL, 0,
+               false, EXPANSIONTYPE_INTERNAL | EXPANSIONTYPE_SCSI
+       },
+       {
+               _T("ide_mb"), _T("A600/A1200/A4000 IDE"), _T("Commodore"),
+               gayle_ide_init, NULL, gayle_add_ide_unit, ROMTYPE_MB_IDE | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_BEFORE, true,
+               NULL, 0,
+               false, EXPANSIONTYPE_INTERNAL | EXPANSIONTYPE_IDE
+       },
+       {
+               _T("pcmcia_mb"), _T("A600/A1200 PCMCIA"), _T("Commodore"),
+               gayle_pcmcia_init, NULL, gayle_add_pcmcia_unit, ROMTYPE_MB_PCMCIA | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_BEFORE, true,
+               NULL, 0,
+               false, EXPANSIONTYPE_INTERNAL
        },
 
 
index 0fa57b203213e884678d9833266f0e9e7f8d865b..be23a9edcdbd65acae8f6c371c08c08413fedc6f 100644 (file)
@@ -88,18 +88,19 @@ our_seglist:
        dc.l 0                                                                  ; 8 /* NextSeg */
 start:
        bra.s startjmp
-       dc.w 11                                         ;0 12
+       dc.w 12                                         ;0 12
 startjmp:
-       bra.w filesys_mainloop          ;1 16
-       dc.l make_dev-start                     ;2 20
-       dc.l filesys_init-start         ;3 24
-       dc.l moverom-start              ;4 28
-       dc.l bootcode-start                     ;5 32
-       dc.l setup_exter-start          ;6 36
-       dc.l bcplwrapper-start ;7 40
-       dc.l afterdos-start     ;8 44
-       dc.l hwtrap_install-start ;9 48
-       dc.l hwtrap_entry-start ; 10 52
+       bra.w filesys_mainloop          ;  1 16
+       dc.l make_dev-start                             ;  2 20
+       dc.l filesys_init-start         ;  3 24
+       dc.l moverom-start                              ;  4 28
+       dc.l bootcode-start                             ;  5 32
+       dc.l setup_exter-start          ;  6 36
+       dc.l bcplwrapper-start          ;  7 40
+       dc.l afterdos-start                             ;  8 44
+       dc.l hwtrap_install-start ;  9 48
+       dc.l hwtrap_entry-start         ; 10 52
+       dc.l keymaphack-start                   ; 11 56
 
 bootcode:
        lea.l doslibname(pc),a1
@@ -3791,6 +3792,123 @@ moveromreloc:
        dc.w exter_task_wait-start
        dc.w 0
 
+keymaphack:
+       move.l 4.w,a6
+
+       moveq #keymapfunc_end-keymapfunc,d0
+       moveq #1,d1
+       jsr -$c6(a6) ;AllocMem
+       tst.l d0
+       beq.s .keymap0
+       move.l d0,a3
+
+       lea keymapfunc(pc),a0
+       move.l a3,a1
+       moveq #keymapfunc_end-keymapfunc-1,d0
+.keymap1
+       move.b (a0)+,(a1)+
+       dbf d0,.keymap1
+       lea keymapfunc_patch(pc),a0
+       move.l a0,keymap_func_ptr-keymapfunc+2(a3)
+       lea keymapfunc2_patch(pc),a0
+       move.l a0,keymaplibfunc-keymapfunc+2(a3)
+
+       jsr -$84(a6)
+
+       lea 350(a6),a0 ;DeviceList
+       lea con_dev(pc),a1
+       jsr -$114(a6) ;FindName
+       tst.l d0
+       beq.s .keymap2
+       move.l d0,a1
+       move.l a3,d0
+       move.w #-$1e,a0 ;BeginIO
+       jsr -$1a4(a6)
+       move.l d0,keymap_original-keymapfunc(a3)
+.keymap2
+
+       lea 378(a6),a0 ;LibList
+       lea key_lib(pc),a1
+       jsr -$114(a6) ;FindName
+       tst.l d0
+       beq.s .keymap3
+       move.l d0,a1
+       lea keymaplibfunc-keymapfunc(a3),a0
+       move.l a0,d0
+       move.w #-$1e,a0 ;SetKeyMapDefault
+       jsr -$1a4(a6)
+       move.l d0,keymap_original2-keymapfunc(a3)
+.keymap3
+
+       jsr -$8a(a6)
+
+.keymap0       
+       rts
+
+keymapfunc
+       cmp.w #10,28(a1) ;CD_SETKEYMAP
+       beq.s keymap_func_ptr
+       cmp.w #12,28(a1) ;CD_SETDEFAULTKEYMAP
+       bne.s keymapfunc2
+keymap_func_ptr
+       jsr 0.l
+keymapfunc2
+       move.l keymap_original(pc),-(sp)
+       rts
+keymaplibfunc
+       jsr 0.l
+       move.l keymap_original2(pc),-(sp)
+       rts
+keymap_original
+       dc.l 0
+keymap_original2
+       dc.l 0
+keymapfunc_end
+
+       ; a0 = keymap
+keymapfunc2_patch
+       movem.l d0-d7/a0-a6,-(sp)
+       move.l a0,a2
+       bra.s keymapfunc_entry
+
+       ; a1 = request
+keymapfunc_patch
+       movem.l d0-d7/a0-a6,-(sp)
+       move.l 40(a1),a2 ;io_Data
+
+keymapfunc_entry
+       move.l 4.w,a6
+
+       subq.l #8,sp
+       move.l sp,a4
+
+       move.l a4,-(sp) ; &size
+       move.l a2,-(sp)
+       bsr.w GetKeyMapData
+       addq.l #8,sp
+       tst.l d0
+       beq.s .keymap0
+       move.l d0,d2
+
+       move.w #$ff38,d0
+       bsr.w getrtbase
+
+       moveq #21,d1
+       move.l d2,a1 ; a1 = data
+       move.l (a4),d0 ; d0 = size
+       jsr (a0)
+
+       move.l d2,a1
+       move.l (a4),d0
+       jsr -$d2(a6) ;FreeMem
+
+.keymap0
+       addq.l #8,sp
+       movem.l (sp)+,d0-d7/a0-a6
+       rts
+
+       include "filesys_helpers.asm"
+
        cnop 0,4
 getrtbaselocal:
        lea start-8-4(pc),a0
@@ -3809,6 +3927,7 @@ getrtbase:
 inp_dev: dc.b 'input.device',0
 tim_dev: dc.b 'timer.device',0
 con_dev: dc.b 'console.device',0
+key_lib: dc.b 'keymap.library',0
 devsn_name: dc.b 'DEVS',0
 devs_name: dc.b 'DEVS:',0
 clip_name: dc.b 'DEVS:clipboard.device',0
index d6d8dcecbe4971cb36ce4709ab293f1885fe6849..9709624afa0a1ce31b081a840704c29a65900edb 100644 (file)
@@ -138,6 +138,7 @@ static uaecptr bootrom_start;
 static uae_u32 fsdevname, fshandlername, filesys_configdev;
 static uae_u32 cdfs_devname, cdfs_handlername;
 static uaecptr afterdos_name, afterdos_id, afterdos_initcode;
+static uaecptr keymaphook_name, keymaphook_id, keymaphook_initcode;
 static uaecptr shell_execute_data, shell_execute_process;
 static int filesys_in_interrupt;
 static uae_u32 mountertask;
@@ -848,55 +849,10 @@ static void add_cpuboard_unit_init(void)
        }
 }
 
-
-static bool ismainboardide(void)
-{
-       return currprefs.cs_ide != 0;
-}
-static bool isa3000scsi(void)
-{
-       return currprefs.cs_mbdmac == 1;
-}
-static bool isa4000tscsi(void)
-{
-       return currprefs.cs_mbdmac == 2;
-}
-static bool iscdtvscsi(void)
-{
-       return currprefs.cs_cdtvscsi != 0;
-}
-// this needs better implementation.
-static void add_mainboard_unit_init(void)
-{
-       if (ismainboardide()) {
-               write_log(_T("Initializing mainboard IDE\n"));
-               gayle_add_ide_unit(-1, NULL);
-       }
-       if (isa3000scsi()) {
-               write_log(_T("Initializing A3000 mainboard SCSI\n"));
-               a3000_add_scsi_unit(-1, NULL, NULL);
-       }
-       if (isa4000tscsi()) {
-               write_log(_T("Initializing A4000T mainboard SCSI\n"));
-               a4000t_add_scsi_unit(-1, NULL, NULL);
-       }
-       if (iscdtvscsi()) {
-               write_log(_T("Initializing CDTV SCSI expansion\n"));
-               cdtv_add_scsi_unit(-1, NULL, NULL);
-       }
-}
-
 static bool add_ide_unit(int type, int unit, struct uaedev_config_info *uci)
 {
        bool added = false;
-       if (type == HD_CONTROLLER_TYPE_IDE_MB) {
-               if (ismainboardide()) {
-                       write_log(_T("Adding mainboard IDE %s unit %d ('%s')\n"),
-                               getunittype(uci), unit, uci->rootdir);
-                       gayle_add_ide_unit(unit, uci);
-                       added = true;
-               }
-       } else if (type >= HD_CONTROLLER_TYPE_IDE_EXPANSION_FIRST && type <= HD_CONTROLLER_TYPE_IDE_LAST) {
+       if (type >= HD_CONTROLLER_TYPE_IDE_EXPANSION_FIRST && type <= HD_CONTROLLER_TYPE_IDE_LAST) {
                for (int i = 0; expansionroms[i].name; i++) {
                        if (i == type - HD_CONTROLLER_TYPE_IDE_EXPANSION_FIRST) {
                                const struct expansionromtype *ert = &expansionroms[i];
@@ -920,34 +876,7 @@ static bool add_ide_unit(int type, int unit, struct uaedev_config_info *uci)
 static bool add_scsi_unit(int type, int unit, struct uaedev_config_info *uci)
 {
        bool added = false;
-       if (type == HD_CONTROLLER_TYPE_SCSI_A3000) {
-#ifdef A2091
-               if (isa3000scsi()) {
-                       write_log(_T("Adding A3000 mainboard SCSI %s unit %d ('%s')\n"), getunittype(uci),
-                               unit, uci->rootdir);
-                       a3000_add_scsi_unit (unit, uci, NULL);
-                       added = true;
-               }
-#endif
-       } else if (type == HD_CONTROLLER_TYPE_SCSI_A4000T) {
-#ifdef NCR
-               if (isa4000tscsi()) {
-                       write_log(_T("Adding A4000T mainboard SCSI %s unit %d ('%s')\n"), getunittype(uci),
-                               unit, uci->rootdir);
-                       a4000t_add_scsi_unit (unit, uci, NULL);
-                       added = true;
-               }
-#endif
-       } else if (type == HD_CONTROLLER_TYPE_SCSI_CDTV) {
-#ifdef CDTV
-               if (iscdtvscsi()) {
-                       write_log(_T("Adding CDTV SCSI expansion %s unit %d ('%s')\n"), getunittype(uci),
-                               unit, uci->rootdir);
-                       cdtv_add_scsi_unit (unit, uci, NULL);
-                       added = true;
-               }
-#endif
-       } else if (type >= HD_CONTROLLER_TYPE_SCSI_EXPANSION_FIRST && type <= HD_CONTROLLER_TYPE_SCSI_LAST) {
+       if (type >= HD_CONTROLLER_TYPE_SCSI_EXPANSION_FIRST && type <= HD_CONTROLLER_TYPE_SCSI_LAST) {
                for (int i = 0; expansionroms[i].name; i++) {
                        if (i == type - HD_CONTROLLER_TYPE_SCSI_EXPANSION_FIRST) {
                                const struct expansionromtype *ert = &expansionroms[i];
@@ -1026,7 +955,6 @@ static void initialize_mountinfo (void)
        }
 
        // init all controllers first
-       add_mainboard_unit_init();
        add_cpuboard_unit_init();
        for (int i = 0; expansionroms[i].name; i++) {
                const struct expansionromtype *ert = &expansionroms[i];
@@ -1065,12 +993,14 @@ static void initialize_mountinfo (void)
                                if (added)
                                        break;
                        }
-               } else if (type == HD_CONTROLLER_TYPE_PCMCIA_SRAM) {
-                       gayle_add_pcmcia_sram_unit (uci);
-                       added = true;
-               } else if (type == HD_CONTROLLER_TYPE_PCMCIA_IDE) {
-                       gayle_add_pcmcia_ide_unit (uci);
-                       added = true;
+               } else if (type == HD_CONTROLLER_TYPE_PCMCIA) {
+                       if (uci->controller_type_unit == 0) {
+                               gayle_add_pcmcia_sram_unit (uci);
+                               added = true;
+                       } else {
+                               gayle_add_pcmcia_ide_unit (uci);
+                               added = true;
+                       }
                }
                if (added)
                        allocuci (&currprefs, nr, -1);
@@ -2155,10 +2085,11 @@ int filesys_media_change (const TCHAR *rootdir, int inserted, struct uaedev_conf
 
 int hardfile_added (struct uaedev_config_info *ci)
 {
-       if (ci->controller_type == HD_CONTROLLER_TYPE_PCMCIA_IDE) {
-               return gayle_add_pcmcia_ide_unit(ci);
-       } else if (ci->controller_type == HD_CONTROLLER_TYPE_PCMCIA_SRAM) {
-               return gayle_add_pcmcia_sram_unit(ci);
+       if (ci->controller_type == HD_CONTROLLER_TYPE_PCMCIA) {
+               if (ci->controller_type_unit == 1)
+                       return gayle_add_pcmcia_ide_unit(ci);
+               if (ci->controller_type_unit == 0)
+                       return gayle_add_pcmcia_sram_unit(ci);
        }
        return 0;
 }
@@ -3349,12 +3280,16 @@ static void     do_info(TrapContext *ctx, Unit *unit, dpacket *packet, uaecptr info,
                uae_s64 numblocks = 0;
                while (blocksize < 32768 || numblocks == 0) {
                        numblocks = fsu.total / blocksize;
+                       if (numblocks <= 10)
+                               numblocks = 10;
                        if (numblocks <= 0x7fffffff)
                                break;
                        blocksize *= 2;
                }
-               uae_s64 inuse = (fsu.total - fsu.avail + blocksize - 1) / blocksize;
-
+               uae_s64 inuse = (numblocks * blocksize - fsu.avail) / blocksize;
+               if (inuse > numblocks)
+                       inuse = numblocks;
+               //write_log(_T("total %lld avail %lld Blocks %lld Inuse %lld blocksize %d\n"), fsu.total, fsu.avail, numblocks, inuse, blocksize);
                put_long_host(buf + 12, (uae_u32)numblocks); /* numblocks */
                put_long_host(buf + 16, (uae_u32)inuse); /* inuse */
                put_long_host(buf + 20, blocksize); /* bytesperblock */
@@ -7451,8 +7386,8 @@ static uae_u32 REGPARAM2 filesys_diagentry (TrapContext *ctx)
        * here.
        * We can simply add more Resident structures here. Although the Amiga OS
        * only knows about the one at address DiagArea + 0x10, we scan for other
-       * Resident structures and call InitResident() for them at the end of the
-       * diag entry. */
+       * Resident structures and inject them to ResList in priority order
+       */
 
        if (kickstart_version >= 37) {
                trap_put_word(ctx, resaddr + 0x0, 0x4afc);
@@ -7485,26 +7420,22 @@ static uae_u32 REGPARAM2 filesys_diagentry (TrapContext *ctx)
 #ifdef WITH_TABLETLIBRARY
        resaddr = tabletlib_startup(ctx, resaddr);
 #endif
-
-       last_resident = resaddr;
-#if 0
-       /* scan for Residents and return pointer to array of them */
-       tmp = first_resident;
-       while (tmp < last_resident && tmp >= first_resident) {
-               if (trap_get_word(ctx, tmp) == 0x4AFC &&
-                       trap_get_long(ctx, tmp + 0x2) == tmp) {
-                               trap_put_word(ctx, resaddr, 0x227C);         /* move.l #tmp,a1 */
-                               trap_put_long(ctx, resaddr + 2, tmp);
-                               trap_put_word(ctx, resaddr + 6, 0x7200);     /* moveq #0,d1 */
-                               trap_put_long(ctx, resaddr + 8, 0x4EAEFF9A); /* jsr -$66(a6) ; InitResident */
-                               resaddr += 12;
-                               tmp = trap_get_long(ctx, tmp + 0x6);
-               } else {
-                       tmp += 2;
-               }
+#ifdef RETROPLATFORM
+       if (rp_isactive()) {
+               trap_put_word(ctx, resaddr + 0x0, 0x4afc);
+               trap_put_long(ctx, resaddr + 0x2, resaddr);
+               trap_put_long(ctx, resaddr + 0x6, resaddr + 0x1A);
+               trap_put_word(ctx, resaddr + 0xA, 0x0100); /* RTF_COLDSTART; Version 0 */
+               trap_put_word(ctx, resaddr + 0xC, 0x0000); /* NT_UNKNOWN; pri */
+               trap_put_long(ctx, resaddr + 0xE, keymaphook_name);
+               trap_put_long(ctx, resaddr + 0x12, keymaphook_id);
+               trap_put_long(ctx, resaddr + 0x16, keymaphook_initcode);
+               resaddr += 0x1A;
        }
 #endif
 
+       last_resident = resaddr;
+
        /* call setup_exter */
        trap_put_word(ctx, resaddr +  0, 0x7000 | (currprefs.uaeboard > 1 ? 3 : 1)); /* moveq #x,d0 */
        trap_put_word(ctx, resaddr +  2, 0x2079); /* move.l RTAREA_BASE+setup_exter,a0 */
@@ -7637,7 +7568,6 @@ static uae_u32 REGPARAM2 filesys_diagentry (TrapContext *ctx)
                }
        }
 
-#if 1
        tmp = first_resident;
        while (tmp < last_resident && tmp >= first_resident) {
                if (trap_get_word(ctx, tmp) == 0x4AFC && trap_get_long(ctx, tmp + 0x2) == tmp) {
@@ -7647,8 +7577,6 @@ static uae_u32 REGPARAM2 filesys_diagentry (TrapContext *ctx)
                        tmp += 2;
                }
        }
-#endif
-       //activate_debugger();
 
        return 1;
 }
@@ -8727,6 +8655,12 @@ static uae_u32 REGPARAM2 mousehack_done (TrapContext *ctx)
        } else if (mode == 20) {
                // boot rom copy done
                return boot_rom_copy(ctx, trap_get_dreg(ctx, 2), 1);
+       } else if (mode == 21) {
+               // keymap hook
+#ifdef RETROPLATFORM
+               rp_keymap(ctx, trap_get_areg(ctx, 1), trap_get_dreg(ctx, 0));
+#endif
+               return 1;
        } else if (mode == 101) {
                consolehook_ret(ctx, trap_get_areg(ctx, 1), trap_get_areg(ctx, 2));
        } else if (mode == 102) {
@@ -8845,11 +8779,16 @@ void filesys_install (void)
 
        fsdevname = ds_ansi ("uae.device"); /* does not really exist */
        fshandlername = ds_bstr_ansi ("uaefs");
+
        cdfs_devname = ds_ansi ("uaescsi.device");
        cdfs_handlername = ds_bstr_ansi ("uaecdfs");
+
        afterdos_name = ds_ansi("UAE afterdos");
        afterdos_id = ds_ansi("UAE afterdos 0.1");
 
+       keymaphook_name = ds_ansi("UAE keymaphook");
+       keymaphook_id = ds_ansi("UAE keymaphook 0.1");
+
        ROM_filesys_diagentry = here ();
        calltrap (deftrap2 (filesys_diagentry, 0, _T("filesys_diagentry")));
        dw(0x4ED0); /* JMP (a0) - jump to code that inits Residents */
@@ -8939,6 +8878,7 @@ void filesys_install_code (void)
        b = bootrom_start + bootrom_header + 3 * 4 - 4;
        filesys_initcode = bootrom_start + dlg (b) + bootrom_header - 4;
        afterdos_initcode = filesys_get_entry(8);
+       keymaphook_initcode = filesys_get_entry(11);
 }
 
 #ifdef _WIN32
index f1ec854a937c9068943f0b30dba0ff638ea178f8..e6ddcc7a6386affef154007c306094200c32251f 100644 (file)
  db(0x00); db(0x00); db(0x00); db(0x10); db(0x00); db(0x00); db(0x00); db(0x00);
- db(0x60); db(0x02); db(0x00); db(0x0b); db(0x60); db(0x00); db(0x0d); db(0xfa);
- db(0x00); db(0x00); db(0x0b); db(0x60); db(0x00); db(0x00); db(0x00); db(0xa8);
- db(0x00); db(0x00); db(0x20); db(0xba); db(0x00); db(0x00); db(0x00); db(0x2c);
- db(0x00); db(0x00); db(0x05); db(0xba); db(0x00); db(0x00); db(0x1c); db(0xc0);
- db(0x00); db(0x00); db(0x00); db(0x64); db(0x00); db(0x00); db(0x1d); db(0x1c);
- db(0x00); db(0x00); db(0x1d); db(0x6e); db(0x43); db(0xfa); db(0x22); db(0x8b);
- db(0x4e); db(0xae); db(0xff); db(0xa0); db(0x20); db(0x40); db(0x20); db(0x28);
- db(0x00); db(0x16); db(0x20); db(0x40); db(0x4e); db(0x90); db(0x4e); db(0x75);
- db(0x00); db(0x00); db(0x00); db(0x07); db(0x00); db(0x00); db(0x00); db(0x00);
- db(0x00); db(0x00); db(0x00); db(0x07); db(0xe5); db(0x89); db(0x2e); db(0x01);
- db(0x60); db(0x00); db(0x0d); db(0xb0); db(0x00); db(0x00); db(0x00); db(0x00);
- db(0x00); db(0x00); db(0x00); db(0x01); db(0x00); db(0x00); db(0x00); db(0x04);
- db(0x00); db(0x00); db(0x00); db(0x02); db(0x48); db(0xe7); db(0x3f); db(0x3e);
- db(0x2c); db(0x78); db(0x00); db(0x04); db(0x43); db(0xfa); db(0x22); db(0x69);
- db(0x70); db(0x00); db(0x4e); db(0xae); db(0xfd); db(0xd8); db(0x22); db(0x00);
- db(0x30); db(0x3c); db(0x3f); db(0xf8); db(0x61); db(0x00); db(0x21); db(0x16);
- db(0x20); db(0x81); db(0x43); db(0xfa); db(0x22); db(0x41); db(0x70); db(0x00);
- db(0x4e); db(0xae); db(0xfd); db(0xd8); db(0x22); db(0x00); db(0x30); db(0x3c);
- db(0x3f); db(0xf4); db(0x61); db(0x00); db(0x21); db(0x00); db(0x20); db(0x81);
- db(0x61); db(0x00); db(0x16); db(0x8c); db(0x61); db(0x00); db(0x1a); db(0x54);
- db(0x4c); db(0xdf); db(0x7c); db(0xfc); db(0x70); db(0x00); db(0x4e); db(0x75);
- db(0x48); db(0xe7); db(0xff); db(0xfe); db(0x2c); db(0x78); db(0x00); db(0x04);
- db(0x30); db(0x3c); db(0xff); db(0xec); db(0x61); db(0x00); db(0x20); db(0xde);
- db(0x2a); db(0x50); db(0x7a); db(0x00); db(0x70); db(0x00); db(0x0c); db(0x6e);
- db(0x00); db(0x21); db(0x00); db(0x14); db(0x65); db(0x1c); db(0x43); db(0xfa);
- db(0x22); db(0x20); db(0x70); db(0x24); db(0x7a); db(0x01); db(0x4e); db(0xae);
- db(0xfd); db(0xd8); db(0x4a); db(0x80); db(0x66); db(0x0c); db(0x43); db(0xfa);
- db(0x22); db(0x10); db(0x70); db(0x00); db(0x7a); db(0x00); db(0x4e); db(0xae);
- db(0xfd); db(0xd8); db(0x28); db(0x40); db(0xc9); db(0x4e); db(0x20); db(0x0e);
- db(0x67); db(0x3c); db(0x08); db(0x2d); db(0x00); db(0x04); db(0x01); db(0x13);
- db(0x66); db(0x34); db(0x4e); db(0xae); db(0xff); db(0xd0); db(0x4a); db(0x80);
- db(0x67); db(0x2c); db(0x20); db(0x40); db(0x43); db(0xfa); db(0xff); db(0x02);
- db(0x20); db(0x09); db(0x42); db(0x40); db(0x21); db(0x40); db(0x00); db(0x20);
- db(0x21); db(0x7c); db(0x00); db(0x01); db(0x00); db(0x00); db(0x00); db(0x24);
- db(0x31); db(0x7c); db(0x01); db(0x04); db(0x00); db(0x10); db(0x31); db(0x7c);
- db(0x07); db(0xdb); db(0x00); db(0x14); db(0x70); db(0x01); db(0x21); db(0x40);
- db(0x00); db(0x16); db(0x4e); db(0xae); db(0xff); db(0xe2); db(0xc9); db(0x4e);
- db(0x4a); db(0xad); db(0x01); db(0x0c); db(0x67); db(0x00); db(0x00); db(0x62);
- db(0x20); db(0x3c); db(0x00); db(0x00); db(0x02); db(0x38); db(0x22); db(0x3c);
- db(0x00); db(0x01); db(0x00); db(0x01); db(0x4e); db(0xae); db(0xff); db(0x3a);
- db(0x26); db(0x40); db(0x27); db(0x4c); db(0x01); db(0xa8); db(0x7c); db(0x00);
- db(0xbc); db(0x6d); db(0x01); db(0x0e); db(0x64); db(0x32); db(0x2f); db(0x06);
- db(0x2e); db(0x2d); db(0x01); db(0x10); db(0x4a); db(0x45); db(0x67); db(0x04);
- db(0x08); db(0xc7); db(0x00); db(0x02); db(0x2f); db(0x0b); db(0x20); db(0x4b);
- db(0x61); db(0x00); db(0x09); db(0xfe); db(0x26); db(0x5f); db(0x27); db(0x41);
- db(0x01); db(0xa4); db(0x0c); db(0x80); db(0xff); db(0xff); db(0xff); db(0xfe);
- db(0x67); db(0x08); db(0x48); db(0x46); db(0x52); db(0x46); db(0x48); db(0x46);
- db(0x60); db(0xd6); db(0x2c); db(0x1f); db(0x52); db(0x46); db(0x60); db(0xc8);
- db(0x2c); db(0x78); db(0x00); db(0x04); db(0x22); db(0x4b); db(0x20); db(0x3c);
- db(0x00); db(0x00); db(0x02); db(0x38); db(0x4e); db(0xae); db(0xff); db(0x2e);
- db(0x2c); db(0x78); db(0x00); db(0x04); db(0x20); db(0x0c); db(0x67); db(0x06);
- db(0x22); db(0x4c); db(0x4e); db(0xae); db(0xfe); db(0x62); db(0x0c); db(0x6e);
- db(0x00); db(0x22); db(0x00); db(0x14); db(0x65); db(0x00); db(0x00); db(0x9e);
- db(0x78); db(0x03); db(0x0c); db(0x6e); db(0x00); db(0x24); db(0x00); db(0x14);
- db(0x65); db(0x04); db(0x00); db(0x44); db(0x01); db(0x00); db(0x30); db(0x3c);
- db(0xff); db(0x80); db(0x61); db(0x00); db(0x1f); db(0xd8); db(0x4e); db(0x90);
- db(0x2a); db(0x00); db(0x20); db(0x49); db(0x20); db(0x01); db(0x67); db(0x0c);
- db(0x22); db(0x04); db(0x74); db(0xfb); db(0x43); db(0xfa); db(0x21); db(0x40);
- db(0x4e); db(0xae); db(0xfd); db(0x96); db(0x0c); db(0x85); db(0x00); db(0x40);
- db(0x00); db(0x00); db(0x65); db(0x26); db(0xba); db(0xae); db(0x00); db(0x3e);
- db(0x67); db(0x20); db(0x4e); db(0xae); db(0xff); db(0x88); db(0x2d); db(0x45);
- db(0x00); db(0x3e); db(0x70); db(0x00); db(0x72); db(0x17); db(0x41); db(0xee);
- db(0x00); db(0x22); db(0xd0); db(0x58); db(0x51); db(0xc9); db(0xff); db(0xfc);
- db(0x46); db(0x40); db(0x3d); db(0x40); db(0x00); db(0x52); db(0x4e); db(0xae);
- db(0xff); db(0x82); db(0x43); db(0xf9); db(0x00); db(0x21); db(0x00); db(0x00);
- db(0x4e); db(0xae); db(0xfd); db(0xea); db(0x4a); db(0x80); db(0x66); db(0x18);
- db(0x22); db(0x04); db(0x74); db(0xf6); db(0x20); db(0x7c); db(0x00); db(0x20);
- db(0x00); db(0x00); db(0x20); db(0x05); db(0x90); db(0x88); db(0x65); db(0x08);
- db(0x67); db(0x06); db(0x93); db(0xc9); db(0x4e); db(0xae); db(0xfd); db(0x96);
- db(0x41); db(0xfa); db(0x20); db(0x38); db(0x43); db(0xfa); db(0x00); db(0x5a);
- db(0x70); db(0x0a); db(0x61); db(0x00); db(0x0f); db(0x40); db(0x22); db(0x40);
- db(0x72); db(0x01); db(0x30); db(0x3c); db(0xff); db(0x48); db(0x61); db(0x00);
- db(0x1f); db(0x54); db(0x4e); db(0x90); db(0x4c); db(0xdf); db(0x7f); db(0xff);
- db(0x4e); db(0x75); db(0x48); db(0xe7); db(0x3c); db(0x22); db(0x7a); db(0x00);
- db(0x2c); db(0x78); db(0x00); db(0x04); db(0x24); db(0x00); db(0x28); db(0x01);
- db(0x26); db(0x09); db(0x24); db(0x48); db(0x43); db(0xfa); db(0x20); db(0x5b);
- db(0x70); db(0x00); db(0x4e); db(0xae); db(0xfd); db(0xd8); db(0x4a); db(0x80);
- db(0x67); db(0x16); db(0x2c); db(0x40); db(0x22); db(0x0a); db(0xe4); db(0x8b);
- db(0x4e); db(0xae); db(0xff); db(0x76); db(0x2a); db(0x00); db(0x22); db(0x4e);
- db(0x2c); db(0x78); db(0x00); db(0x04); db(0x4e); db(0xae); db(0xfe); db(0x62);
- db(0x20); db(0x05); db(0x4c); db(0xdf); db(0x44); db(0x3c); db(0x4e); db(0x75);
- db(0x2c); db(0x78); db(0x00); db(0x04); db(0x70); db(0x00); db(0x08); db(0xc0);
- db(0x00); db(0x0d); db(0x4e); db(0xae); db(0xfe); db(0xc2); db(0x41); db(0xfa);
- db(0x1f); db(0xfb); db(0x43); db(0xfa); db(0x00); db(0x14); db(0x70); db(0x0f);
- db(0x22); db(0x3c); db(0x00); db(0x00); db(0x1f); db(0x40); db(0x61); db(0x00);
- db(0xff); db(0xa2); db(0x60); db(0xdc); db(0x00); db(0x00); db(0x00); db(0x10);
- db(0x00); db(0x00); db(0x00); db(0x00); db(0x72); db(0x02); db(0x30); db(0x3c);
- db(0xff); db(0x48); db(0x61); db(0x00); db(0x1e); db(0xc8); db(0x4e); db(0x90);
- db(0x22); db(0x00); db(0x6b); db(0x04); db(0x61); db(0x00); db(0x0a); db(0x94);
- db(0x70); db(0x00); db(0x4e); db(0x75); db(0x2c); db(0x78); db(0x00); db(0x04);
- db(0x20); db(0x3c); db(0x00); db(0x00); db(0x01); db(0x00); db(0x4e); db(0xae);
- db(0xfe); db(0xc2); db(0x7e); db(0x00); db(0x20); db(0x3c); db(0x00); db(0x00);
- db(0xf0); db(0x00); db(0x61); db(0x00); db(0x1e); db(0xb0); db(0x22); db(0x48);
- db(0x20); db(0x3c); db(0x00); db(0x00); db(0x40); db(0x00); db(0x61); db(0x00);
- db(0x1e); db(0xa4); db(0x7c); db(0x03); db(0x4a); db(0x29); db(0x00); db(0x03);
- db(0x67); db(0x42); db(0x0c); db(0x29); db(0x00); db(0xfd); db(0x00); db(0x07);
- db(0x66); db(0x3a); db(0x52); db(0x87); db(0x49); db(0xe8); db(0x00); db(0x54);
- db(0x4b); db(0xe9); db(0x00); db(0x04); db(0x48); db(0xe7); db(0x03); db(0xce);
- db(0x38); db(0x15); db(0x4c); db(0xd4); db(0x07); db(0x00); db(0x4c); db(0xd4);
- db(0x00); db(0x07); db(0x0c); db(0x44); db(0x00); db(0x12); db(0x66); db(0x06);
- db(0x61); db(0x00); db(0x1d); db(0x1a); db(0x60); db(0x0a); db(0x0c); db(0x44);
- db(0x00); db(0x13); db(0x66); db(0x04); db(0x61); db(0x00); db(0x1d); db(0x28);
- db(0x4c); db(0xdf); db(0x73); db(0xc0); db(0x28); db(0x80); db(0x1b); db(0x7c);
- db(0x00); db(0x02); db(0x00); db(0x03); db(0xd0); db(0xfc); db(0x20); db(0x00);
- db(0xd2); db(0xfc); db(0x00); db(0x08); db(0x51); db(0xce); db(0xff); db(0xae);
- db(0x4a); db(0x87); db(0x67); db(0x00); db(0xff); db(0x84); db(0x60); db(0x00);
- db(0xff); db(0x8a); db(0x2c); db(0x78); db(0x00); db(0x04); db(0x20); db(0x3c);
- db(0x00); db(0x00); db(0x01); db(0x00); db(0x4e); db(0xae); db(0xfe); db(0xc2);
- db(0x61); db(0x04); db(0x60); db(0xf2); db(0x4e); db(0x75); db(0x7e); db(0x0a);
- db(0x30); db(0x3c); db(0xff); db(0x50); db(0x61); db(0x00); db(0x1e); db(0x16);
- db(0x20); db(0x07); db(0x4e); db(0x90); db(0x4a); db(0x80); db(0x67); db(0xec);
- db(0x7e); db(0x0b); db(0x0c); db(0x40); db(0x00); db(0x01); db(0x6d); db(0x00);
- db(0xff); db(0xe8); db(0x6e); db(0x06); db(0x4e); db(0xae); db(0xfe); db(0x92);
- db(0x60); db(0xde); db(0x0c); db(0x40); db(0x00); db(0x02); db(0x6e); db(0x08);
- db(0x20); db(0x01); db(0x4e); db(0xae); db(0xfe); db(0xbc); db(0x60); db(0xd0);
- db(0x0c); db(0x40); db(0x00); db(0x03); db(0x6e); db(0x06); db(0x4e); db(0xae);
- db(0xfe); db(0x86); db(0x60); db(0xc4); db(0x0c); db(0x40); db(0x00); db(0x04);
- db(0x6e); db(0x06); db(0x4e); db(0xae); db(0xff); db(0x4c); db(0x60); db(0xb8);
- db(0x0c); db(0x40); db(0x00); db(0x05); db(0x6e); db(0x46); db(0x48); db(0xe7);
- db(0x00); db(0xc0); db(0x70); db(0x26); db(0x22); db(0x3c); db(0x00); db(0x01);
- db(0x00); db(0x01); db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x4c); db(0xdf);
- db(0x03); db(0x00); db(0x24); db(0x40); db(0x15); db(0x7c); db(0x00); db(0x08);
- db(0x00); db(0x08); db(0x25); db(0x48); db(0x00); db(0x0e); db(0x35); db(0x7c);
- db(0x00); db(0x26); db(0x00); db(0x12); db(0x25); db(0x7c); db(0x40); db(0x00);
- db(0x00); db(0x00); db(0x00); db(0x14); db(0x35); db(0x7c); db(0x12); db(0x34);
- db(0x00); db(0x18); db(0x25); db(0x49); db(0x00); db(0x1a); db(0x20); db(0x69);
- db(0x00); db(0x10); db(0x22); db(0x4a); db(0x4e); db(0xae); db(0xfe); db(0x92);
- db(0x60); db(0x00); db(0xff); db(0x6e); db(0x0c); db(0x40); db(0x00); db(0x06);
- db(0x6e); db(0x00); db(0xff); db(0x66); db(0x41); db(0xfa); db(0x1f); db(0x24);
- db(0x43); db(0xfa); db(0x00); db(0x42); db(0x70); db(0x01); db(0x22); db(0x3c);
- db(0x00); db(0x00); db(0x27); db(0x10); db(0x61); db(0x00); db(0xfe); db(0x34);
- db(0x22); db(0x00); db(0x30); db(0x3c); db(0xff); db(0x50); db(0x61); db(0x00);
- db(0x1d); db(0x64); db(0x70); db(0x14); db(0x4e); db(0x90); db(0x60); db(0x00);
- db(0xff); db(0x40); db(0x70); db(0x00); db(0x20); db(0x59); db(0x4a); db(0x10);
- db(0x67); db(0x10); db(0x2c); db(0x59); db(0x22); db(0x51); db(0x20); db(0x3c);
- db(0x00); db(0x00); db(0x01); db(0x00); db(0x4e); db(0xae); db(0xfe); db(0xbc);
- db(0x70); db(0x01); db(0x4a); db(0x40); db(0x4e); db(0x75); db(0x00); db(0x00);
+ db(0x60); db(0x02); db(0x00); db(0x0c); db(0x60); db(0x00); db(0x0d); db(0xfe);
+ db(0x00); db(0x00); db(0x0b); db(0x64); db(0x00); db(0x00); db(0x00); db(0xac);
+ db(0x00); db(0x00); db(0x20); db(0xbe); db(0x00); db(0x00); db(0x00); db(0x30);
+ db(0x00); db(0x00); db(0x05); db(0xbe); db(0x00); db(0x00); db(0x1c); db(0xc4);
+ db(0x00); db(0x00); db(0x00); db(0x68); db(0x00); db(0x00); db(0x1d); db(0x20);
+ db(0x00); db(0x00); db(0x1d); db(0x72); db(0x00); db(0x00); db(0x21); db(0x88);
+ db(0x43); db(0xfa); db(0x29); db(0x0a); db(0x4e); db(0xae); db(0xff); db(0xa0);
+ db(0x20); db(0x40); db(0x20); db(0x28); db(0x00); db(0x16); db(0x20); db(0x40);
+ db(0x4e); db(0x90); db(0x4e); db(0x75); db(0x00); db(0x00); db(0x00); db(0x07);
+ db(0x00); db(0x00); db(0x00); db(0x00); db(0x00); db(0x00); db(0x00); db(0x07);
+ db(0xe5); db(0x89); db(0x2e); db(0x01); db(0x60); db(0x00); db(0x0d); db(0xb0);
+ db(0x00); db(0x00); db(0x00); db(0x00); db(0x00); db(0x00); db(0x00); db(0x01);
+ db(0x00); db(0x00); db(0x00); db(0x04); db(0x00); db(0x00); db(0x00); db(0x02);
+ db(0x48); db(0xe7); db(0x3f); db(0x3e); db(0x2c); db(0x78); db(0x00); db(0x04);
+ db(0x43); db(0xfa); db(0x28); db(0xe8); db(0x70); db(0x00); db(0x4e); db(0xae);
+ db(0xfd); db(0xd8); db(0x22); db(0x00); db(0x30); db(0x3c); db(0x3f); db(0xf8);
+ db(0x61); db(0x00); db(0x27); db(0x86); db(0x20); db(0x81); db(0x43); db(0xfa);
+ db(0x28); db(0xc0); db(0x70); db(0x00); db(0x4e); db(0xae); db(0xfd); db(0xd8);
+ db(0x22); db(0x00); db(0x30); db(0x3c); db(0x3f); db(0xf4); db(0x61); db(0x00);
+ db(0x27); db(0x70); db(0x20); db(0x81); db(0x61); db(0x00); db(0x16); db(0x8c);
+ db(0x61); db(0x00); db(0x1a); db(0x54); db(0x4c); db(0xdf); db(0x7c); db(0xfc);
+ db(0x70); db(0x00); db(0x4e); db(0x75); db(0x48); db(0xe7); db(0xff); db(0xfe);
+ db(0x2c); db(0x78); db(0x00); db(0x04); db(0x30); db(0x3c); db(0xff); db(0xec);
+ db(0x61); db(0x00); db(0x27); db(0x4e); db(0x2a); db(0x50); db(0x7a); db(0x00);
+ db(0x70); db(0x00); db(0x0c); db(0x6e); db(0x00); db(0x21); db(0x00); db(0x14);
+ db(0x65); db(0x1c); db(0x43); db(0xfa); db(0x28); db(0x9f); db(0x70); db(0x24);
+ db(0x7a); db(0x01); db(0x4e); db(0xae); db(0xfd); db(0xd8); db(0x4a); db(0x80);
+ db(0x66); db(0x0c); db(0x43); db(0xfa); db(0x28); db(0x8f); db(0x70); db(0x00);
+ db(0x7a); db(0x00); db(0x4e); db(0xae); db(0xfd); db(0xd8); db(0x28); db(0x40);
+ db(0xc9); db(0x4e); db(0x20); db(0x0e); db(0x67); db(0x3c); db(0x08); db(0x2d);
+ db(0x00); db(0x04); db(0x01); db(0x13); db(0x66); db(0x34); db(0x4e); db(0xae);
+ db(0xff); db(0xd0); db(0x4a); db(0x80); db(0x67); db(0x2c); db(0x20); db(0x40);
+ db(0x43); db(0xfa); db(0xfe); db(0xfe); db(0x20); db(0x09); db(0x42); db(0x40);
+ db(0x21); db(0x40); db(0x00); db(0x20); db(0x21); db(0x7c); db(0x00); db(0x01);
+ db(0x00); db(0x00); db(0x00); db(0x24); db(0x31); db(0x7c); db(0x01); db(0x04);
+ db(0x00); db(0x10); db(0x31); db(0x7c); db(0x07); db(0xdb); db(0x00); db(0x14);
+ db(0x70); db(0x01); db(0x21); db(0x40); db(0x00); db(0x16); db(0x4e); db(0xae);
+ db(0xff); db(0xe2); db(0xc9); db(0x4e); db(0x4a); db(0xad); db(0x01); db(0x0c);
+ db(0x67); db(0x00); db(0x00); db(0x62); db(0x20); db(0x3c); db(0x00); db(0x00);
+ db(0x02); db(0x38); db(0x22); db(0x3c); db(0x00); db(0x01); db(0x00); db(0x01);
+ db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x26); db(0x40); db(0x27); db(0x4c);
+ db(0x01); db(0xa8); db(0x7c); db(0x00); db(0xbc); db(0x6d); db(0x01); db(0x0e);
+ db(0x64); db(0x32); db(0x2f); db(0x06); db(0x2e); db(0x2d); db(0x01); db(0x10);
+ db(0x4a); db(0x45); db(0x67); db(0x04); db(0x08); db(0xc7); db(0x00); db(0x02);
+ db(0x2f); db(0x0b); db(0x20); db(0x4b); db(0x61); db(0x00); db(0x09); db(0xfe);
+ db(0x26); db(0x5f); db(0x27); db(0x41); db(0x01); db(0xa4); db(0x0c); db(0x80);
+ db(0xff); db(0xff); db(0xff); db(0xfe); db(0x67); db(0x08); db(0x48); db(0x46);
+ db(0x52); db(0x46); db(0x48); db(0x46); db(0x60); db(0xd6); db(0x2c); db(0x1f);
+ db(0x52); db(0x46); db(0x60); db(0xc8); db(0x2c); db(0x78); db(0x00); db(0x04);
+ db(0x22); db(0x4b); db(0x20); db(0x3c); db(0x00); db(0x00); db(0x02); db(0x38);
+ db(0x4e); db(0xae); db(0xff); db(0x2e); db(0x2c); db(0x78); db(0x00); db(0x04);
+ db(0x20); db(0x0c); db(0x67); db(0x06); db(0x22); db(0x4c); db(0x4e); db(0xae);
+ db(0xfe); db(0x62); db(0x0c); db(0x6e); db(0x00); db(0x22); db(0x00); db(0x14);
+ db(0x65); db(0x00); db(0x00); db(0x9e); db(0x78); db(0x03); db(0x0c); db(0x6e);
+ db(0x00); db(0x24); db(0x00); db(0x14); db(0x65); db(0x04); db(0x00); db(0x44);
+ db(0x01); db(0x00); db(0x30); db(0x3c); db(0xff); db(0x80); db(0x61); db(0x00);
+ db(0x26); db(0x48); db(0x4e); db(0x90); db(0x2a); db(0x00); db(0x20); db(0x49);
+ db(0x20); db(0x01); db(0x67); db(0x0c); db(0x22); db(0x04); db(0x74); db(0xfb);
+ db(0x43); db(0xfa); db(0x27); db(0xbf); db(0x4e); db(0xae); db(0xfd); db(0x96);
+ db(0x0c); db(0x85); db(0x00); db(0x40); db(0x00); db(0x00); db(0x65); db(0x26);
+ db(0xba); db(0xae); db(0x00); db(0x3e); db(0x67); db(0x20); db(0x4e); db(0xae);
+ db(0xff); db(0x88); db(0x2d); db(0x45); db(0x00); db(0x3e); db(0x70); db(0x00);
+ db(0x72); db(0x17); db(0x41); db(0xee); db(0x00); db(0x22); db(0xd0); db(0x58);
+ db(0x51); db(0xc9); db(0xff); db(0xfc); db(0x46); db(0x40); db(0x3d); db(0x40);
+ db(0x00); db(0x52); db(0x4e); db(0xae); db(0xff); db(0x82); db(0x43); db(0xf9);
+ db(0x00); db(0x21); db(0x00); db(0x00); db(0x4e); db(0xae); db(0xfd); db(0xea);
+ db(0x4a); db(0x80); db(0x66); db(0x18); db(0x22); db(0x04); db(0x74); db(0xf6);
+ db(0x20); db(0x7c); db(0x00); db(0x20); db(0x00); db(0x00); db(0x20); db(0x05);
+ db(0x90); db(0x88); db(0x65); db(0x08); db(0x67); db(0x06); db(0x93); db(0xc9);
+ db(0x4e); db(0xae); db(0xfd); db(0x96); db(0x41); db(0xfa); db(0x26); db(0xb7);
+ db(0x43); db(0xfa); db(0x00); db(0x5a); db(0x70); db(0x0a); db(0x61); db(0x00);
+ db(0x0f); db(0x40); db(0x22); db(0x40); db(0x72); db(0x01); db(0x30); db(0x3c);
+ db(0xff); db(0x48); db(0x61); db(0x00); db(0x25); db(0xc4); db(0x4e); db(0x90);
+ db(0x4c); db(0xdf); db(0x7f); db(0xff); db(0x4e); db(0x75); db(0x48); db(0xe7);
+ db(0x3c); db(0x22); db(0x7a); db(0x00); db(0x2c); db(0x78); db(0x00); db(0x04);
+ db(0x24); db(0x00); db(0x28); db(0x01); db(0x26); db(0x09); db(0x24); db(0x48);
+ db(0x43); db(0xfa); db(0x26); db(0xda); db(0x70); db(0x00); db(0x4e); db(0xae);
+ db(0xfd); db(0xd8); db(0x4a); db(0x80); db(0x67); db(0x16); db(0x2c); db(0x40);
+ db(0x22); db(0x0a); db(0xe4); db(0x8b); db(0x4e); db(0xae); db(0xff); db(0x76);
+ db(0x2a); db(0x00); db(0x22); db(0x4e); db(0x2c); db(0x78); db(0x00); db(0x04);
+ db(0x4e); db(0xae); db(0xfe); db(0x62); db(0x20); db(0x05); db(0x4c); db(0xdf);
+ db(0x44); db(0x3c); db(0x4e); db(0x75); db(0x2c); db(0x78); db(0x00); db(0x04);
+ db(0x70); db(0x00); db(0x08); db(0xc0); db(0x00); db(0x0d); db(0x4e); db(0xae);
+ db(0xfe); db(0xc2); db(0x41); db(0xfa); db(0x26); db(0x7a); db(0x43); db(0xfa);
+ db(0x00); db(0x14); db(0x70); db(0x0f); db(0x22); db(0x3c); db(0x00); db(0x00);
+ db(0x1f); db(0x40); db(0x61); db(0x00); db(0xff); db(0xa2); db(0x60); db(0xdc);
  db(0x00); db(0x00); db(0x00); db(0x10); db(0x00); db(0x00); db(0x00); db(0x00);
- db(0x2c); db(0x78); db(0x00); db(0x04); db(0x43); db(0xfa); db(0x1e); db(0x63);
- db(0x70); db(0x00); db(0x4e); db(0xae); db(0xfd); db(0xd8); db(0x2a); db(0x40);
- db(0xcb); db(0x4e); db(0x60); db(0x0e); db(0xcb); db(0x4e); db(0x70); db(0x00);
- db(0x08); db(0xc0); db(0x00); db(0x0d); db(0x4e); db(0xae); db(0xfe); db(0xc2);
- db(0xcb); db(0x4e); db(0x30); db(0x3c); db(0xff); db(0x50); db(0x61); db(0x00);
- db(0x1d); db(0x0c); db(0x70); db(0x15); db(0x4e); db(0x90); db(0x2e); db(0x08);
- db(0x67); db(0xe2); db(0x28); db(0x4f); db(0x4f); db(0xef); db(0xfd); db(0xd8);
- db(0x2c); db(0x0f); db(0x24); db(0x46); db(0x47); db(0xea); db(0x00); db(0x28);
- db(0x22); db(0x4b); db(0x20); db(0x47); db(0x12); db(0xd8); db(0x66); db(0xfc);
- db(0x20); db(0x47); db(0x42); db(0x10); db(0x24); db(0xfc); db(0x80); db(0x00);
- db(0x00); db(0x21); db(0x41); db(0xfa); db(0x1d); db(0x51); db(0x22); db(0x08);
- db(0x24); db(0x3c); db(0x00); db(0x00); db(0x03); db(0xed); db(0x4e); db(0xae);
- db(0xff); db(0xe2); db(0x24); db(0xc0); db(0x24); db(0xfc); db(0x80); db(0x00);
- db(0x00); db(0x22); db(0x41); db(0xfa); db(0x1d); db(0x39); db(0x22); db(0x08);
- db(0x4e); db(0xae); db(0xff); db(0xe2); db(0x24); db(0xc0); db(0x24); db(0xfc);
- db(0x80); db(0x00); db(0x00); db(0x23); db(0x70); db(0xff); db(0x24); db(0xc0);
- db(0x42); db(0x9a); db(0x42); db(0x92); db(0x0c); db(0x6e); db(0x00); db(0x24);
- db(0x00); db(0x14); db(0x64); db(0x20); db(0x24); db(0x46); db(0x22); db(0x0b);
- db(0x74); db(0x00); db(0x26); db(0x2a); db(0x00); db(0x0c); db(0x4e); db(0xae);
- db(0xff); db(0x22); db(0x22); db(0x2a); db(0x00); db(0x04); db(0x4e); db(0xae);
- db(0xff); db(0xdc); db(0x22); db(0x2a); db(0x00); db(0x0c); db(0x4e); db(0xae);
- db(0xff); db(0xdc); db(0x60); db(0x08); db(0x22); db(0x0b); db(0x24); db(0x06);
- db(0x4e); db(0xae); db(0xfd); db(0xa2); db(0x2e); db(0x4c); db(0x30); db(0x3c);
- db(0xff); db(0x50); db(0x61); db(0x00); db(0x1c); db(0x78); db(0x70); db(0x16);
- db(0x4e); db(0x90); db(0x60); db(0x00); db(0xff); db(0x50); db(0x48); db(0xe7);
- db(0xf0); db(0xf8); db(0x24); db(0x00); db(0x26); db(0x01); db(0x30); db(0x3c);
- db(0xff); db(0x38); db(0x72); db(0x12); db(0x61); db(0x00); db(0x1c); db(0x5e);
- db(0x20); db(0x02); db(0x24); db(0x03); db(0x4e); db(0x90); db(0x24); db(0x40);
- db(0x70); db(0x2a); db(0x22); db(0x3c); db(0x00); db(0x01); db(0x00); db(0x01);
- db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x28); db(0x40); db(0x47); db(0xec);
- db(0x00); db(0x16); db(0x22); db(0x4b); db(0x22); db(0xca); db(0x22); db(0xc2);
- db(0x22); db(0xc3); db(0x30); db(0x3c); db(0x3f); db(0xf4); db(0x61); db(0x00);
- db(0x1c); db(0x44); db(0x22); db(0xc8); db(0x30); db(0x3c); db(0x3f); db(0xf0);
- db(0x61); db(0x00); db(0x1c); db(0x3a); db(0x22); db(0xc8); db(0x29); db(0x4b);
- db(0x00); db(0x0e); db(0x19); db(0x7c); db(0x00); db(0x02); db(0x00); db(0x08);
- db(0x19); db(0x7c); db(0x00); db(0xf6); db(0x00); db(0x09); db(0x41); db(0xfa);
- db(0x1c); db(0xdc); db(0x29); db(0x48); db(0x00); db(0x0a); db(0x41); db(0xfa);
- db(0x00); db(0x14); db(0x29); db(0x48); db(0x00); db(0x12); db(0x22); db(0x4c);
- db(0x70); db(0x05); db(0x4e); db(0xae); db(0xff); db(0x58); db(0x4c); db(0xdf);
- db(0x1f); db(0x0f); db(0x4e); db(0x75); db(0x20); db(0x51); db(0x52); db(0x90);
- db(0x20); db(0x69); db(0x00); db(0x0c); db(0x20); db(0x10); db(0x67); db(0x1e);
- db(0x20); db(0x40); db(0x0c); db(0x68); db(0x00); db(0x1f); db(0x00); db(0x14);
- db(0x65); db(0x14); db(0x4a); db(0xa8); db(0x00); db(0x22); db(0x67); db(0x0e);
- db(0x4a); db(0xa8); db(0x00); db(0x3c); db(0x67); db(0x08); db(0x22); db(0x69);
- db(0x00); db(0x10); db(0x22); db(0xa8); db(0x00); db(0x44); db(0x70); db(0x00);
- db(0x4e); db(0x75); db(0x48); db(0xe7); db(0xf1); db(0xe0); db(0x2e); db(0x00);
- db(0x20); db(0x3c); db(0x00); db(0x00); db(0xff); db(0xfc); db(0x61); db(0x00);
- db(0x1b); db(0xcc); db(0x24); db(0x48); db(0x74); db(0x00); db(0x08); db(0x07);
- db(0x00); db(0x00); db(0x67); db(0x10); db(0x41); db(0xfa); db(0x1c); db(0x9f);
- db(0x43); db(0xfa); db(0xfd); db(0x78); db(0x70); db(0x14); db(0x61); db(0x00);
- db(0x0b); db(0x94); db(0x24); db(0x00); db(0x76); db(0x00); db(0x08); db(0x07);
- db(0x00); db(0x01); db(0x67); db(0x10); db(0x41); db(0xfa); db(0x1c); db(0x95);
- db(0x43); db(0xfa); db(0xfc); db(0xda); db(0x70); db(0x19); db(0x61); db(0x00);
- db(0x0b); db(0x7c); db(0x26); db(0x00); db(0x70); db(0x2a); db(0x22); db(0x3c);
- db(0x00); db(0x01); db(0x00); db(0x01); db(0x4e); db(0xae); db(0xff); db(0x3a);
- db(0x22); db(0x40); db(0x41); db(0xe9); db(0x00); db(0x1a); db(0x20); db(0xca);
- db(0x20); db(0xce); db(0x20); db(0xc2); db(0x20); db(0x83); db(0x41); db(0xfa);
- db(0x1c); db(0x43); db(0x23); db(0x48); db(0x00); db(0x0a); db(0x45); db(0xe9);
- db(0x00); db(0x1a); db(0x23); db(0x4a); db(0x00); db(0x0e); db(0x41); db(0xfa);
- db(0xfe); db(0x02); db(0x23); db(0x48); db(0x00); db(0x12); db(0x33); db(0x7c);
- db(0x02); db(0x14); db(0x00); db(0x08); db(0x70); db(0x03); db(0x4e); db(0xae);
- db(0xff); db(0x58); db(0x20); db(0x02); db(0x22); db(0x03); db(0x61); db(0x00);
- db(0xfe); db(0xd6); db(0x30); db(0x3c); db(0xff); db(0x38); db(0x72); db(0x04);
- db(0x61); db(0x00); db(0x1b); db(0x3a); db(0x4e); db(0x90); db(0x4a); db(0x80);
- db(0x67); db(0x04); db(0x61); db(0x00); db(0x0b); db(0x7c); db(0x4c); db(0xdf);
- db(0x07); db(0x8f); db(0x4e); db(0x75); db(0x48); db(0xe7); db(0xc0); db(0xf2);
- db(0x2c); db(0x78); db(0x00); db(0x04); db(0x24); db(0x48); db(0x26); db(0x49);
- db(0x20); db(0x3c); db(0x00); db(0x00); db(0x00); db(0xbe); db(0x22); db(0x3c);
+ db(0x72); db(0x02); db(0x30); db(0x3c); db(0xff); db(0x48); db(0x61); db(0x00);
+ db(0x25); db(0x38); db(0x4e); db(0x90); db(0x22); db(0x00); db(0x6b); db(0x04);
+ db(0x61); db(0x00); db(0x0a); db(0x94); db(0x70); db(0x00); db(0x4e); db(0x75);
+ db(0x2c); db(0x78); db(0x00); db(0x04); db(0x20); db(0x3c); db(0x00); db(0x00);
+ db(0x01); db(0x00); db(0x4e); db(0xae); db(0xfe); db(0xc2); db(0x7e); db(0x00);
+ db(0x20); db(0x3c); db(0x00); db(0x00); db(0xf0); db(0x00); db(0x61); db(0x00);
+ db(0x25); db(0x20); db(0x22); db(0x48); db(0x20); db(0x3c); db(0x00); db(0x00);
+ db(0x40); db(0x00); db(0x61); db(0x00); db(0x25); db(0x14); db(0x7c); db(0x03);
+ db(0x4a); db(0x29); db(0x00); db(0x03); db(0x67); db(0x42); db(0x0c); db(0x29);
+ db(0x00); db(0xfd); db(0x00); db(0x07); db(0x66); db(0x3a); db(0x52); db(0x87);
+ db(0x49); db(0xe8); db(0x00); db(0x54); db(0x4b); db(0xe9); db(0x00); db(0x04);
+ db(0x48); db(0xe7); db(0x03); db(0xce); db(0x38); db(0x15); db(0x4c); db(0xd4);
+ db(0x07); db(0x00); db(0x4c); db(0xd4); db(0x00); db(0x07); db(0x0c); db(0x44);
+ db(0x00); db(0x12); db(0x66); db(0x06); db(0x61); db(0x00); db(0x1d); db(0x1a);
+ db(0x60); db(0x0a); db(0x0c); db(0x44); db(0x00); db(0x13); db(0x66); db(0x04);
+ db(0x61); db(0x00); db(0x1d); db(0x28); db(0x4c); db(0xdf); db(0x73); db(0xc0);
+ db(0x28); db(0x80); db(0x1b); db(0x7c); db(0x00); db(0x02); db(0x00); db(0x03);
+ db(0xd0); db(0xfc); db(0x20); db(0x00); db(0xd2); db(0xfc); db(0x00); db(0x08);
+ db(0x51); db(0xce); db(0xff); db(0xae); db(0x4a); db(0x87); db(0x67); db(0x00);
+ db(0xff); db(0x84); db(0x60); db(0x00); db(0xff); db(0x8a); db(0x2c); db(0x78);
+ db(0x00); db(0x04); db(0x20); db(0x3c); db(0x00); db(0x00); db(0x01); db(0x00);
+ db(0x4e); db(0xae); db(0xfe); db(0xc2); db(0x61); db(0x04); db(0x60); db(0xf2);
+ db(0x4e); db(0x75); db(0x7e); db(0x0a); db(0x30); db(0x3c); db(0xff); db(0x50);
+ db(0x61); db(0x00); db(0x24); db(0x86); db(0x20); db(0x07); db(0x4e); db(0x90);
+ db(0x4a); db(0x80); db(0x67); db(0xec); db(0x7e); db(0x0b); db(0x0c); db(0x40);
+ db(0x00); db(0x01); db(0x6d); db(0x00); db(0xff); db(0xe8); db(0x6e); db(0x06);
+ db(0x4e); db(0xae); db(0xfe); db(0x92); db(0x60); db(0xde); db(0x0c); db(0x40);
+ db(0x00); db(0x02); db(0x6e); db(0x08); db(0x20); db(0x01); db(0x4e); db(0xae);
+ db(0xfe); db(0xbc); db(0x60); db(0xd0); db(0x0c); db(0x40); db(0x00); db(0x03);
+ db(0x6e); db(0x06); db(0x4e); db(0xae); db(0xfe); db(0x86); db(0x60); db(0xc4);
+ db(0x0c); db(0x40); db(0x00); db(0x04); db(0x6e); db(0x06); db(0x4e); db(0xae);
+ db(0xff); db(0x4c); db(0x60); db(0xb8); db(0x0c); db(0x40); db(0x00); db(0x05);
+ db(0x6e); db(0x46); db(0x48); db(0xe7); db(0x00); db(0xc0); db(0x70); db(0x26);
+ db(0x22); db(0x3c); db(0x00); db(0x01); db(0x00); db(0x01); db(0x4e); db(0xae);
+ db(0xff); db(0x3a); db(0x4c); db(0xdf); db(0x03); db(0x00); db(0x24); db(0x40);
+ db(0x15); db(0x7c); db(0x00); db(0x08); db(0x00); db(0x08); db(0x25); db(0x48);
+ db(0x00); db(0x0e); db(0x35); db(0x7c); db(0x00); db(0x26); db(0x00); db(0x12);
+ db(0x25); db(0x7c); db(0x40); db(0x00); db(0x00); db(0x00); db(0x00); db(0x14);
+ db(0x35); db(0x7c); db(0x12); db(0x34); db(0x00); db(0x18); db(0x25); db(0x49);
+ db(0x00); db(0x1a); db(0x20); db(0x69); db(0x00); db(0x10); db(0x22); db(0x4a);
+ db(0x4e); db(0xae); db(0xfe); db(0x92); db(0x60); db(0x00); db(0xff); db(0x6e);
+ db(0x0c); db(0x40); db(0x00); db(0x06); db(0x6e); db(0x00); db(0xff); db(0x66);
+ db(0x41); db(0xfa); db(0x25); db(0xa3); db(0x43); db(0xfa); db(0x00); db(0x42);
+ db(0x70); db(0x01); db(0x22); db(0x3c); db(0x00); db(0x00); db(0x27); db(0x10);
+ db(0x61); db(0x00); db(0xfe); db(0x34); db(0x22); db(0x00); db(0x30); db(0x3c);
+ db(0xff); db(0x50); db(0x61); db(0x00); db(0x23); db(0xd4); db(0x70); db(0x14);
+ db(0x4e); db(0x90); db(0x60); db(0x00); db(0xff); db(0x40); db(0x70); db(0x00);
+ db(0x20); db(0x59); db(0x4a); db(0x10); db(0x67); db(0x10); db(0x2c); db(0x59);
+ db(0x22); db(0x51); db(0x20); db(0x3c); db(0x00); db(0x00); db(0x01); db(0x00);
+ db(0x4e); db(0xae); db(0xfe); db(0xbc); db(0x70); db(0x01); db(0x4a); db(0x40);
+ db(0x4e); db(0x75); db(0x00); db(0x00); db(0x00); db(0x00); db(0x00); db(0x10);
+ db(0x00); db(0x00); db(0x00); db(0x00); db(0x2c); db(0x78); db(0x00); db(0x04);
+ db(0x43); db(0xfa); db(0x24); db(0xe2); db(0x70); db(0x00); db(0x4e); db(0xae);
+ db(0xfd); db(0xd8); db(0x2a); db(0x40); db(0xcb); db(0x4e); db(0x60); db(0x0e);
+ db(0xcb); db(0x4e); db(0x70); db(0x00); db(0x08); db(0xc0); db(0x00); db(0x0d);
+ db(0x4e); db(0xae); db(0xfe); db(0xc2); db(0xcb); db(0x4e); db(0x30); db(0x3c);
+ db(0xff); db(0x50); db(0x61); db(0x00); db(0x23); db(0x7c); db(0x70); db(0x15);
+ db(0x4e); db(0x90); db(0x2e); db(0x08); db(0x67); db(0xe2); db(0x28); db(0x4f);
+ db(0x4f); db(0xef); db(0xfd); db(0xd8); db(0x2c); db(0x0f); db(0x24); db(0x46);
+ db(0x47); db(0xea); db(0x00); db(0x28); db(0x22); db(0x4b); db(0x20); db(0x47);
+ db(0x12); db(0xd8); db(0x66); db(0xfc); db(0x20); db(0x47); db(0x42); db(0x10);
+ db(0x24); db(0xfc); db(0x80); db(0x00); db(0x00); db(0x21); db(0x41); db(0xfa);
+ db(0x23); db(0xd0); db(0x22); db(0x08); db(0x24); db(0x3c); db(0x00); db(0x00);
+ db(0x03); db(0xed); db(0x4e); db(0xae); db(0xff); db(0xe2); db(0x24); db(0xc0);
+ db(0x24); db(0xfc); db(0x80); db(0x00); db(0x00); db(0x22); db(0x41); db(0xfa);
+ db(0x23); db(0xb8); db(0x22); db(0x08); db(0x4e); db(0xae); db(0xff); db(0xe2);
+ db(0x24); db(0xc0); db(0x24); db(0xfc); db(0x80); db(0x00); db(0x00); db(0x23);
+ db(0x70); db(0xff); db(0x24); db(0xc0); db(0x42); db(0x9a); db(0x42); db(0x92);
+ db(0x0c); db(0x6e); db(0x00); db(0x24); db(0x00); db(0x14); db(0x64); db(0x20);
+ db(0x24); db(0x46); db(0x22); db(0x0b); db(0x74); db(0x00); db(0x26); db(0x2a);
+ db(0x00); db(0x0c); db(0x4e); db(0xae); db(0xff); db(0x22); db(0x22); db(0x2a);
+ db(0x00); db(0x04); db(0x4e); db(0xae); db(0xff); db(0xdc); db(0x22); db(0x2a);
+ db(0x00); db(0x0c); db(0x4e); db(0xae); db(0xff); db(0xdc); db(0x60); db(0x08);
+ db(0x22); db(0x0b); db(0x24); db(0x06); db(0x4e); db(0xae); db(0xfd); db(0xa2);
+ db(0x2e); db(0x4c); db(0x30); db(0x3c); db(0xff); db(0x50); db(0x61); db(0x00);
+ db(0x22); db(0xe8); db(0x70); db(0x16); db(0x4e); db(0x90); db(0x60); db(0x00);
+ db(0xff); db(0x50); db(0x48); db(0xe7); db(0xf0); db(0xf8); db(0x24); db(0x00);
+ db(0x26); db(0x01); db(0x30); db(0x3c); db(0xff); db(0x38); db(0x72); db(0x12);
+ db(0x61); db(0x00); db(0x22); db(0xce); db(0x20); db(0x02); db(0x24); db(0x03);
+ db(0x4e); db(0x90); db(0x24); db(0x40); db(0x70); db(0x2a); db(0x22); db(0x3c);
  db(0x00); db(0x01); db(0x00); db(0x01); db(0x4e); db(0xae); db(0xff); db(0x3a);
- db(0x20); db(0x40); db(0x70); db(0x00); db(0x43); db(0xeb); db(0x01); db(0xac);
- db(0x11); db(0xb1); db(0x00); db(0x00); db(0x00); db(0x0e); db(0x52); db(0x40);
- db(0x0c); db(0x40); db(0x00); db(0x8c); db(0x66); db(0xf2); db(0x20); db(0x0a);
- db(0xe4); db(0x88); db(0x21); db(0x40); db(0x00); db(0x36); db(0x22); db(0x48);
- db(0x41); db(0xfa); db(0x1b); db(0xc1); db(0x23); db(0x48); db(0x00); db(0x0a);
- db(0x20); db(0x6b); db(0x01); db(0x9c); db(0x41); db(0xe8); db(0x00); db(0x12);
- db(0x4e); db(0xae); db(0xff); db(0x10); db(0x4c); db(0xdf); db(0x4f); db(0x03);
- db(0x4e); db(0x75); db(0x48); db(0xe7); db(0x7f); db(0x7e); db(0x2c); db(0x78);
- db(0x00); db(0x04); db(0x24); db(0x48); db(0x0c); db(0x9a); db(0x00); db(0x00);
- db(0x03); db(0xf3); db(0x66); db(0x00); db(0x00); db(0xe4); db(0x50); db(0x8a);
- db(0x2e); db(0x2a); db(0x00); db(0x04); db(0x9e); db(0x92); db(0x50); db(0x8a);
- db(0x52); db(0x87); db(0x26); db(0x4a); db(0x20); db(0x07); db(0xd0); db(0x80);
- db(0xd0); db(0x80); db(0xd7); db(0xc0); db(0x28); db(0x4a); db(0x9b); db(0xcd);
- db(0x7c); db(0x00); db(0x24); db(0x12); db(0x72); db(0x01); db(0x08); db(0x02);
- db(0x00); db(0x1e); db(0x67); db(0x04); db(0x08); db(0xc1); db(0x00); db(0x01);
- db(0x08); db(0xc1); db(0x00); db(0x10); db(0xe5); db(0x8a); db(0x66); db(0x04);
- db(0x42); db(0x9a); db(0x60); db(0x20); db(0x50); db(0x82); db(0x20); db(0x02);
- db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x4a); db(0x80); db(0x67); db(0x00);
- db(0x00); db(0xa0); db(0x20); db(0x40); db(0x20); db(0xc2); db(0x24); db(0xc8);
- db(0x22); db(0x0d); db(0x67); db(0x06); db(0x20); db(0x08); db(0xe4); db(0x88);
- db(0x2a); db(0x80); db(0x2a); db(0x48); db(0x52); db(0x86); db(0xbe); db(0x86);
- db(0x66); db(0xc0); db(0x7c); db(0x00); db(0x22); db(0x06); db(0xd2); db(0x81);
- db(0xd2); db(0x81); db(0x20); db(0x74); db(0x18); db(0x00); db(0x58); db(0x88);
- db(0x26); db(0x1b); db(0x28); db(0x1b); db(0xe5); db(0x8c); db(0x0c); db(0x83);
- db(0x00); db(0x00); db(0x03); db(0xe9); db(0x67); db(0x08); db(0x0c); db(0x83);
- db(0x00); db(0x00); db(0x03); db(0xea); db(0x66); db(0x0c); db(0x20); db(0x04);
- db(0x4a); db(0x80); db(0x67); db(0x0e); db(0x10); db(0xdb); db(0x53); db(0x80);
- db(0x60); db(0xf6); db(0x0c); db(0x83); db(0x00); db(0x00); db(0x03); db(0xeb);
- db(0x66); db(0x4e); db(0x26); db(0x1b); db(0x0c); db(0x83); db(0x00); db(0x00);
- db(0x03); db(0xec); db(0x66); db(0x28); db(0x22); db(0x06); db(0xd2); db(0x81);
- db(0xd2); db(0x81); db(0x20); db(0x74); db(0x18); db(0x00); db(0x58); db(0x88);
- db(0x20); db(0x1b); db(0x67); db(0xe6); db(0x22); db(0x1b); db(0xd2); db(0x81);
- db(0xd2); db(0x81); db(0x26); db(0x34); db(0x18); db(0x00); db(0x58); db(0x83);
- db(0x24); db(0x1b); db(0xd7); db(0xb0); db(0x28); db(0x00); db(0x53); db(0x80);
- db(0x66); db(0xf6); db(0x60); db(0xe4); db(0x0c); db(0x83); db(0x00); db(0x00);
- db(0x03); db(0xf2); db(0x66); db(0x14); db(0x52); db(0x86); db(0xbe); db(0x86);
- db(0x66); db(0x00); db(0xff); db(0x8a); db(0x7e); db(0x01); db(0x20); db(0x54);
- db(0x20); db(0x07); db(0x4c); db(0xdf); db(0x7e); db(0xfe); db(0x4e); db(0x75);
- db(0x91); db(0xc8); db(0x7e); db(0x00); db(0x60); db(0xf2); db(0x48); db(0xe7);
- db(0x40); db(0xf2); db(0x26); db(0x48); db(0x2c); db(0x78); db(0x00); db(0x04);
- db(0x41); db(0xee); db(0x01); db(0x50); db(0x20); db(0x50); db(0x4a); db(0x90);
- db(0x67); db(0x1a); db(0x22); db(0x68); db(0x00); db(0x0a); db(0x45); db(0xfa);
- db(0x1b); db(0x32); db(0x10); db(0x19); db(0x12); db(0x1a); db(0xb0); db(0x01);
- db(0x66); db(0x06); db(0x4a); db(0x00); db(0x67); db(0x46); db(0x60); db(0xf2);
- db(0x20); db(0x50); db(0x60); db(0xe2); db(0x70); db(0x20); db(0x22); db(0x3c);
+ db(0x28); db(0x40); db(0x47); db(0xec); db(0x00); db(0x16); db(0x22); db(0x4b);
+ db(0x22); db(0xca); db(0x22); db(0xc2); db(0x22); db(0xc3); db(0x30); db(0x3c);
+ db(0x3f); db(0xf4); db(0x61); db(0x00); db(0x22); db(0xb4); db(0x22); db(0xc8);
+ db(0x30); db(0x3c); db(0x3f); db(0xf0); db(0x61); db(0x00); db(0x22); db(0xaa);
+ db(0x22); db(0xc8); db(0x29); db(0x4b); db(0x00); db(0x0e); db(0x19); db(0x7c);
+ db(0x00); db(0x02); db(0x00); db(0x08); db(0x19); db(0x7c); db(0x00); db(0xf6);
+ db(0x00); db(0x09); db(0x41); db(0xfa); db(0x23); db(0x5b); db(0x29); db(0x48);
+ db(0x00); db(0x0a); db(0x41); db(0xfa); db(0x00); db(0x14); db(0x29); db(0x48);
+ db(0x00); db(0x12); db(0x22); db(0x4c); db(0x70); db(0x05); db(0x4e); db(0xae);
+ db(0xff); db(0x58); db(0x4c); db(0xdf); db(0x1f); db(0x0f); db(0x4e); db(0x75);
+ db(0x20); db(0x51); db(0x52); db(0x90); db(0x20); db(0x69); db(0x00); db(0x0c);
+ db(0x20); db(0x10); db(0x67); db(0x1e); db(0x20); db(0x40); db(0x0c); db(0x68);
+ db(0x00); db(0x1f); db(0x00); db(0x14); db(0x65); db(0x14); db(0x4a); db(0xa8);
+ db(0x00); db(0x22); db(0x67); db(0x0e); db(0x4a); db(0xa8); db(0x00); db(0x3c);
+ db(0x67); db(0x08); db(0x22); db(0x69); db(0x00); db(0x10); db(0x22); db(0xa8);
+ db(0x00); db(0x44); db(0x70); db(0x00); db(0x4e); db(0x75); db(0x48); db(0xe7);
+ db(0xf1); db(0xe0); db(0x2e); db(0x00); db(0x20); db(0x3c); db(0x00); db(0x00);
+ db(0xff); db(0xfc); db(0x61); db(0x00); db(0x22); db(0x3c); db(0x24); db(0x48);
+ db(0x74); db(0x00); db(0x08); db(0x07); db(0x00); db(0x00); db(0x67); db(0x10);
+ db(0x41); db(0xfa); db(0x23); db(0x1e); db(0x43); db(0xfa); db(0xfd); db(0x78);
+ db(0x70); db(0x14); db(0x61); db(0x00); db(0x0b); db(0x94); db(0x24); db(0x00);
+ db(0x76); db(0x00); db(0x08); db(0x07); db(0x00); db(0x01); db(0x67); db(0x10);
+ db(0x41); db(0xfa); db(0x23); db(0x14); db(0x43); db(0xfa); db(0xfc); db(0xda);
+ db(0x70); db(0x19); db(0x61); db(0x00); db(0x0b); db(0x7c); db(0x26); db(0x00);
+ db(0x70); db(0x2a); db(0x22); db(0x3c); db(0x00); db(0x01); db(0x00); db(0x01);
+ db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x22); db(0x40); db(0x41); db(0xe9);
+ db(0x00); db(0x1a); db(0x20); db(0xca); db(0x20); db(0xce); db(0x20); db(0xc2);
+ db(0x20); db(0x83); db(0x41); db(0xfa); db(0x22); db(0xc2); db(0x23); db(0x48);
+ db(0x00); db(0x0a); db(0x45); db(0xe9); db(0x00); db(0x1a); db(0x23); db(0x4a);
+ db(0x00); db(0x0e); db(0x41); db(0xfa); db(0xfe); db(0x02); db(0x23); db(0x48);
+ db(0x00); db(0x12); db(0x33); db(0x7c); db(0x02); db(0x14); db(0x00); db(0x08);
+ db(0x70); db(0x03); db(0x4e); db(0xae); db(0xff); db(0x58); db(0x20); db(0x02);
+ db(0x22); db(0x03); db(0x61); db(0x00); db(0xfe); db(0xd6); db(0x30); db(0x3c);
+ db(0xff); db(0x38); db(0x72); db(0x04); db(0x61); db(0x00); db(0x21); db(0xaa);
+ db(0x4e); db(0x90); db(0x4a); db(0x80); db(0x67); db(0x04); db(0x61); db(0x00);
+ db(0x0b); db(0x7c); db(0x4c); db(0xdf); db(0x07); db(0x8f); db(0x4e); db(0x75);
+ db(0x48); db(0xe7); db(0xc0); db(0xf2); db(0x2c); db(0x78); db(0x00); db(0x04);
+ db(0x24); db(0x48); db(0x26); db(0x49); db(0x20); db(0x3c); db(0x00); db(0x00);
+ db(0x00); db(0xbe); db(0x22); db(0x3c); db(0x00); db(0x01); db(0x00); db(0x01);
+ db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x20); db(0x40); db(0x70); db(0x00);
+ db(0x43); db(0xeb); db(0x01); db(0xac); db(0x11); db(0xb1); db(0x00); db(0x00);
+ db(0x00); db(0x0e); db(0x52); db(0x40); db(0x0c); db(0x40); db(0x00); db(0x8c);
+ db(0x66); db(0xf2); db(0x20); db(0x0a); db(0xe4); db(0x88); db(0x21); db(0x40);
+ db(0x00); db(0x36); db(0x22); db(0x48); db(0x41); db(0xfa); db(0x22); db(0x40);
+ db(0x23); db(0x48); db(0x00); db(0x0a); db(0x20); db(0x6b); db(0x01); db(0x9c);
+ db(0x41); db(0xe8); db(0x00); db(0x12); db(0x4e); db(0xae); db(0xff); db(0x10);
+ db(0x4c); db(0xdf); db(0x4f); db(0x03); db(0x4e); db(0x75); db(0x48); db(0xe7);
+ db(0x7f); db(0x7e); db(0x2c); db(0x78); db(0x00); db(0x04); db(0x24); db(0x48);
+ db(0x0c); db(0x9a); db(0x00); db(0x00); db(0x03); db(0xf3); db(0x66); db(0x00);
+ db(0x00); db(0xe4); db(0x50); db(0x8a); db(0x2e); db(0x2a); db(0x00); db(0x04);
+ db(0x9e); db(0x92); db(0x50); db(0x8a); db(0x52); db(0x87); db(0x26); db(0x4a);
+ db(0x20); db(0x07); db(0xd0); db(0x80); db(0xd0); db(0x80); db(0xd7); db(0xc0);
+ db(0x28); db(0x4a); db(0x9b); db(0xcd); db(0x7c); db(0x00); db(0x24); db(0x12);
+ db(0x72); db(0x01); db(0x08); db(0x02); db(0x00); db(0x1e); db(0x67); db(0x04);
+ db(0x08); db(0xc1); db(0x00); db(0x01); db(0x08); db(0xc1); db(0x00); db(0x10);
+ db(0xe5); db(0x8a); db(0x66); db(0x04); db(0x42); db(0x9a); db(0x60); db(0x20);
+ db(0x50); db(0x82); db(0x20); db(0x02); db(0x4e); db(0xae); db(0xff); db(0x3a);
+ db(0x4a); db(0x80); db(0x67); db(0x00); db(0x00); db(0xa0); db(0x20); db(0x40);
+ db(0x20); db(0xc2); db(0x24); db(0xc8); db(0x22); db(0x0d); db(0x67); db(0x06);
+ db(0x20); db(0x08); db(0xe4); db(0x88); db(0x2a); db(0x80); db(0x2a); db(0x48);
+ db(0x52); db(0x86); db(0xbe); db(0x86); db(0x66); db(0xc0); db(0x7c); db(0x00);
+ db(0x22); db(0x06); db(0xd2); db(0x81); db(0xd2); db(0x81); db(0x20); db(0x74);
+ db(0x18); db(0x00); db(0x58); db(0x88); db(0x26); db(0x1b); db(0x28); db(0x1b);
+ db(0xe5); db(0x8c); db(0x0c); db(0x83); db(0x00); db(0x00); db(0x03); db(0xe9);
+ db(0x67); db(0x08); db(0x0c); db(0x83); db(0x00); db(0x00); db(0x03); db(0xea);
+ db(0x66); db(0x0c); db(0x20); db(0x04); db(0x4a); db(0x80); db(0x67); db(0x0e);
+ db(0x10); db(0xdb); db(0x53); db(0x80); db(0x60); db(0xf6); db(0x0c); db(0x83);
+ db(0x00); db(0x00); db(0x03); db(0xeb); db(0x66); db(0x4e); db(0x26); db(0x1b);
+ db(0x0c); db(0x83); db(0x00); db(0x00); db(0x03); db(0xec); db(0x66); db(0x28);
+ db(0x22); db(0x06); db(0xd2); db(0x81); db(0xd2); db(0x81); db(0x20); db(0x74);
+ db(0x18); db(0x00); db(0x58); db(0x88); db(0x20); db(0x1b); db(0x67); db(0xe6);
+ db(0x22); db(0x1b); db(0xd2); db(0x81); db(0xd2); db(0x81); db(0x26); db(0x34);
+ db(0x18); db(0x00); db(0x58); db(0x83); db(0x24); db(0x1b); db(0xd7); db(0xb0);
+ db(0x28); db(0x00); db(0x53); db(0x80); db(0x66); db(0xf6); db(0x60); db(0xe4);
+ db(0x0c); db(0x83); db(0x00); db(0x00); db(0x03); db(0xf2); db(0x66); db(0x14);
+ db(0x52); db(0x86); db(0xbe); db(0x86); db(0x66); db(0x00); db(0xff); db(0x8a);
+ db(0x7e); db(0x01); db(0x20); db(0x54); db(0x20); db(0x07); db(0x4c); db(0xdf);
+ db(0x7e); db(0xfe); db(0x4e); db(0x75); db(0x91); db(0xc8); db(0x7e); db(0x00);
+ db(0x60); db(0xf2); db(0x48); db(0xe7); db(0x40); db(0xf2); db(0x26); db(0x48);
+ db(0x2c); db(0x78); db(0x00); db(0x04); db(0x41); db(0xee); db(0x01); db(0x50);
+ db(0x20); db(0x50); db(0x4a); db(0x90); db(0x67); db(0x1a); db(0x22); db(0x68);
+ db(0x00); db(0x0a); db(0x45); db(0xfa); db(0x21); db(0xb1); db(0x10); db(0x19);
+ db(0x12); db(0x1a); db(0xb0); db(0x01); db(0x66); db(0x06); db(0x4a); db(0x00);
+ db(0x67); db(0x46); db(0x60); db(0xf2); db(0x20); db(0x50); db(0x60); db(0xe2);
+ db(0x70); db(0x20); db(0x22); db(0x3c); db(0x00); db(0x01); db(0x00); db(0x01);
+ db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x24); db(0x40); db(0x15); db(0x7c);
+ db(0x00); db(0x08); db(0x00); db(0x08); db(0x41); db(0xfa); db(0x21); db(0x87);
+ db(0x25); db(0x48); db(0x00); db(0x0a); db(0x41); db(0xfa); db(0x20); db(0xe0);
+ db(0x25); db(0x48); db(0x00); db(0x0e); db(0x41); db(0xea); db(0x00); db(0x12);
+ db(0x20); db(0x88); db(0x58); db(0x90); db(0x21); db(0x48); db(0x00); db(0x08);
+ db(0x41); db(0xee); db(0x01); db(0x50); db(0x22); db(0x4a); db(0x4e); db(0xae);
+ db(0xff); db(0x0a); db(0x20); db(0x4a); db(0x27); db(0x48); db(0x01); db(0xa0);
+ db(0x20); db(0x08); db(0x4c); db(0xdf); db(0x4f); db(0x02); db(0x4e); db(0x75);
+ db(0x48); db(0xe7); db(0x01); db(0x02); db(0x2e); db(0x00); db(0x4a); db(0x2b);
+ db(0x00); db(0x60); db(0x67); db(0x7c); db(0x2c); db(0x6b); db(0x00); db(0xa0);
+ db(0x0c); db(0x6e); db(0x00); db(0x25); db(0x00); db(0x14); db(0x65); db(0x3e);
+ db(0x72); db(0x0e); db(0x4e); db(0xae); db(0xfd); db(0x66); db(0x02); db(0x80);
+ db(0xff); db(0xff); db(0xff); db(0xfe); db(0x67); db(0x62); db(0x08); db(0x07);
+ db(0x00); db(0x00); db(0x67); db(0x0a); db(0x41); db(0xeb); db(0x00); db(0x20);
+ db(0x22); db(0x08); db(0x4e); db(0xae); db(0xfd); db(0x5a); db(0x08); db(0x07);
+ db(0x00); db(0x01); db(0x67); db(0x12); db(0x4a); db(0x2b); db(0x00); db(0x9e);
+ db(0x66); db(0x0c); db(0x50); db(0xeb); db(0x00); db(0x9e); db(0x22); db(0x2b);
+ db(0x00); db(0xb4); db(0x4e); db(0xae); db(0xfd); db(0x5a); db(0x72); db(0x0e);
+ db(0x4e); db(0xae); db(0xfd); db(0x6c); db(0x60); db(0x32); db(0x2c); db(0x78);
+ db(0x00); db(0x04); db(0x4e); db(0xae); db(0xff); db(0x7c); db(0x08); db(0x07);
+ db(0x00); db(0x00); db(0x67); db(0x08); db(0x41); db(0xeb); db(0x00); db(0x20);
+ db(0x61); db(0x00); db(0x00); db(0xac); db(0x08); db(0x07); db(0x00); db(0x01);
+ db(0x67); db(0x12); db(0x4a); db(0x2b); db(0x00); db(0x9e); db(0x66); db(0x0c);
+ db(0x50); db(0xeb); db(0x00); db(0x9e); db(0x20); db(0x6b); db(0x00); db(0xb4);
+ db(0x61); db(0x00); db(0x00); db(0x94); db(0x4e); db(0xae); db(0xff); db(0x76);
+ db(0x4c); db(0xdf); db(0x40); db(0x80); db(0x4e); db(0x75); db(0x48); db(0xe7);
+ db(0x01); db(0x22); db(0x2e); db(0x00); db(0x2c); db(0x6b); db(0x00); db(0xa0);
+ db(0x0c); db(0x6e); db(0x00); db(0x25); db(0x00); db(0x14); db(0x65); db(0x3e);
+ db(0x72); db(0x0e); db(0x4e); db(0xae); db(0xfd); db(0x66); db(0x02); db(0x80);
+ db(0xff); db(0xff); db(0xff); db(0xfe); db(0x67); db(0x62); db(0x08); db(0x07);
+ db(0x00); db(0x00); db(0x67); db(0x0a); db(0x41); db(0xeb); db(0x00); db(0x20);
+ db(0x22); db(0x08); db(0x4e); db(0xae); db(0xfd); db(0x60); db(0x08); db(0x07);
+ db(0x00); db(0x01); db(0x67); db(0x12); db(0x4a); db(0x2b); db(0x00); db(0x9e);
+ db(0x67); db(0x0c); db(0x42); db(0x2b); db(0x00); db(0x9e); db(0x22); db(0x2b);
+ db(0x00); db(0xb4); db(0x4e); db(0xae); db(0xfd); db(0x60); db(0x72); db(0x0e);
+ db(0x4e); db(0xae); db(0xfd); db(0x6c); db(0x60); db(0x32); db(0x2c); db(0x78);
+ db(0x00); db(0x04); db(0x4e); db(0xae); db(0xff); db(0x7c); db(0x08); db(0x07);
+ db(0x00); db(0x00); db(0x67); db(0x08); db(0x41); db(0xeb); db(0x00); db(0x20);
+ db(0x61); db(0x00); db(0x00); db(0x44); db(0x08); db(0x07); db(0x00); db(0x01);
+ db(0x67); db(0x12); db(0x4a); db(0x2b); db(0x00); db(0x9e); db(0x67); db(0x0c);
+ db(0x42); db(0x2b); db(0x00); db(0x9e); db(0x20); db(0x6b); db(0x00); db(0xb4);
+ db(0x61); db(0x00); db(0x00); db(0x2c); db(0x4e); db(0xae); db(0xff); db(0x76);
+ db(0x4c); db(0xdf); db(0x44); db(0x80); db(0x4e); db(0x75); db(0x22); db(0x48);
+ db(0x20); db(0x6b); db(0x00); db(0xa0); db(0x20); db(0x68); db(0x00); db(0x22);
+ db(0x20); db(0x68); db(0x00); db(0x18); db(0xd1); db(0xc8); db(0xd1); db(0xc8);
+ db(0x22); db(0xa8); db(0x00); db(0x04); db(0x20); db(0x09); db(0xe4); db(0x88);
+ db(0x21); db(0x40); db(0x00); db(0x04); db(0x4e); db(0x75); db(0x24); db(0x48);
+ db(0x20); db(0x6b); db(0x00); db(0xa0); db(0x20); db(0x68); db(0x00); db(0x22);
+ db(0x20); db(0x68); db(0x00); db(0x18); db(0xd1); db(0xc8); db(0xd1); db(0xc8);
+ db(0x22); db(0x68); db(0x00); db(0x04); db(0xd3); db(0xc9); db(0xd3); db(0xc9);
+ db(0xb3); db(0xca); db(0x66); db(0x06); db(0x21); db(0x52); db(0x00); db(0x04);
+ db(0x60); db(0x18); db(0x20); db(0x09); db(0x67); db(0x0e); db(0x20); db(0x11);
+ db(0xd0); db(0x80); db(0xd0); db(0x80); db(0xb5); db(0xc0); db(0x67); db(0x04);
+ db(0x22); db(0x40); db(0x60); db(0xee); db(0x20); db(0x09); db(0x67); db(0x02);
+ db(0x22); db(0x92); db(0x4e); db(0x75); db(0x48); db(0xe7); db(0x20); db(0x22);
+ db(0x74); db(0x16); db(0x9f); db(0xc2); db(0x24); db(0x4f); db(0x32); db(0x02);
+ db(0x42); db(0x32); db(0x10); db(0xff); db(0x53); db(0x41); db(0x66); db(0xf8);
+ db(0x2c); db(0x78); db(0x00); db(0x04); db(0x72); db(0x0f); db(0x4a); db(0x80);
+ db(0x67); db(0x02); db(0x72); db(0x10); db(0x15); db(0x41); db(0x00); db(0x04);
+ db(0x35); db(0x7c); db(0x08); db(0x00); db(0x00); db(0x08); db(0x22); db(0x6b);
+ db(0x00); db(0xa4); db(0x33); db(0x7c); db(0x00); db(0x0b); db(0x00); db(0x1c);
+ db(0x23); db(0x7c); db(0x00); db(0x00); db(0x00); db(0x16); db(0x00); db(0x24);
+ db(0x23); db(0x4a); db(0x00); db(0x28); db(0x13); db(0x7c); db(0x00); db(0x01);
+ db(0x00); db(0x1e); db(0x22); db(0x6b); db(0x00); db(0xa8); db(0x33); db(0x7c);
+ db(0x00); db(0x0a); db(0x00); db(0x1c); db(0x13); db(0x7c); db(0x00); db(0x01);
+ db(0x00); db(0x1e); db(0x4e); db(0xae); db(0xfe); db(0x38); db(0x22); db(0x6b);
+ db(0x00); db(0xa8); db(0x25); db(0x69); db(0x00); db(0x20); db(0x00); db(0x0e);
+ db(0x25); db(0x69); db(0x00); db(0x24); db(0x00); db(0x12); db(0x22); db(0x6b);
+ db(0x00); db(0xa4); db(0x4e); db(0xae); db(0xfe); db(0x38); db(0xdf); db(0xc2);
+ db(0x4c); db(0xdf); db(0x44); db(0x04); db(0x4e); db(0x75); db(0x4a); db(0x00);
+ db(0x67); db(0x26); db(0x4a); db(0x2b); db(0x00); db(0x60); db(0x66); db(0x36);
+ db(0x70); db(0x00); db(0x4a); db(0x33); db(0x00); db(0x61); db(0x67); db(0x04);
+ db(0x52); db(0x00); db(0x60); db(0xf6); db(0x17); db(0x40); db(0x00); db(0x60);
+ db(0x67); db(0x24); db(0x20); db(0x01); db(0x61); db(0x00); db(0xfd); db(0xf2);
+ db(0x70); db(0x01); db(0x61); db(0x00); db(0xff); db(0x60); db(0x60); db(0x16);
+ db(0x4a); db(0x2b); db(0x00); db(0x60); db(0x67); db(0x10); db(0x42); db(0x2b);
+ db(0x00); db(0x60); db(0x20); db(0x01); db(0x61); db(0x00); db(0xfe); db(0x68);
+ db(0x70); db(0x00); db(0x61); db(0x00); db(0xff); db(0x48); db(0x4e); db(0x75);
+ db(0x4a); db(0xac); db(0x00); db(0x14); db(0x67); db(0x0a); db(0x70); db(0x00);
+ db(0x72); db(0x01); db(0x61); db(0x00); db(0xff); db(0xb2); db(0x4e); db(0x75);
+ db(0x70); db(0x01); db(0x72); db(0x03); db(0x61); db(0x00); db(0xff); db(0xa8);
+ db(0x4e); db(0x75); db(0x20); db(0x2b); db(0x00); db(0xb8); db(0x0c); db(0x80);
+ db(0xff); db(0xff); db(0xff); db(0xff); db(0x67); db(0x18); db(0x20); db(0x6b);
+ db(0x00); db(0xb4); db(0x20); db(0x68); db(0x00); db(0x1c); db(0xd1); db(0xc8);
+ db(0xd1); db(0xc8); db(0x20); db(0x68); db(0x00); db(0x08); db(0xd1); db(0xc8);
+ db(0xd1); db(0xc8); db(0x21); db(0x40); db(0x00); db(0x28); db(0x4e); db(0x75);
+ db(0x61); db(0x00); db(0xff); db(0xd8); db(0x10); db(0x2b); db(0x00); db(0xac);
+ db(0x6b); db(0x0a); db(0x70); db(0x01); db(0x72); db(0x03); db(0x61); db(0x00);
+ db(0xff); db(0x6e); db(0x4e); db(0x75); db(0x72); db(0x01); db(0x0c); db(0x00);
+ db(0x00); db(0xfe); db(0x66); db(0x02); db(0x72); db(0x03); db(0x70); db(0x00);
+ db(0x61); db(0x00); db(0xff); db(0x5c); db(0x4e); db(0x75); db(0x20); db(0x6c);
+ db(0x00); db(0x24); db(0x4a); db(0x90); db(0x67); db(0x0c); db(0x4a); db(0xa8);
+ db(0x00); db(0x08); db(0x66); db(0x0a); db(0x4a); db(0xa8); db(0x00); db(0x0c);
+ db(0x66); db(0x04); db(0x70); db(0x01); db(0x4e); db(0x75); db(0x48); db(0xe7);
+ db(0x3f); db(0x3e); db(0x2a); db(0x48); db(0x24); db(0x6c); db(0x00); db(0x18);
+ db(0x2e); db(0x15); db(0x7a); db(0x00); db(0x4a); db(0x87); db(0x67); db(0x70);
+ db(0x20); db(0x0a); db(0x67); db(0x6c); db(0x7c); db(0x00); db(0x22); db(0x2d);
+ db(0x00); db(0x08); db(0x67); db(0x12); db(0x24); db(0x2a); db(0x00); db(0x04);
+ db(0x2c); db(0x6b); db(0x00); db(0xa0); db(0x4e); db(0xae); db(0xfc); db(0x34);
+ db(0x4a); db(0x80); db(0x66); db(0x02); db(0x50); db(0xc6); db(0x22); db(0x2d);
+ db(0x00); db(0x0c); db(0x67); db(0x1c); db(0x20); db(0x41); db(0x22); db(0x4a);
+ db(0x2f); db(0x0a); db(0x45); db(0xec); db(0x00); db(0x20); db(0x48); db(0x7a);
+ db(0x00); db(0x08); db(0x2f); db(0x28); db(0x00); db(0x08); db(0x4e); db(0x75);
+ db(0x24); db(0x5f); db(0x4a); db(0x80); db(0x66); db(0x02); db(0x50); db(0xc6);
+ db(0x4a); db(0x06); db(0x67); db(0x24); db(0x20); db(0x2a); db(0x00); db(0x04);
+ db(0x90); db(0x8a); db(0x4a); db(0x92); db(0x66); db(0x0a); db(0x20); db(0x05);
+ db(0x67); db(0x10); db(0x20); db(0x40); db(0x42); db(0x90); db(0x60); db(0x0a);
+ db(0x20); db(0x52); db(0x22); db(0x4a); db(0x22); db(0xd8); db(0x59); db(0x80);
+ db(0x6a); db(0xfa); db(0x53); db(0x95); db(0x53); db(0x87); db(0x60); db(0x94);
+ db(0x2a); db(0x0a); db(0x24); db(0x52); db(0x53); db(0x87); db(0x60); db(0x8c);
+ db(0x4c); db(0xdf); db(0x7c); db(0xfc); db(0x20); db(0x6c); db(0x00); db(0x24);
+ db(0x4a); db(0x90); db(0x4e); db(0x75); db(0x61); db(0x00); db(0xfc); db(0x4c);
+ db(0x21); db(0x40); db(0x01); db(0x9c); db(0x2f); db(0x08); db(0x30); db(0x3c);
+ db(0xff); db(0xec); db(0x61); db(0x00); db(0x1c); db(0x94); db(0x2a); db(0x50);
+ db(0x30); db(0x3c); db(0xff); db(0x28); db(0x61); db(0x00); db(0x1c); db(0x7a);
+ db(0x22); db(0x48); db(0x20); db(0x5f); db(0x42); db(0xa8); db(0x01); db(0x90);
+ db(0x42); db(0xa8); db(0x01); db(0x94); db(0x4e); db(0x91); db(0x26); db(0x00);
+ db(0x0c); db(0x43); db(0xff); db(0xfe); db(0x67); db(0x00); db(0xf6); db(0xb6);
+ db(0x20); db(0x28); db(0x01); db(0x90); db(0x67); db(0x14); db(0x6b); db(0x12);
+ db(0x2f); db(0x08); db(0x72); db(0x01); db(0x2c); db(0x78); db(0x00); db(0x04);
+ db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x20); db(0x5f); db(0x21); db(0x40);
+ db(0x01); db(0x94); db(0x4a); db(0x83); db(0x6a); db(0x0e); db(0x22); db(0x48);
+ db(0x30); db(0x3c); db(0xff); db(0x20); db(0x61); db(0x00); db(0x1c); db(0x3a);
+ db(0x4e); db(0x90); db(0x60); db(0x26); db(0x2c); db(0x4c); db(0x2f); db(0x08);
+ db(0x61); db(0x00); db(0x0f); db(0xf6); db(0x20); db(0x5f); db(0x22); db(0x48);
+ db(0x26); db(0x40); db(0x30); db(0x3c); db(0xff); db(0x20); db(0x61); db(0x00);
+ db(0x1c); db(0x20); db(0x4e); db(0x90); db(0x70); db(0x00); db(0x27); db(0x40);
+ db(0x00); db(0x08); db(0x27); db(0x40); db(0x00); db(0x10); db(0x27); db(0x40);
+ db(0x00); db(0x20); db(0x20); db(0x69); db(0x01); db(0x94); db(0x4a); db(0xa9);
+ db(0x01); db(0x90); db(0x67); db(0x2c); db(0x20); db(0x08); db(0x67); db(0x32);
+ db(0x61); db(0x00); db(0xfa); db(0xbc); db(0x48); db(0xe7); db(0x80); db(0xc0);
+ db(0x20); db(0x29); db(0x01); db(0x90); db(0x22); db(0x69); db(0x01); db(0x94);
+ db(0x2c); db(0x78); db(0x00); db(0x04); db(0x4e); db(0xae); db(0xff); db(0x2e);
+ db(0x4c); db(0xdf); db(0x03); db(0x01); db(0x42); db(0xa9); db(0x01); db(0x90);
+ db(0x23); db(0x48); db(0x01); db(0x94); db(0x4a); db(0x80); db(0x67); db(0x0a);
+ db(0x4a); db(0xa9); db(0x01); db(0x98); db(0x67); db(0x04); db(0x61); db(0x00);
+ db(0xfa); db(0x38); db(0x4a); db(0x83); db(0x6b); db(0x00); db(0xf6); db(0x1e);
+ db(0x2c); db(0x78); db(0x00); db(0x04); db(0x2f); db(0x09); db(0x43); db(0xfa);
+ db(0x1d); db(0x69); db(0x4e); db(0xae); db(0xfe); db(0xda); db(0x22); db(0x5f);
+ db(0x22); db(0x00); db(0x30); db(0x3c); db(0xff); db(0x18); db(0x61); db(0x00);
+ db(0x1b); db(0xb0); db(0x4e); db(0x90); db(0x20); db(0x03); db(0x16); db(0x29);
+ db(0x00); db(0x4f); db(0x4a); db(0x80); db(0x66); db(0x24); db(0x27); db(0x7c);
+ db(0x00); db(0x00); db(0x17); db(0x70); db(0x00); db(0x14); db(0x41); db(0xfa);
+ db(0xf3); db(0x9c); db(0x70); db(0xff); db(0x22); db(0x0c); db(0x66); db(0x06);
+ db(0x41); db(0xfa); db(0xf3); db(0xde); db(0x70); db(0x00); db(0x27); db(0x40);
+ db(0x00); db(0x24); db(0x20); db(0x08); db(0xe4); db(0x88); db(0x27); db(0x40);
+ db(0x00); db(0x20); db(0x08); db(0x07); db(0x00); db(0x03); db(0x66); db(0x48);
+ db(0x08); db(0x07); db(0x00); db(0x00); db(0x67); db(0x42); db(0x0c); db(0x03);
+ db(0x00); db(0x80); db(0x67); db(0x3c); db(0x2c); db(0x78); db(0x00); db(0x04);
+ db(0x70); db(0x14); db(0x22); db(0x3c); db(0x00); db(0x01); db(0x00); db(0x01);
+ db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x22); db(0x40); db(0x30); db(0x3c);
+ db(0x10); db(0x00); db(0x80); db(0x03); db(0x33); db(0x40); db(0x00); db(0x08);
+ db(0x23); db(0x6d); db(0x01); db(0x04); db(0x00); db(0x0a); db(0x23); db(0x4b);
+ db(0x00); db(0x10); db(0x41); db(0xec); db(0x00); db(0x4a); db(0x4e); db(0xae);
+ db(0xff); db(0x7c); db(0x4e); db(0xae); db(0xfe); db(0xf2); db(0x4e); db(0xae);
+ db(0xff); db(0x76); db(0x72); db(0x00); db(0x70); db(0x00); db(0x4e); db(0x75);
+ db(0x76); db(0x00); db(0x24); db(0x49); db(0x20); db(0x4b); db(0x72); db(0x00);
+ db(0x22); db(0x41); db(0x08); db(0x07); db(0x00); db(0x01); db(0x67); db(0x08);
+ db(0x08); db(0x07); db(0x00); db(0x02); db(0x67); db(0x02); db(0x72); db(0x01);
+ db(0x70); db(0x80); db(0x2c); db(0x4c); db(0x61); db(0x00); db(0x0f); db(0x92);
+ db(0x08); db(0x07); db(0x00); db(0x01); db(0x67); db(0x6a); db(0x08); db(0x07);
+ db(0x00); db(0x02); db(0x66); db(0x64); db(0x20); db(0x52); db(0x74); db(0x02);
+ db(0x52); db(0x82); db(0x4a); db(0x30); db(0x28); db(0xfd); db(0x66); db(0xf8);
+ db(0x2c); db(0x78); db(0x00); db(0x04); db(0x06); db(0x82); db(0x00); db(0x00);
+ db(0x10); db(0x04); db(0x20); db(0x02); db(0x72); db(0x01); db(0x4e); db(0xae);
+ db(0xff); db(0x3a); db(0x4a); db(0x80); db(0x67); db(0x42); db(0x20); db(0x52);
+ db(0x24); db(0x40); db(0x22); db(0x4a); db(0x12); db(0xd8); db(0x66); db(0xfc);
+ db(0x13); db(0x7c); db(0x00); db(0x3a); db(0xff); db(0xff); db(0x42); db(0x11);
+ db(0x2c); db(0x78); db(0x00); db(0x04); db(0x43); db(0xfa); db(0x1c); db(0x0e);
+ db(0x4e); db(0xae); db(0xfe); db(0x68); db(0x2c); db(0x40); db(0x22); db(0x0a);
+ db(0x26); db(0x0f); db(0x4f); db(0xea); db(0x10); db(0x04); db(0x4e); db(0xae);
+ db(0xff); db(0x52); db(0x2e); db(0x43); db(0x26); db(0x01); db(0x22); db(0x4e);
+ db(0x2c); db(0x78); db(0x00); db(0x04); db(0x4e); db(0xae); db(0xfe); db(0x62);
+ db(0x22); db(0x4a); db(0x20); db(0x02); db(0x4e); db(0xae); db(0xff); db(0x2e);
+ db(0x22); db(0x03); db(0x70); db(0x00); db(0x4e); db(0x75); db(0x48); db(0xe7);
+ db(0x3f); db(0x3e); db(0x2c); db(0x01); db(0x7e); db(0x06); db(0x2c); db(0x78);
+ db(0x00); db(0x04); db(0x43); db(0xfa); db(0x1b); db(0xff); db(0x70); db(0x24);
+ db(0x4e); db(0xae); db(0xfd); db(0xd8); db(0x4a); db(0x80); db(0x66); db(0x0e);
+ db(0x08); db(0x87); db(0x00); db(0x02); db(0x43); db(0xfa); db(0x1b); db(0xed);
+ db(0x70); db(0x00); db(0x4e); db(0xae); db(0xfd); db(0xd8); db(0x28); db(0x40);
+ db(0x20); db(0x3c); db(0x00); db(0x00); db(0x02); db(0x38); db(0x22); db(0x3c);
  db(0x00); db(0x01); db(0x00); db(0x01); db(0x4e); db(0xae); db(0xff); db(0x3a);
- db(0x24); db(0x40); db(0x15); db(0x7c); db(0x00); db(0x08); db(0x00); db(0x08);
- db(0x41); db(0xfa); db(0x1b); db(0x08); db(0x25); db(0x48); db(0x00); db(0x0a);
- db(0x41); db(0xfa); db(0x1a); db(0x61); db(0x25); db(0x48); db(0x00); db(0x0e);
- db(0x41); db(0xea); db(0x00); db(0x12); db(0x20); db(0x88); db(0x58); db(0x90);
- db(0x21); db(0x48); db(0x00); db(0x08); db(0x41); db(0xee); db(0x01); db(0x50);
- db(0x22); db(0x4a); db(0x4e); db(0xae); db(0xff); db(0x0a); db(0x20); db(0x4a);
- db(0x27); db(0x48); db(0x01); db(0xa0); db(0x20); db(0x08); db(0x4c); db(0xdf);
- db(0x4f); db(0x02); db(0x4e); db(0x75); db(0x48); db(0xe7); db(0x01); db(0x02);
- db(0x2e); db(0x00); db(0x4a); db(0x2b); db(0x00); db(0x60); db(0x67); db(0x7c);
- db(0x2c); db(0x6b); db(0x00); db(0xa0); db(0x0c); db(0x6e); db(0x00); db(0x25);
- db(0x00); db(0x14); db(0x65); db(0x3e); db(0x72); db(0x0e); db(0x4e); db(0xae);
- db(0xfd); db(0x66); db(0x02); db(0x80); db(0xff); db(0xff); db(0xff); db(0xfe);
- db(0x67); db(0x62); db(0x08); db(0x07); db(0x00); db(0x00); db(0x67); db(0x0a);
- db(0x41); db(0xeb); db(0x00); db(0x20); db(0x22); db(0x08); db(0x4e); db(0xae);
- db(0xfd); db(0x5a); db(0x08); db(0x07); db(0x00); db(0x01); db(0x67); db(0x12);
- db(0x4a); db(0x2b); db(0x00); db(0x9e); db(0x66); db(0x0c); db(0x50); db(0xeb);
- db(0x00); db(0x9e); db(0x22); db(0x2b); db(0x00); db(0xb4); db(0x4e); db(0xae);
- db(0xfd); db(0x5a); db(0x72); db(0x0e); db(0x4e); db(0xae); db(0xfd); db(0x6c);
- db(0x60); db(0x32); db(0x2c); db(0x78); db(0x00); db(0x04); db(0x4e); db(0xae);
- db(0xff); db(0x7c); db(0x08); db(0x07); db(0x00); db(0x00); db(0x67); db(0x08);
- db(0x41); db(0xeb); db(0x00); db(0x20); db(0x61); db(0x00); db(0x00); db(0xac);
- db(0x08); db(0x07); db(0x00); db(0x01); db(0x67); db(0x12); db(0x4a); db(0x2b);
- db(0x00); db(0x9e); db(0x66); db(0x0c); db(0x50); db(0xeb); db(0x00); db(0x9e);
- db(0x20); db(0x6b); db(0x00); db(0xb4); db(0x61); db(0x00); db(0x00); db(0x94);
- db(0x4e); db(0xae); db(0xff); db(0x76); db(0x4c); db(0xdf); db(0x40); db(0x80);
- db(0x4e); db(0x75); db(0x48); db(0xe7); db(0x01); db(0x22); db(0x2e); db(0x00);
- db(0x2c); db(0x6b); db(0x00); db(0xa0); db(0x0c); db(0x6e); db(0x00); db(0x25);
- db(0x00); db(0x14); db(0x65); db(0x3e); db(0x72); db(0x0e); db(0x4e); db(0xae);
- db(0xfd); db(0x66); db(0x02); db(0x80); db(0xff); db(0xff); db(0xff); db(0xfe);
- db(0x67); db(0x62); db(0x08); db(0x07); db(0x00); db(0x00); db(0x67); db(0x0a);
- db(0x41); db(0xeb); db(0x00); db(0x20); db(0x22); db(0x08); db(0x4e); db(0xae);
- db(0xfd); db(0x60); db(0x08); db(0x07); db(0x00); db(0x01); db(0x67); db(0x12);
- db(0x4a); db(0x2b); db(0x00); db(0x9e); db(0x67); db(0x0c); db(0x42); db(0x2b);
- db(0x00); db(0x9e); db(0x22); db(0x2b); db(0x00); db(0xb4); db(0x4e); db(0xae);
- db(0xfd); db(0x60); db(0x72); db(0x0e); db(0x4e); db(0xae); db(0xfd); db(0x6c);
- db(0x60); db(0x32); db(0x2c); db(0x78); db(0x00); db(0x04); db(0x4e); db(0xae);
- db(0xff); db(0x7c); db(0x08); db(0x07); db(0x00); db(0x00); db(0x67); db(0x08);
- db(0x41); db(0xeb); db(0x00); db(0x20); db(0x61); db(0x00); db(0x00); db(0x44);
- db(0x08); db(0x07); db(0x00); db(0x01); db(0x67); db(0x12); db(0x4a); db(0x2b);
- db(0x00); db(0x9e); db(0x67); db(0x0c); db(0x42); db(0x2b); db(0x00); db(0x9e);
- db(0x20); db(0x6b); db(0x00); db(0xb4); db(0x61); db(0x00); db(0x00); db(0x2c);
- db(0x4e); db(0xae); db(0xff); db(0x76); db(0x4c); db(0xdf); db(0x44); db(0x80);
- db(0x4e); db(0x75); db(0x22); db(0x48); db(0x20); db(0x6b); db(0x00); db(0xa0);
- db(0x20); db(0x68); db(0x00); db(0x22); db(0x20); db(0x68); db(0x00); db(0x18);
- db(0xd1); db(0xc8); db(0xd1); db(0xc8); db(0x22); db(0xa8); db(0x00); db(0x04);
- db(0x20); db(0x09); db(0xe4); db(0x88); db(0x21); db(0x40); db(0x00); db(0x04);
- db(0x4e); db(0x75); db(0x24); db(0x48); db(0x20); db(0x6b); db(0x00); db(0xa0);
- db(0x20); db(0x68); db(0x00); db(0x22); db(0x20); db(0x68); db(0x00); db(0x18);
- db(0xd1); db(0xc8); db(0xd1); db(0xc8); db(0x22); db(0x68); db(0x00); db(0x04);
- db(0xd3); db(0xc9); db(0xd3); db(0xc9); db(0xb3); db(0xca); db(0x66); db(0x06);
- db(0x21); db(0x52); db(0x00); db(0x04); db(0x60); db(0x18); db(0x20); db(0x09);
- db(0x67); db(0x0e); db(0x20); db(0x11); db(0xd0); db(0x80); db(0xd0); db(0x80);
- db(0xb5); db(0xc0); db(0x67); db(0x04); db(0x22); db(0x40); db(0x60); db(0xee);
- db(0x20); db(0x09); db(0x67); db(0x02); db(0x22); db(0x92); db(0x4e); db(0x75);
- db(0x48); db(0xe7); db(0x20); db(0x22); db(0x74); db(0x16); db(0x9f); db(0xc2);
- db(0x24); db(0x4f); db(0x32); db(0x02); db(0x42); db(0x32); db(0x10); db(0xff);
- db(0x53); db(0x41); db(0x66); db(0xf8); db(0x2c); db(0x78); db(0x00); db(0x04);
- db(0x72); db(0x0f); db(0x4a); db(0x80); db(0x67); db(0x02); db(0x72); db(0x10);
- db(0x15); db(0x41); db(0x00); db(0x04); db(0x35); db(0x7c); db(0x08); db(0x00);
- db(0x00); db(0x08); db(0x22); db(0x6b); db(0x00); db(0xa4); db(0x33); db(0x7c);
- db(0x00); db(0x0b); db(0x00); db(0x1c); db(0x23); db(0x7c); db(0x00); db(0x00);
- db(0x00); db(0x16); db(0x00); db(0x24); db(0x23); db(0x4a); db(0x00); db(0x28);
- db(0x13); db(0x7c); db(0x00); db(0x01); db(0x00); db(0x1e); db(0x22); db(0x6b);
- db(0x00); db(0xa8); db(0x33); db(0x7c); db(0x00); db(0x0a); db(0x00); db(0x1c);
+ db(0x20); db(0x40); db(0x4a); db(0x80); db(0x67); db(0x2c); db(0x21); db(0x4c);
+ db(0x01); db(0xa8); db(0x48); db(0xe7); db(0x00); db(0x8a); db(0x61); db(0x00);
+ db(0xfd); db(0xbc); db(0x4c); db(0xdf); db(0x51); db(0x00); db(0x0c); db(0x80);
+ db(0xff); db(0xff); db(0xff); db(0xfe); db(0x67); db(0x08); db(0x48); db(0x46);
+ db(0x52); db(0x46); db(0x48); db(0x46); db(0x60); db(0xe4); db(0x22); db(0x48);
+ db(0x20); db(0x3c); db(0x00); db(0x00); db(0x02); db(0x38); db(0x4e); db(0xae);
+ db(0xff); db(0x2e); db(0x22); db(0x4c); db(0x4e); db(0xae); db(0xfe); db(0x62);
+ db(0x4c); db(0xdf); db(0x7c); db(0xfc); db(0x4e); db(0x75); db(0x30); db(0x3c);
+ db(0xff); db(0x58); db(0x61); db(0x00); db(0x1a); db(0x1c); db(0x70); db(0x03);
+ db(0x4e); db(0x90); db(0x22); db(0x6b); db(0x00); db(0xa8); db(0x23); db(0x40);
+ db(0x00); db(0x20); db(0x67); db(0x16); db(0x70); db(0x00); db(0x23); db(0x40);
+ db(0x00); db(0x24); db(0x33); db(0x7c); db(0x00); db(0x0b); db(0x00); db(0x1c);
  db(0x13); db(0x7c); db(0x00); db(0x01); db(0x00); db(0x1e); db(0x4e); db(0xae);
- db(0xfe); db(0x38); db(0x22); db(0x6b); db(0x00); db(0xa8); db(0x25); db(0x69);
- db(0x00); db(0x20); db(0x00); db(0x0e); db(0x25); db(0x69); db(0x00); db(0x24);
- db(0x00); db(0x12); db(0x22); db(0x6b); db(0x00); db(0xa4); db(0x4e); db(0xae);
- db(0xfe); db(0x38); db(0xdf); db(0xc2); db(0x4c); db(0xdf); db(0x44); db(0x04);
- db(0x4e); db(0x75); db(0x4a); db(0x00); db(0x67); db(0x26); db(0x4a); db(0x2b);
- db(0x00); db(0x60); db(0x66); db(0x36); db(0x70); db(0x00); db(0x4a); db(0x33);
- db(0x00); db(0x61); db(0x67); db(0x04); db(0x52); db(0x00); db(0x60); db(0xf6);
- db(0x17); db(0x40); db(0x00); db(0x60); db(0x67); db(0x24); db(0x20); db(0x01);
- db(0x61); db(0x00); db(0xfd); db(0xf2); db(0x70); db(0x01); db(0x61); db(0x00);
- db(0xff); db(0x60); db(0x60); db(0x16); db(0x4a); db(0x2b); db(0x00); db(0x60);
- db(0x67); db(0x10); db(0x42); db(0x2b); db(0x00); db(0x60); db(0x20); db(0x01);
- db(0x61); db(0x00); db(0xfe); db(0x68); db(0x70); db(0x00); db(0x61); db(0x00);
- db(0xff); db(0x48); db(0x4e); db(0x75); db(0x4a); db(0xac); db(0x00); db(0x14);
- db(0x67); db(0x0a); db(0x70); db(0x00); db(0x72); db(0x01); db(0x61); db(0x00);
- db(0xff); db(0xb2); db(0x4e); db(0x75); db(0x70); db(0x01); db(0x72); db(0x03);
- db(0x61); db(0x00); db(0xff); db(0xa8); db(0x4e); db(0x75); db(0x20); db(0x2b);
- db(0x00); db(0xb8); db(0x0c); db(0x80); db(0xff); db(0xff); db(0xff); db(0xff);
- db(0x67); db(0x18); db(0x20); db(0x6b); db(0x00); db(0xb4); db(0x20); db(0x68);
- db(0x00); db(0x1c); db(0xd1); db(0xc8); db(0xd1); db(0xc8); db(0x20); db(0x68);
- db(0x00); db(0x08); db(0xd1); db(0xc8); db(0xd1); db(0xc8); db(0x21); db(0x40);
- db(0x00); db(0x28); db(0x4e); db(0x75); db(0x61); db(0x00); db(0xff); db(0xd8);
- db(0x10); db(0x2b); db(0x00); db(0xac); db(0x6b); db(0x0a); db(0x70); db(0x01);
- db(0x72); db(0x03); db(0x61); db(0x00); db(0xff); db(0x6e); db(0x4e); db(0x75);
- db(0x72); db(0x01); db(0x0c); db(0x00); db(0x00); db(0xfe); db(0x66); db(0x02);
- db(0x72); db(0x03); db(0x70); db(0x00); db(0x61); db(0x00); db(0xff); db(0x5c);
- db(0x4e); db(0x75); db(0x20); db(0x6c); db(0x00); db(0x24); db(0x4a); db(0x90);
- db(0x67); db(0x0c); db(0x4a); db(0xa8); db(0x00); db(0x08); db(0x66); db(0x0a);
- db(0x4a); db(0xa8); db(0x00); db(0x0c); db(0x66); db(0x04); db(0x70); db(0x01);
- db(0x4e); db(0x75); db(0x48); db(0xe7); db(0x3f); db(0x3e); db(0x2a); db(0x48);
- db(0x24); db(0x6c); db(0x00); db(0x18); db(0x2e); db(0x15); db(0x7a); db(0x00);
- db(0x4a); db(0x87); db(0x67); db(0x70); db(0x20); db(0x0a); db(0x67); db(0x6c);
- db(0x7c); db(0x00); db(0x22); db(0x2d); db(0x00); db(0x08); db(0x67); db(0x12);
- db(0x24); db(0x2a); db(0x00); db(0x04); db(0x2c); db(0x6b); db(0x00); db(0xa0);
- db(0x4e); db(0xae); db(0xfc); db(0x34); db(0x4a); db(0x80); db(0x66); db(0x02);
- db(0x50); db(0xc6); db(0x22); db(0x2d); db(0x00); db(0x0c); db(0x67); db(0x1c);
- db(0x20); db(0x41); db(0x22); db(0x4a); db(0x2f); db(0x0a); db(0x45); db(0xec);
- db(0x00); db(0x20); db(0x48); db(0x7a); db(0x00); db(0x08); db(0x2f); db(0x28);
- db(0x00); db(0x08); db(0x4e); db(0x75); db(0x24); db(0x5f); db(0x4a); db(0x80);
- db(0x66); db(0x02); db(0x50); db(0xc6); db(0x4a); db(0x06); db(0x67); db(0x24);
- db(0x20); db(0x2a); db(0x00); db(0x04); db(0x90); db(0x8a); db(0x4a); db(0x92);
- db(0x66); db(0x0a); db(0x20); db(0x05); db(0x67); db(0x10); db(0x20); db(0x40);
- db(0x42); db(0x90); db(0x60); db(0x0a); db(0x20); db(0x52); db(0x22); db(0x4a);
- db(0x22); db(0xd8); db(0x59); db(0x80); db(0x6a); db(0xfa); db(0x53); db(0x95);
- db(0x53); db(0x87); db(0x60); db(0x94); db(0x2a); db(0x0a); db(0x24); db(0x52);
- db(0x53); db(0x87); db(0x60); db(0x8c); db(0x4c); db(0xdf); db(0x7c); db(0xfc);
- db(0x20); db(0x6c); db(0x00); db(0x24); db(0x4a); db(0x90); db(0x4e); db(0x75);
- db(0x61); db(0x00); db(0xfc); db(0x4c); db(0x21); db(0x40); db(0x01); db(0x9c);
- db(0x2f); db(0x08); db(0x30); db(0x3c); db(0xff); db(0xec); db(0x61); db(0x00);
- db(0x16); db(0x24); db(0x2a); db(0x50); db(0x30); db(0x3c); db(0xff); db(0x28);
- db(0x61); db(0x00); db(0x16); db(0x0a); db(0x22); db(0x48); db(0x20); db(0x5f);
- db(0x42); db(0xa8); db(0x01); db(0x90); db(0x42); db(0xa8); db(0x01); db(0x94);
- db(0x4e); db(0x91); db(0x26); db(0x00); db(0x0c); db(0x43); db(0xff); db(0xfe);
- db(0x67); db(0x00); db(0xf6); db(0xb6); db(0x20); db(0x28); db(0x01); db(0x90);
- db(0x67); db(0x14); db(0x6b); db(0x12); db(0x2f); db(0x08); db(0x72); db(0x01);
- db(0x2c); db(0x78); db(0x00); db(0x04); db(0x4e); db(0xae); db(0xff); db(0x3a);
- db(0x20); db(0x5f); db(0x21); db(0x40); db(0x01); db(0x94); db(0x4a); db(0x83);
- db(0x6a); db(0x0e); db(0x22); db(0x48); db(0x30); db(0x3c); db(0xff); db(0x20);
- db(0x61); db(0x00); db(0x15); db(0xca); db(0x4e); db(0x90); db(0x60); db(0x26);
- db(0x2c); db(0x4c); db(0x2f); db(0x08); db(0x61); db(0x00); db(0x0f); db(0xf6);
- db(0x20); db(0x5f); db(0x22); db(0x48); db(0x26); db(0x40); db(0x30); db(0x3c);
- db(0xff); db(0x20); db(0x61); db(0x00); db(0x15); db(0xb0); db(0x4e); db(0x90);
- db(0x70); db(0x00); db(0x27); db(0x40); db(0x00); db(0x08); db(0x27); db(0x40);
- db(0x00); db(0x10); db(0x27); db(0x40); db(0x00); db(0x20); db(0x20); db(0x69);
- db(0x01); db(0x94); db(0x4a); db(0xa9); db(0x01); db(0x90); db(0x67); db(0x2c);
- db(0x20); db(0x08); db(0x67); db(0x32); db(0x61); db(0x00); db(0xfa); db(0xbc);
- db(0x48); db(0xe7); db(0x80); db(0xc0); db(0x20); db(0x29); db(0x01); db(0x90);
- db(0x22); db(0x69); db(0x01); db(0x94); db(0x2c); db(0x78); db(0x00); db(0x04);
- db(0x4e); db(0xae); db(0xff); db(0x2e); db(0x4c); db(0xdf); db(0x03); db(0x01);
- db(0x42); db(0xa9); db(0x01); db(0x90); db(0x23); db(0x48); db(0x01); db(0x94);
- db(0x4a); db(0x80); db(0x67); db(0x0a); db(0x4a); db(0xa9); db(0x01); db(0x98);
- db(0x67); db(0x04); db(0x61); db(0x00); db(0xfa); db(0x38); db(0x4a); db(0x83);
- db(0x6b); db(0x00); db(0xf6); db(0x1e); db(0x2c); db(0x78); db(0x00); db(0x04);
- db(0x2f); db(0x09); db(0x43); db(0xfa); db(0x16); db(0xea); db(0x4e); db(0xae);
- db(0xfe); db(0xda); db(0x22); db(0x5f); db(0x22); db(0x00); db(0x30); db(0x3c);
- db(0xff); db(0x18); db(0x61); db(0x00); db(0x15); db(0x40); db(0x4e); db(0x90);
- db(0x20); db(0x03); db(0x16); db(0x29); db(0x00); db(0x4f); db(0x4a); db(0x80);
- db(0x66); db(0x24); db(0x27); db(0x7c); db(0x00); db(0x00); db(0x17); db(0x70);
- db(0x00); db(0x14); db(0x41); db(0xfa); db(0xf3); db(0xa0); db(0x70); db(0xff);
- db(0x22); db(0x0c); db(0x66); db(0x06); db(0x41); db(0xfa); db(0xf3); db(0xde);
- db(0x70); db(0x00); db(0x27); db(0x40); db(0x00); db(0x24); db(0x20); db(0x08);
- db(0xe4); db(0x88); db(0x27); db(0x40); db(0x00); db(0x20); db(0x08); db(0x07);
- db(0x00); db(0x03); db(0x66); db(0x48); db(0x08); db(0x07); db(0x00); db(0x00);
- db(0x67); db(0x42); db(0x0c); db(0x03); db(0x00); db(0x80); db(0x67); db(0x3c);
- db(0x2c); db(0x78); db(0x00); db(0x04); db(0x70); db(0x14); db(0x22); db(0x3c);
- db(0x00); db(0x01); db(0x00); db(0x01); db(0x4e); db(0xae); db(0xff); db(0x3a);
- db(0x22); db(0x40); db(0x30); db(0x3c); db(0x10); db(0x00); db(0x80); db(0x03);
- db(0x33); db(0x40); db(0x00); db(0x08); db(0x23); db(0x6d); db(0x01); db(0x04);
- db(0x00); db(0x0a); db(0x23); db(0x4b); db(0x00); db(0x10); db(0x41); db(0xec);
- db(0x00); db(0x4a); db(0x4e); db(0xae); db(0xff); db(0x7c); db(0x4e); db(0xae);
- db(0xfe); db(0xf2); db(0x4e); db(0xae); db(0xff); db(0x76); db(0x72); db(0x00);
- db(0x70); db(0x00); db(0x4e); db(0x75); db(0x76); db(0x00); db(0x24); db(0x49);
- db(0x20); db(0x4b); db(0x72); db(0x00); db(0x22); db(0x41); db(0x08); db(0x07);
- db(0x00); db(0x01); db(0x67); db(0x08); db(0x08); db(0x07); db(0x00); db(0x02);
- db(0x67); db(0x02); db(0x72); db(0x01); db(0x70); db(0x80); db(0x2c); db(0x4c);
- db(0x61); db(0x00); db(0x0f); db(0x92); db(0x08); db(0x07); db(0x00); db(0x01);
- db(0x67); db(0x6a); db(0x08); db(0x07); db(0x00); db(0x02); db(0x66); db(0x64);
- db(0x20); db(0x52); db(0x74); db(0x02); db(0x52); db(0x82); db(0x4a); db(0x30);
- db(0x28); db(0xfd); db(0x66); db(0xf8); db(0x2c); db(0x78); db(0x00); db(0x04);
- db(0x06); db(0x82); db(0x00); db(0x00); db(0x10); db(0x04); db(0x20); db(0x02);
- db(0x72); db(0x01); db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x4a); db(0x80);
- db(0x67); db(0x42); db(0x20); db(0x52); db(0x24); db(0x40); db(0x22); db(0x4a);
- db(0x12); db(0xd8); db(0x66); db(0xfc); db(0x13); db(0x7c); db(0x00); db(0x3a);
- db(0xff); db(0xff); db(0x42); db(0x11); db(0x2c); db(0x78); db(0x00); db(0x04);
- db(0x43); db(0xfa); db(0x15); db(0x8f); db(0x4e); db(0xae); db(0xfe); db(0x68);
- db(0x2c); db(0x40); db(0x22); db(0x0a); db(0x26); db(0x0f); db(0x4f); db(0xea);
- db(0x10); db(0x04); db(0x4e); db(0xae); db(0xff); db(0x52); db(0x2e); db(0x43);
- db(0x26); db(0x01); db(0x22); db(0x4e); db(0x2c); db(0x78); db(0x00); db(0x04);
- db(0x4e); db(0xae); db(0xfe); db(0x62); db(0x22); db(0x4a); db(0x20); db(0x02);
- db(0x4e); db(0xae); db(0xff); db(0x2e); db(0x22); db(0x03); db(0x70); db(0x00);
- db(0x4e); db(0x75); db(0x48); db(0xe7); db(0x3f); db(0x3e); db(0x2c); db(0x01);
- db(0x7e); db(0x06); db(0x2c); db(0x78); db(0x00); db(0x04); db(0x43); db(0xfa);
- db(0x15); db(0x80); db(0x70); db(0x24); db(0x4e); db(0xae); db(0xfd); db(0xd8);
- db(0x4a); db(0x80); db(0x66); db(0x0e); db(0x08); db(0x87); db(0x00); db(0x02);
- db(0x43); db(0xfa); db(0x15); db(0x6e); db(0x70); db(0x00); db(0x4e); db(0xae);
- db(0xfd); db(0xd8); db(0x28); db(0x40); db(0x20); db(0x3c); db(0x00); db(0x00);
- db(0x02); db(0x38); db(0x22); db(0x3c); db(0x00); db(0x01); db(0x00); db(0x01);
- db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x20); db(0x40); db(0x4a); db(0x80);
- db(0x67); db(0x2c); db(0x21); db(0x4c); db(0x01); db(0xa8); db(0x48); db(0xe7);
- db(0x00); db(0x8a); db(0x61); db(0x00); db(0xfd); db(0xbc); db(0x4c); db(0xdf);
- db(0x51); db(0x00); db(0x0c); db(0x80); db(0xff); db(0xff); db(0xff); db(0xfe);
- db(0x67); db(0x08); db(0x48); db(0x46); db(0x52); db(0x46); db(0x48); db(0x46);
- db(0x60); db(0xe4); db(0x22); db(0x48); db(0x20); db(0x3c); db(0x00); db(0x00);
- db(0x02); db(0x38); db(0x4e); db(0xae); db(0xff); db(0x2e); db(0x22); db(0x4c);
- db(0x4e); db(0xae); db(0xfe); db(0x62); db(0x4c); db(0xdf); db(0x7c); db(0xfc);
- db(0x4e); db(0x75); db(0x30); db(0x3c); db(0xff); db(0x58); db(0x61); db(0x00);
- db(0x13); db(0xac); db(0x70); db(0x03); db(0x4e); db(0x90); db(0x22); db(0x6b);
- db(0x00); db(0xa8); db(0x23); db(0x40); db(0x00); db(0x20); db(0x67); db(0x16);
- db(0x70); db(0x00); db(0x23); db(0x40); db(0x00); db(0x24); db(0x33); db(0x7c);
- db(0x00); db(0x0b); db(0x00); db(0x1c); db(0x13); db(0x7c); db(0x00); db(0x01);
- db(0x00); db(0x1e); db(0x4e); db(0xae); db(0xfe); db(0x38); db(0x4e); db(0x75);
- db(0x7e); db(0x00); db(0x2c); db(0x78); db(0x00); db(0x04); db(0x93); db(0xc9);
- db(0x4e); db(0xae); db(0xfe); db(0xda); db(0x20); db(0x40); db(0x4b); db(0xe8);
- db(0x00); db(0x5c); db(0x43); db(0xfa); db(0x14); db(0xa5); db(0x4e); db(0xae);
- db(0xfe); db(0x68); db(0x24); db(0x40); db(0x22); db(0x3c); db(0x00); db(0x00);
- db(0x00); db(0xbc); db(0x30); db(0x3c); db(0xff); db(0x40); db(0x61); db(0x00);
- db(0x13); db(0x5c); db(0x70); db(0x01); db(0x4e); db(0x90); db(0x4a); db(0x80);
- db(0x66); db(0x0c); db(0x20); db(0x01); db(0x22); db(0x3c); db(0x00); db(0x01);
- db(0x00); db(0x01); db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x26); db(0x40);
- db(0x7c); db(0x00); db(0x26); db(0x86); db(0x27); db(0x46); db(0x00); db(0x04);
- db(0x27); db(0x46); db(0x00); db(0x08); db(0x27); db(0x4a); db(0x00); db(0xa0);
- db(0x50); db(0xeb); db(0x00); db(0x9e); db(0x70); db(0xff); db(0x27); db(0x40);
- db(0x00); db(0xb8); db(0x93); db(0xc9); db(0x4e); db(0xae); db(0xfe); db(0xda);
- db(0x27); db(0x40); db(0x00); db(0xb0); db(0x41); db(0xfa); db(0x13); db(0x40);
- db(0x70); db(0x00); db(0x72); db(0x00); db(0x61); db(0x00); db(0x02); db(0xcc);
- db(0x27); db(0x40); db(0x00); db(0xa4); db(0x41); db(0xfa); db(0x13); db(0x3d);
- db(0x70); db(0x00); db(0x72); db(0x00); db(0x61); db(0x00); db(0x02); db(0xbc);
- db(0x27); db(0x40); db(0x00); db(0xa8); db(0x7a); db(0x00); db(0x26); db(0x07);
- db(0x66); db(0x12); db(0x20); db(0x4d); db(0x4e); db(0xae); db(0xfe); db(0x80);
- db(0x20); db(0x4d); db(0x4e); db(0xae); db(0xfe); db(0x8c); db(0x28); db(0x40);
- db(0x26); db(0x2c); db(0x00); db(0x0a); db(0x30); db(0x3c); db(0xff); db(0x40);
- db(0x61); db(0x00); db(0x12); db(0xe2); db(0x70); db(0x00); db(0x4e); db(0x90);
- db(0x24); db(0x00); db(0x61); db(0x00); db(0xfb); db(0xc2); db(0x70); db(0x01);
- db(0x61); db(0x00); db(0xf9); db(0x72); db(0x08); db(0x02); db(0x00); db(0x01);
- db(0x67); db(0x06); db(0x70); db(0x01); db(0x61); db(0x00); db(0xfa); db(0xda);
- db(0x60); db(0x00); db(0x01); db(0x44); db(0x20); db(0x4d); db(0x4e); db(0xae);
- db(0xfe); db(0x8c); db(0x28); db(0x40); db(0x4a); db(0x80); db(0x66); db(0x10);
- db(0x70); db(0x00); db(0x12); db(0x2d); db(0x00); db(0x0f); db(0x03); db(0xc0);
- db(0x08); db(0xc0); db(0x00); db(0x0d); db(0x4e); db(0xae); db(0xfe); db(0xc2);
- db(0x08); db(0x2b); db(0x00); db(0x00); db(0x00); db(0xad); db(0x67); db(0x0a);
- db(0x61); db(0x00); db(0xfe); db(0xe8); db(0x08); db(0xab); db(0x00); db(0x00);
- db(0x00); db(0xad); db(0x08); db(0x2b); db(0x00); db(0x01); db(0x00); db(0xad);
- db(0x67); db(0x0a); db(0x61); db(0x00); db(0x0c); db(0x62); db(0x08); db(0xab);
- db(0x00); db(0x01); db(0x00); db(0xad); db(0x4a); db(0x2b); db(0x00); db(0xac);
- db(0x67); db(0x24); db(0x30); db(0x3c); db(0xff); db(0x58); db(0x61); db(0x00);
- db(0x12); db(0x74); db(0x70); db(0x01); db(0x4e); db(0x90); db(0x4a); db(0x80);
- db(0x67); db(0x04); db(0x61); db(0x00); db(0xfb); db(0x78); db(0x42); db(0x2b);
- db(0x00); db(0xac); db(0x30); db(0x3c); db(0xff); db(0x58); db(0x61); db(0x00);
- db(0x12); db(0x5c); db(0x70); db(0x02); db(0x4e); db(0x90); db(0x20); db(0x0c);
- db(0x67); db(0x56); db(0x0c); db(0x6c); db(0x00); db(0x26); db(0x00); db(0x12);
- db(0x66); db(0x4e); db(0x0c); db(0xac); db(0x40); db(0x00); db(0x00); db(0x00);
- db(0x00); db(0x14); db(0x66); db(0x44); db(0x0c); db(0x6c); db(0x12); db(0x34);
- db(0x00); db(0x18); db(0x66); db(0x3c); db(0x20); db(0x6c); db(0x00); db(0x1a);
- db(0x20); db(0x28); db(0x00); db(0x0c); db(0x02); db(0x80); db(0x80); db(0x00);
- db(0x00); db(0x08); db(0x0c); db(0x80); db(0x80); db(0x00); db(0x00); db(0x08);
- db(0x66); db(0x1a); db(0x02); db(0xa8); db(0x7f); db(0xff); db(0xff); db(0xff);
- db(0x00); db(0x0c); db(0x20); db(0x68); db(0x00); db(0x10); db(0x22); db(0x4c);
- db(0x12); db(0xbc); db(0x00); db(0x08); db(0x4e); db(0xae); db(0xfe); db(0x92);
- db(0x60); db(0x00); db(0xff); db(0x4a); db(0x22); db(0x4c); db(0x70); db(0x26);
- db(0x4e); db(0xae); db(0xff); db(0x2e); db(0x60); db(0x00); db(0xff); db(0x3e);
- db(0x74); db(0xfe); db(0x20); db(0x0c); db(0x67); db(0x14); db(0x26); db(0x2c);
- db(0x00); db(0x0a); db(0x66); db(0x42); db(0x74); db(0xff); db(0x30); db(0x3c);
- db(0xff); db(0x50); db(0x61); db(0x00); db(0x11); db(0xe8); db(0x70); db(0x01);
- db(0x4e); db(0x90); db(0x45); db(0xeb); db(0x00); db(0x04); db(0x20); db(0x52);
- db(0x20); db(0x08); db(0x67); db(0x00); db(0xff); db(0x18); db(0x22); db(0x50);
- db(0x20); db(0x40); db(0x20); db(0x28); db(0x00); db(0x04); db(0xb4); db(0x80);
- db(0x66); db(0x16); db(0x48); db(0xe7); db(0x00); db(0xc0); db(0x28); db(0x68);
- db(0x00); db(0x0a); db(0x61); db(0x4a); db(0x53); db(0x85); db(0x4c); db(0xdf);
- db(0x03); db(0x00); db(0x24); db(0x89); db(0x20); db(0x49); db(0x60); db(0xd8);
- db(0x24); db(0x48); db(0x20); db(0x49); db(0x60); db(0xd2); db(0x0c); db(0x85);
- db(0x00); db(0x00); db(0x00); db(0x14); db(0x65); db(0x00); db(0x00); db(0x0a);
- db(0x70); db(0x01); db(0x29); db(0x40); db(0x00); db(0x04); db(0x60); db(0x12);
- db(0x61); db(0x5e); db(0x30); db(0x3c); db(0xff); db(0x30); db(0x61); db(0x00);
- db(0x11); db(0x94); db(0x4e); db(0x90); db(0x4a); db(0x80); db(0x67); db(0x0e);
- db(0x52); db(0x85); db(0x28); db(0xab); db(0x00); db(0x04); db(0x27); db(0x4c);
- db(0x00); db(0x04); db(0x60); db(0x00); db(0xfe); db(0xc0); db(0x28); db(0x43);
- db(0x61); db(0x04); db(0x60); db(0x00); db(0xfe); db(0xb8); db(0x0c); db(0xac);
- db(0x00); db(0x00); db(0x00); db(0x1f); db(0x00); db(0x08); db(0x66); db(0x04);
- db(0x61); db(0x00); db(0xfa); db(0x3a); db(0x0c); db(0xac); db(0x00); db(0x00);
- db(0x04); db(0x09); db(0x00); db(0x08); db(0x66); db(0x14); db(0x61); db(0x00);
- db(0xfa); db(0x92); db(0x66); db(0x0e); db(0x30); db(0x3c); db(0xff); db(0x58);
- db(0x61); db(0x00); db(0x11); db(0x52); db(0x70); db(0x00); db(0x4e); db(0x90);
- db(0x60); db(0xec); db(0x22); db(0x54); db(0x20); db(0x6c); db(0x00); db(0x04);
- db(0x29); db(0x4d); db(0x00); db(0x04); db(0x4e); db(0xee); db(0xfe); db(0x92);
- db(0x2f); db(0x05); db(0x7a); db(0xfc); db(0x24); db(0x53); db(0x2e); db(0x0a);
- db(0x22); db(0x0a); db(0x67); db(0x00); db(0x00); db(0x0c); db(0x52); db(0x85);
- db(0x67); db(0x1e); db(0x22); db(0x4a); db(0x24); db(0x52); db(0x60); db(0xf0);
- db(0x52); db(0x85); db(0x67); db(0x3c); db(0x24); db(0x47); db(0x70); db(0x18);
- db(0x72); db(0x01); db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x52); db(0x46);
- db(0x24); db(0x40); db(0x24); db(0x87); db(0x2e); db(0x0a); db(0x60); db(0xe8);
- db(0x20); db(0x12); db(0x67); db(0x24); db(0x20); db(0x40); db(0x20); db(0x10);
- db(0x67); db(0x1e); db(0x20); db(0x40); db(0x20); db(0x10); db(0x67); db(0x18);
- db(0x70); db(0x00); db(0x22); db(0x80); db(0x22); db(0x4a); db(0x24); db(0x51);
- db(0x70); db(0x18); db(0x4e); db(0xae); db(0xff); db(0x2e); db(0x06); db(0x86);
- db(0x00); db(0x01); db(0x00); db(0x00); db(0x20); db(0x0a); db(0x66); db(0xec);
- db(0x26); db(0x87); db(0x2a); db(0x1f); db(0x4e); db(0x75); db(0x20); db(0x88);
- db(0x58); db(0x90); db(0x42); db(0xa8); db(0x00); db(0x04); db(0x21); db(0x48);
- db(0x00); db(0x08); db(0x4e); db(0x75); db(0x48); db(0xe7); db(0x20); db(0x22);
- db(0x2c); db(0x78); db(0x00); db(0x04); db(0x70); db(0xff); db(0x4e); db(0xae);
- db(0xfe); db(0xb6); db(0x91); db(0xc8); db(0x24); db(0x00); db(0x6b); db(0x32);
- db(0x70); db(0x22); db(0x22); db(0x3c); db(0x00); db(0x01); db(0x00); db(0x01);
- db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x91); db(0xc8); db(0x24); db(0x40);
- db(0x4a); db(0x80); db(0x67); db(0x1e); db(0x15); db(0x7c); db(0x00); db(0x04);
- db(0x00); db(0x08); db(0x15); db(0x42); db(0x00); db(0x0f); db(0x93); db(0xc9);
- db(0x4e); db(0xae); db(0xfe); db(0xda); db(0x25); db(0x40); db(0x00); db(0x10);
- db(0x41); db(0xea); db(0x00); db(0x14); db(0x61); db(0x00); db(0xff); db(0xb0);
- db(0x20); db(0x4a); db(0x20); db(0x08); db(0x4c); db(0xdf); db(0x44); db(0x04);
- db(0x4e); db(0x75); db(0x48); db(0xe7); db(0x20); db(0x22); db(0x2c); db(0x78);
- db(0x00); db(0x04); db(0x4a); db(0x80); db(0x67); db(0x24); db(0x24); db(0x40);
- db(0x24); db(0x01); db(0x66); db(0x02); db(0x74); db(0x30); db(0x20); db(0x02);
- db(0x22); db(0x3c); db(0x00); db(0x01); db(0x00); db(0x01); db(0x4e); db(0xae);
- db(0xff); db(0x3a); db(0x20); db(0x40); db(0x11); db(0x7c); db(0x00); db(0x0a);
- db(0x00); db(0x08); db(0x31); db(0x42); db(0x00); db(0x12); db(0x21); db(0x4a);
- db(0x00); db(0x0e); db(0x4a); db(0x80); db(0x4c); db(0xdf); db(0x44); db(0x04);
- db(0x4e); db(0x75); db(0x48); db(0xe7); db(0x30); db(0x22); db(0x24); db(0x48);
- db(0x24); db(0x00); db(0x26); db(0x01); db(0x2c); db(0x78); db(0x00); db(0x04);
- db(0x61); db(0x00); db(0xff); db(0x6a); db(0x22); db(0x03); db(0x61); db(0x00);
- db(0xff); db(0xb2); db(0x67); db(0x18); db(0x20); db(0x4a); db(0x22); db(0x40);
- db(0x24); db(0x40); db(0x20); db(0x02); db(0x72); db(0x00); db(0x4e); db(0xae);
- db(0xfe); db(0x44); db(0x22); db(0x00); db(0x70); db(0x00); db(0x4a); db(0x81);
- db(0x66); db(0x02); db(0x20); db(0x0a); db(0x4a); db(0x80); db(0x4c); db(0xdf);
- db(0x44); db(0x0c); db(0x4e); db(0x75); db(0x48); db(0xe7); db(0x38); db(0x32);
- db(0x2c); db(0x78); db(0x00); db(0x04); db(0x28); db(0x00); db(0x24); db(0x08);
- db(0x26); db(0x09); db(0x20); db(0x3c); db(0x00); db(0x00); db(0x08); db(0x5c);
+ db(0xfe); db(0x38); db(0x4e); db(0x75); db(0x7e); db(0x00); db(0x2c); db(0x78);
+ db(0x00); db(0x04); db(0x93); db(0xc9); db(0x4e); db(0xae); db(0xfe); db(0xda);
+ db(0x20); db(0x40); db(0x4b); db(0xe8); db(0x00); db(0x5c); db(0x43); db(0xfa);
+ db(0x1b); db(0x24); db(0x4e); db(0xae); db(0xfe); db(0x68); db(0x24); db(0x40);
+ db(0x22); db(0x3c); db(0x00); db(0x00); db(0x00); db(0xbc); db(0x30); db(0x3c);
+ db(0xff); db(0x40); db(0x61); db(0x00); db(0x19); db(0xcc); db(0x70); db(0x01);
+ db(0x4e); db(0x90); db(0x4a); db(0x80); db(0x66); db(0x0c); db(0x20); db(0x01);
  db(0x22); db(0x3c); db(0x00); db(0x01); db(0x00); db(0x01); db(0x4e); db(0xae);
- db(0xff); db(0x3a); db(0x4a); db(0x80); db(0x67); db(0x00); db(0x00); db(0x34);
- db(0x24); db(0x40); db(0x15); db(0x7c); db(0x00); db(0x01); db(0x00); db(0x08);
- db(0x15); db(0x44); db(0x00); db(0x09); db(0x25); db(0x42); db(0x00); db(0x0a);
- db(0x47); db(0xea); db(0x00); db(0x5c); db(0x25); db(0x4b); db(0x00); db(0x3a);
- db(0x47); db(0xeb); db(0x08); db(0x00); db(0x25); db(0x4b); db(0x00); db(0x3e);
- db(0x25); db(0x4b); db(0x00); db(0x36); db(0x22); db(0x4a); db(0x24); db(0x43);
- db(0x97); db(0xcb); db(0x24); db(0x09); db(0x4e); db(0xae); db(0xfe); db(0xe6);
- db(0x20); db(0x02); db(0x4c); db(0xdf); db(0x4c); db(0x1c); db(0x4e); db(0x75);
- db(0x41); db(0xfa); db(0x10); db(0x69); db(0x43); db(0xfa); db(0x01); db(0x50);
- db(0x70); db(0x13); db(0x61); db(0x00); db(0xff); db(0x98); db(0x4e); db(0x75);
- db(0x9e); db(0xfc); db(0x00); db(0x18); db(0x42); db(0x92); db(0x42); db(0xaa);
- db(0x00); db(0x0e); db(0x42); db(0xaa); db(0x00); db(0x12); db(0x20); db(0x4a);
- db(0x22); db(0x4f); db(0x70); db(0x05); db(0x22); db(0xd8); db(0x51); db(0xc8);
- db(0xff); db(0xfc); db(0x0c); db(0x6e); db(0x00); db(0x24); db(0x00); db(0x14);
- db(0x64); db(0x24); db(0x22); db(0x6d); db(0x02); db(0x0c); db(0x33); db(0x7c);
- db(0x00); db(0x0a); db(0x00); db(0x1c); db(0x13); db(0x7c); db(0x00); db(0x01);
- db(0x00); db(0x1e); db(0x4e); db(0xae); db(0xfe); db(0x38); db(0x22); db(0x6d);
- db(0x02); db(0x0c); db(0x2f); db(0x69); db(0x00); db(0x20); db(0x00); db(0x0e);
- db(0x2f); db(0x69); db(0x00); db(0x24); db(0x00); db(0x12); db(0x22); db(0x6d);
- db(0x02); db(0x08); db(0x33); db(0x7c); db(0x00); db(0x0b); db(0x00); db(0x1c);
- db(0x23); db(0x7c); db(0x00); db(0x00); db(0x00); db(0x16); db(0x00); db(0x24);
- db(0x13); db(0x7c); db(0x00); db(0x01); db(0x00); db(0x1e); db(0x23); db(0x4f);
- db(0x00); db(0x28); db(0x4e); db(0xae); db(0xfe); db(0x38); db(0xde); db(0xfc);
- db(0x00); db(0x18); db(0x4e); db(0x75); db(0x48); db(0xe7); db(0xf8); db(0xfe);
- db(0x2a); db(0x48); db(0x95); db(0xca); db(0x97); db(0xcb); db(0x99); db(0xcc);
- db(0x78); db(0x00); db(0x2c); db(0x6d); db(0x00); db(0x18); db(0x20); db(0x6d);
- db(0x00); db(0x14); db(0x20); db(0x28); db(0x00); db(0x3c); db(0x67); db(0x5c);
- db(0x20); db(0x40); db(0x41); db(0xe8); db(0x00); db(0x2c); db(0x28); db(0x48);
- db(0x4e); db(0xae); db(0xfc); db(0xe8); db(0x72); db(0xff); db(0x74); db(0xff);
- db(0xb2); db(0x80); db(0x67); db(0x48); db(0x26); db(0x00); db(0x2c); db(0x6d);
- db(0x00); db(0x14); db(0x41); db(0xed); db(0x00); db(0xc0); db(0x70); db(0x66);
- db(0x4e); db(0xae); db(0xff); db(0x7c); db(0x41); db(0xed); db(0x00); db(0xc0);
- db(0x38); db(0x28); db(0x00); db(0x64); db(0x2c); db(0x6d); db(0x00); db(0x18);
- db(0x91); db(0xc8); db(0x43); db(0xed); db(0x00); db(0x38); db(0x70); db(0x00);
- db(0x30); db(0x3c); db(0x00); db(0x58); db(0x22); db(0x3c); db(0x80); db(0x00);
- db(0x10); db(0x00); db(0x24); db(0x03); db(0x4e); db(0xae); db(0xfd); db(0x0c);
- db(0x72); db(0xff); db(0x74); db(0xff); db(0x4a); db(0x80); db(0x6b); db(0x0c);
- db(0x45); db(0xed); db(0x00); db(0x38); db(0x22); db(0x2a); db(0x00); db(0x32);
- db(0x24); db(0x2a); db(0x00); db(0x36); db(0x20); db(0x2c); db(0x00); db(0x1c);
- db(0xb8); db(0x6d); db(0x00); db(0x2c); db(0x66); db(0x12); db(0xb0); db(0xad);
- db(0x00); db(0x28); db(0x66); db(0x0c); db(0xb2); db(0xad); db(0x00); db(0x20);
- db(0x66); db(0x06); db(0xb4); db(0xad); db(0x00); db(0x24); db(0x67); db(0x40);
- db(0x2b); db(0x40); db(0x00); db(0x28); db(0x2b); db(0x41); db(0x00); db(0x20);
- db(0x2b); db(0x42); db(0x00); db(0x24); db(0x3b); db(0x44); db(0x00); db(0x2c);
- db(0x91); db(0xc8); db(0x43); db(0xed); db(0x00); db(0x90); db(0x70); db(0x00);
- db(0x30); db(0x3c); db(0x00); db(0x58); db(0x22); db(0x3c); db(0x80); db(0x00);
- db(0x00); db(0x00); db(0x24); db(0x03); db(0x4e); db(0xae); db(0xfd); db(0x0c);
- db(0x4a); db(0x80); db(0x6b); db(0x04); db(0x47); db(0xed); db(0x00); db(0x90);
- db(0x34); db(0x2d); db(0x00); db(0x2c); db(0x30); db(0x3c); db(0xff); db(0x38);
- db(0x72); db(0x01); db(0x61); db(0x00); db(0x0e); db(0x68); db(0x4e); db(0x90);
- db(0x4c); db(0xdf); db(0x7f); db(0x1f); db(0x4e); db(0x75); db(0x2c); db(0x78);
- db(0x00); db(0x04); db(0x3e); db(0x2e); db(0x00); db(0x14); db(0x70); db(0xff);
- db(0x4e); db(0xae); db(0xfe); db(0xb6); db(0x7c); db(0x00); db(0x01); db(0xc6);
- db(0x93); db(0xc9); db(0x4e); db(0xae); db(0xfe); db(0xda); db(0x24); db(0x40);
- db(0x70); db(0x14); db(0x22); db(0x4a); db(0x4e); db(0xae); db(0xfe); db(0xd4);
- db(0x70); db(0x00); db(0x30); db(0x3c); db(0x02); db(0x14); db(0x22); db(0x3c);
+ db(0xff); db(0x3a); db(0x26); db(0x40); db(0x7c); db(0x00); db(0x26); db(0x86);
+ db(0x27); db(0x46); db(0x00); db(0x04); db(0x27); db(0x46); db(0x00); db(0x08);
+ db(0x27); db(0x4a); db(0x00); db(0xa0); db(0x50); db(0xeb); db(0x00); db(0x9e);
+ db(0x70); db(0xff); db(0x27); db(0x40); db(0x00); db(0xb8); db(0x93); db(0xc9);
+ db(0x4e); db(0xae); db(0xfe); db(0xda); db(0x27); db(0x40); db(0x00); db(0xb0);
+ db(0x41); db(0xfa); db(0x19); db(0xb0); db(0x70); db(0x00); db(0x72); db(0x00);
+ db(0x61); db(0x00); db(0x02); db(0xcc); db(0x27); db(0x40); db(0x00); db(0xa4);
+ db(0x41); db(0xfa); db(0x19); db(0xad); db(0x70); db(0x00); db(0x72); db(0x00);
+ db(0x61); db(0x00); db(0x02); db(0xbc); db(0x27); db(0x40); db(0x00); db(0xa8);
+ db(0x7a); db(0x00); db(0x26); db(0x07); db(0x66); db(0x12); db(0x20); db(0x4d);
+ db(0x4e); db(0xae); db(0xfe); db(0x80); db(0x20); db(0x4d); db(0x4e); db(0xae);
+ db(0xfe); db(0x8c); db(0x28); db(0x40); db(0x26); db(0x2c); db(0x00); db(0x0a);
+ db(0x30); db(0x3c); db(0xff); db(0x40); db(0x61); db(0x00); db(0x19); db(0x52);
+ db(0x70); db(0x00); db(0x4e); db(0x90); db(0x24); db(0x00); db(0x61); db(0x00);
+ db(0xfb); db(0xc2); db(0x70); db(0x01); db(0x61); db(0x00); db(0xf9); db(0x72);
+ db(0x08); db(0x02); db(0x00); db(0x01); db(0x67); db(0x06); db(0x70); db(0x01);
+ db(0x61); db(0x00); db(0xfa); db(0xda); db(0x60); db(0x00); db(0x01); db(0x44);
+ db(0x20); db(0x4d); db(0x4e); db(0xae); db(0xfe); db(0x8c); db(0x28); db(0x40);
+ db(0x4a); db(0x80); db(0x66); db(0x10); db(0x70); db(0x00); db(0x12); db(0x2d);
+ db(0x00); db(0x0f); db(0x03); db(0xc0); db(0x08); db(0xc0); db(0x00); db(0x0d);
+ db(0x4e); db(0xae); db(0xfe); db(0xc2); db(0x08); db(0x2b); db(0x00); db(0x00);
+ db(0x00); db(0xad); db(0x67); db(0x0a); db(0x61); db(0x00); db(0xfe); db(0xe8);
+ db(0x08); db(0xab); db(0x00); db(0x00); db(0x00); db(0xad); db(0x08); db(0x2b);
+ db(0x00); db(0x01); db(0x00); db(0xad); db(0x67); db(0x0a); db(0x61); db(0x00);
+ db(0x0c); db(0x62); db(0x08); db(0xab); db(0x00); db(0x01); db(0x00); db(0xad);
+ db(0x4a); db(0x2b); db(0x00); db(0xac); db(0x67); db(0x24); db(0x30); db(0x3c);
+ db(0xff); db(0x58); db(0x61); db(0x00); db(0x18); db(0xe4); db(0x70); db(0x01);
+ db(0x4e); db(0x90); db(0x4a); db(0x80); db(0x67); db(0x04); db(0x61); db(0x00);
+ db(0xfb); db(0x78); db(0x42); db(0x2b); db(0x00); db(0xac); db(0x30); db(0x3c);
+ db(0xff); db(0x58); db(0x61); db(0x00); db(0x18); db(0xcc); db(0x70); db(0x02);
+ db(0x4e); db(0x90); db(0x20); db(0x0c); db(0x67); db(0x56); db(0x0c); db(0x6c);
+ db(0x00); db(0x26); db(0x00); db(0x12); db(0x66); db(0x4e); db(0x0c); db(0xac);
+ db(0x40); db(0x00); db(0x00); db(0x00); db(0x00); db(0x14); db(0x66); db(0x44);
+ db(0x0c); db(0x6c); db(0x12); db(0x34); db(0x00); db(0x18); db(0x66); db(0x3c);
+ db(0x20); db(0x6c); db(0x00); db(0x1a); db(0x20); db(0x28); db(0x00); db(0x0c);
+ db(0x02); db(0x80); db(0x80); db(0x00); db(0x00); db(0x08); db(0x0c); db(0x80);
+ db(0x80); db(0x00); db(0x00); db(0x08); db(0x66); db(0x1a); db(0x02); db(0xa8);
+ db(0x7f); db(0xff); db(0xff); db(0xff); db(0x00); db(0x0c); db(0x20); db(0x68);
+ db(0x00); db(0x10); db(0x22); db(0x4c); db(0x12); db(0xbc); db(0x00); db(0x08);
+ db(0x4e); db(0xae); db(0xfe); db(0x92); db(0x60); db(0x00); db(0xff); db(0x4a);
+ db(0x22); db(0x4c); db(0x70); db(0x26); db(0x4e); db(0xae); db(0xff); db(0x2e);
+ db(0x60); db(0x00); db(0xff); db(0x3e); db(0x74); db(0xfe); db(0x20); db(0x0c);
+ db(0x67); db(0x14); db(0x26); db(0x2c); db(0x00); db(0x0a); db(0x66); db(0x42);
+ db(0x74); db(0xff); db(0x30); db(0x3c); db(0xff); db(0x50); db(0x61); db(0x00);
+ db(0x18); db(0x58); db(0x70); db(0x01); db(0x4e); db(0x90); db(0x45); db(0xeb);
+ db(0x00); db(0x04); db(0x20); db(0x52); db(0x20); db(0x08); db(0x67); db(0x00);
+ db(0xff); db(0x18); db(0x22); db(0x50); db(0x20); db(0x40); db(0x20); db(0x28);
+ db(0x00); db(0x04); db(0xb4); db(0x80); db(0x66); db(0x16); db(0x48); db(0xe7);
+ db(0x00); db(0xc0); db(0x28); db(0x68); db(0x00); db(0x0a); db(0x61); db(0x4a);
+ db(0x53); db(0x85); db(0x4c); db(0xdf); db(0x03); db(0x00); db(0x24); db(0x89);
+ db(0x20); db(0x49); db(0x60); db(0xd8); db(0x24); db(0x48); db(0x20); db(0x49);
+ db(0x60); db(0xd2); db(0x0c); db(0x85); db(0x00); db(0x00); db(0x00); db(0x14);
+ db(0x65); db(0x00); db(0x00); db(0x0a); db(0x70); db(0x01); db(0x29); db(0x40);
+ db(0x00); db(0x04); db(0x60); db(0x12); db(0x61); db(0x5e); db(0x30); db(0x3c);
+ db(0xff); db(0x30); db(0x61); db(0x00); db(0x18); db(0x04); db(0x4e); db(0x90);
+ db(0x4a); db(0x80); db(0x67); db(0x0e); db(0x52); db(0x85); db(0x28); db(0xab);
+ db(0x00); db(0x04); db(0x27); db(0x4c); db(0x00); db(0x04); db(0x60); db(0x00);
+ db(0xfe); db(0xc0); db(0x28); db(0x43); db(0x61); db(0x04); db(0x60); db(0x00);
+ db(0xfe); db(0xb8); db(0x0c); db(0xac); db(0x00); db(0x00); db(0x00); db(0x1f);
+ db(0x00); db(0x08); db(0x66); db(0x04); db(0x61); db(0x00); db(0xfa); db(0x3a);
+ db(0x0c); db(0xac); db(0x00); db(0x00); db(0x04); db(0x09); db(0x00); db(0x08);
+ db(0x66); db(0x14); db(0x61); db(0x00); db(0xfa); db(0x92); db(0x66); db(0x0e);
+ db(0x30); db(0x3c); db(0xff); db(0x58); db(0x61); db(0x00); db(0x17); db(0xc2);
+ db(0x70); db(0x00); db(0x4e); db(0x90); db(0x60); db(0xec); db(0x22); db(0x54);
+ db(0x20); db(0x6c); db(0x00); db(0x04); db(0x29); db(0x4d); db(0x00); db(0x04);
+ db(0x4e); db(0xee); db(0xfe); db(0x92); db(0x2f); db(0x05); db(0x7a); db(0xfc);
+ db(0x24); db(0x53); db(0x2e); db(0x0a); db(0x22); db(0x0a); db(0x67); db(0x00);
+ db(0x00); db(0x0c); db(0x52); db(0x85); db(0x67); db(0x1e); db(0x22); db(0x4a);
+ db(0x24); db(0x52); db(0x60); db(0xf0); db(0x52); db(0x85); db(0x67); db(0x3c);
+ db(0x24); db(0x47); db(0x70); db(0x18); db(0x72); db(0x01); db(0x4e); db(0xae);
+ db(0xff); db(0x3a); db(0x52); db(0x46); db(0x24); db(0x40); db(0x24); db(0x87);
+ db(0x2e); db(0x0a); db(0x60); db(0xe8); db(0x20); db(0x12); db(0x67); db(0x24);
+ db(0x20); db(0x40); db(0x20); db(0x10); db(0x67); db(0x1e); db(0x20); db(0x40);
+ db(0x20); db(0x10); db(0x67); db(0x18); db(0x70); db(0x00); db(0x22); db(0x80);
+ db(0x22); db(0x4a); db(0x24); db(0x51); db(0x70); db(0x18); db(0x4e); db(0xae);
+ db(0xff); db(0x2e); db(0x06); db(0x86); db(0x00); db(0x01); db(0x00); db(0x00);
+ db(0x20); db(0x0a); db(0x66); db(0xec); db(0x26); db(0x87); db(0x2a); db(0x1f);
+ db(0x4e); db(0x75); db(0x20); db(0x88); db(0x58); db(0x90); db(0x42); db(0xa8);
+ db(0x00); db(0x04); db(0x21); db(0x48); db(0x00); db(0x08); db(0x4e); db(0x75);
+ db(0x48); db(0xe7); db(0x20); db(0x22); db(0x2c); db(0x78); db(0x00); db(0x04);
+ db(0x70); db(0xff); db(0x4e); db(0xae); db(0xfe); db(0xb6); db(0x91); db(0xc8);
+ db(0x24); db(0x00); db(0x6b); db(0x32); db(0x70); db(0x22); db(0x22); db(0x3c);
  db(0x00); db(0x01); db(0x00); db(0x01); db(0x4e); db(0xae); db(0xff); db(0x3a);
- db(0x2a); db(0x40); db(0x30); db(0x3c); db(0x3e); db(0x00); db(0x61); db(0x00);
- db(0x0e); db(0x34); db(0x2b); db(0x48); db(0x02); db(0x10); db(0x28); db(0x48);
- db(0x47); db(0xed); db(0x00); db(0x16); db(0x27); db(0x4e); db(0x00); db(0x10);
- db(0x27); db(0x4a); db(0x00); db(0x08); db(0x27); db(0x46); db(0x00); db(0x0c);
- db(0x70); db(0xff); db(0x37); db(0x40); db(0x00); db(0x00); db(0x30); db(0x3c);
- db(0xff); db(0x38); db(0x72); db(0x05); db(0x61); db(0x00); db(0x0d); db(0xfe);
- db(0x20); db(0x0c); db(0x4e); db(0x90); db(0x43); db(0xed); db(0x00); db(0x00);
- db(0x13); db(0x7c); db(0x00); db(0x02); db(0x00); db(0x08); db(0x13); db(0x7c);
- db(0x00); db(0x05); db(0x00); db(0x09); db(0x41); db(0xfa); db(0x0e); db(0x9d);
- db(0x23); db(0x48); db(0x00); db(0x0a); db(0x41); db(0xfa); db(0x03); db(0x2e);
- db(0x23); db(0x48); db(0x00); db(0x12); db(0x23); db(0x4d); db(0x00); db(0x0e);
- db(0x70); db(0x05); db(0x4e); db(0xae); db(0xff); db(0x58); db(0x20); db(0x06);
- db(0x4e); db(0xae); db(0xfe); db(0xc2); db(0x70); db(0x00); db(0x53); db(0xab);
- db(0x00); db(0x1c); db(0x6a); db(0x06); db(0x70); db(0x0a); db(0x27); db(0x40);
- db(0x00); db(0x1c); db(0x4a); db(0xab); db(0x00); db(0x14); db(0x66); db(0x22);
- db(0x4a); db(0xab); db(0x00); db(0x1c); db(0x66); db(0xe0); db(0x43); db(0xfa);
- db(0x0e); db(0xed); db(0x70); db(0x00); db(0x4e); db(0xae); db(0xfd); db(0xd8);
- db(0x27); db(0x40); db(0x00); db(0x14); db(0x67); db(0xd0); db(0x22); db(0x00);
- db(0x30); db(0x3c); db(0x3f); db(0xf4); db(0x61); db(0x00); db(0x0d); db(0xa6);
- db(0x20); db(0x81); db(0x4a); db(0xab); db(0x00); db(0x18); db(0x66); db(0x24);
- db(0x4a); db(0xab); db(0x00); db(0x1c); db(0x66); db(0xb8); db(0x43); db(0xfa);
- db(0x0e); db(0xd7); db(0x70); db(0x00); db(0x4e); db(0xae); db(0xfd); db(0xd8);
- db(0x27); db(0x40); db(0x00); db(0x18); db(0x67); db(0x00); db(0xff); db(0xa8);
- db(0x22); db(0x00); db(0x30); db(0x3c); db(0x3f); db(0xf8); db(0x61); db(0x00);
- db(0x0d); db(0x7c); db(0x20); db(0x81); db(0x4a); db(0xad); db(0x02); db(0x08);
- db(0x66); db(0x3a); db(0x4a); db(0xab); db(0x00); db(0x1c); db(0x66); db(0x8e);
- db(0x4e); db(0xae); db(0xff); db(0x7c); db(0x41); db(0xee); db(0x01); db(0x5e);
- db(0x43); db(0xfa); db(0x0d); db(0x74); db(0x4e); db(0xae); db(0xfe); db(0xec);
- db(0x24); db(0x00); db(0x4e); db(0xae); db(0xff); db(0x76); db(0x4a); db(0x82);
- db(0x67); db(0x00); db(0xff); db(0x74); db(0x41); db(0xfa); db(0x0d); db(0x60);
- db(0x70); db(0x00); db(0x72); db(0x00); db(0x61); db(0x00); db(0xfc); db(0xec);
- db(0x2b); db(0x40); db(0x02); db(0x08); db(0x67); db(0x00); db(0x02); db(0x52);
- db(0x60); db(0x00); db(0xff); db(0x5c); db(0x4a); db(0xad); db(0x02); db(0x0c);
- db(0x66); db(0x48); db(0x4a); db(0xab); db(0x00); db(0x1c); db(0x66); db(0x00);
- db(0xff); db(0x4e); db(0x4e); db(0xae); db(0xff); db(0x7c); db(0x41); db(0xee);
- db(0x01); db(0x5e); db(0x43); db(0xfa); db(0x0d); db(0x3f); db(0x4e); db(0xae);
- db(0xfe); db(0xec); db(0x24); db(0x00); db(0x4e); db(0xae); db(0xff); db(0x76);
- db(0x4a); db(0x82); db(0x67); db(0x00); db(0xff); db(0x32); db(0x41); db(0xfa);
- db(0x0d); db(0x2b); db(0x70); db(0x00); db(0x72); db(0x00); db(0x61); db(0x00);
- db(0xfc); db(0xaa); db(0x2b); db(0x40); db(0x02); db(0x0c); db(0x67); db(0x00);
- db(0x02); db(0x10); db(0x30); db(0x3c); db(0xff); db(0x38); db(0x72); db(0x00);
- db(0x61); db(0x00); db(0x0c); db(0xe2); db(0x4e); db(0x90); db(0x60); db(0x00);
- db(0xff); db(0x0e); db(0x0c); db(0x47); db(0x00); db(0x24); db(0x65); db(0x18);
- db(0x0c); db(0x47); db(0x00); db(0x32); db(0x64); db(0x12); db(0x53); db(0xab);
- db(0x00); db(0x34); db(0x6a); db(0x0c); db(0x20); db(0x4b); db(0x61); db(0x00);
- db(0xfd); db(0x8c); db(0x70); db(0x32); db(0x27); db(0x40); db(0x00); db(0x34);
- db(0x45); db(0xed); db(0x01); db(0x3c); db(0x10); db(0x2c); db(0x00); db(0x00);
- db(0x0c); db(0x47); db(0x00); db(0x27); db(0x65); db(0x00); db(0x01); db(0x0a);
- db(0x08); db(0x00); db(0x00); db(0x01); db(0x67); db(0x00); db(0x01); db(0x02);
- db(0x41); db(0xed); db(0x01); db(0x68); db(0x25); db(0x48); db(0x00); db(0x0a);
- db(0x15); db(0x7c); db(0x00); db(0x13); db(0x00); db(0x04); db(0x15); db(0x7c);
- db(0x00); db(0x03); db(0x00); db(0x05); db(0x42); db(0x90); db(0x42); db(0xa8);
- db(0x00); db(0x04); db(0x42); db(0xa8); db(0x00); db(0x08); db(0x42); db(0x68);
- db(0x00); db(0x0c); db(0x42); db(0x6a); db(0x00); db(0x06); db(0x61); db(0x00);
- db(0x01); db(0xa2); db(0x31); db(0x6c); db(0x00); db(0x0a); db(0x00); db(0x0e);
- db(0x42); db(0x68); db(0x00); db(0x10); db(0x31); db(0x6c); db(0x00); db(0x0c);
- db(0x00); db(0x12); db(0x42); db(0x68); db(0x00); db(0x14); db(0x31); db(0x6c);
- db(0x00); db(0x04); db(0x00); db(0x16); db(0x42); db(0x68); db(0x00); db(0x18);
- db(0x31); db(0x6c); db(0x00); db(0x06); db(0x00); db(0x1a); db(0x43); db(0xed);
- db(0x01); db(0x88); db(0x21); db(0x49); db(0x00); db(0x1c); db(0x22); db(0xfc);
- db(0x80); db(0x03); db(0xa0); db(0x06); db(0x30); db(0x2c); db(0x00); db(0x20);
- db(0x48); db(0xc0); db(0xe1); db(0x80); db(0x22); db(0xc0); db(0x22); db(0xfc);
- db(0x80); db(0x03); db(0xa0); db(0x07); db(0x22); db(0xec); db(0x00); db(0x22);
- db(0x70); db(0x00); db(0x30); db(0x2c); db(0x00); db(0x10); db(0x6b); db(0x08);
- db(0x22); db(0xfc); db(0x80); db(0x03); db(0xa0); db(0x09); db(0x22); db(0xc0);
- db(0x30); db(0x2c); db(0x00); db(0x12); db(0x6b); db(0x08); db(0x22); db(0xfc);
- db(0x80); db(0x03); db(0xa0); db(0x0a); db(0x22); db(0xc0); db(0x30); db(0x2c);
- db(0x00); db(0x08); db(0x6b); db(0x14); db(0x22); db(0xfc); db(0x80); db(0x03);
- db(0xa0); db(0x02); db(0x22); db(0xc0); db(0x30); db(0x2c); db(0x00); db(0x0e);
- db(0x22); db(0xfc); db(0x80); db(0x03); db(0xa0); db(0x01); db(0x22); db(0xc0);
- db(0x30); db(0x2c); db(0x00); db(0x14); db(0x6b); db(0x10); db(0x22); db(0xfc);
- db(0x80); db(0x03); db(0xa0); db(0x03); db(0x30); db(0x2c); db(0x00); db(0x1a);
- db(0x48); db(0xc0); db(0xe1); db(0x80); db(0x22); db(0xc0); db(0x30); db(0x2c);
- db(0x00); db(0x16); db(0x6b); db(0x10); db(0x22); db(0xfc); db(0x80); db(0x03);
- db(0xa0); db(0x04); db(0x30); db(0x2c); db(0x00); db(0x1c); db(0x48); db(0xc0);
- db(0xe1); db(0x80); db(0x22); db(0xc0); db(0x30); db(0x2c); db(0x00); db(0x18);
- db(0x6b); db(0x10); db(0x22); db(0xfc); db(0x80); db(0x03); db(0xa0); db(0x05);
- db(0x30); db(0x2c); db(0x00); db(0x1e); db(0x48); db(0xc0); db(0xe1); db(0x80);
- db(0x22); db(0xc0); db(0x70); db(0x00); db(0x30); db(0x2c); db(0x00); db(0x26);
- db(0x6b); db(0x08); db(0x22); db(0xfc); db(0x80); db(0x03); db(0xa0); db(0x08);
- db(0x22); db(0xc0); db(0x42); db(0x91); db(0x61); db(0x00); db(0xfc); db(0x02);
- db(0x10); db(0x2c); db(0x00); db(0x00); db(0x08); db(0x00); db(0x00); db(0x01);
- db(0x66); db(0x08); db(0x08); db(0x00); db(0x00); db(0x00); db(0x67); db(0x00);
- db(0xfd); db(0xc6); db(0x20); db(0x6b); db(0x00); db(0x14); db(0x30); db(0x2c);
- db(0x00); db(0x28); db(0x32); db(0x28); db(0x00); db(0x30); db(0xd2); db(0x41);
+ db(0x91); db(0xc8); db(0x24); db(0x40); db(0x4a); db(0x80); db(0x67); db(0x1e);
+ db(0x15); db(0x7c); db(0x00); db(0x04); db(0x00); db(0x08); db(0x15); db(0x42);
+ db(0x00); db(0x0f); db(0x93); db(0xc9); db(0x4e); db(0xae); db(0xfe); db(0xda);
+ db(0x25); db(0x40); db(0x00); db(0x10); db(0x41); db(0xea); db(0x00); db(0x14);
+ db(0x61); db(0x00); db(0xff); db(0xb0); db(0x20); db(0x4a); db(0x20); db(0x08);
+ db(0x4c); db(0xdf); db(0x44); db(0x04); db(0x4e); db(0x75); db(0x48); db(0xe7);
+ db(0x20); db(0x22); db(0x2c); db(0x78); db(0x00); db(0x04); db(0x4a); db(0x80);
+ db(0x67); db(0x24); db(0x24); db(0x40); db(0x24); db(0x01); db(0x66); db(0x02);
+ db(0x74); db(0x30); db(0x20); db(0x02); db(0x22); db(0x3c); db(0x00); db(0x01);
+ db(0x00); db(0x01); db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x20); db(0x40);
+ db(0x11); db(0x7c); db(0x00); db(0x0a); db(0x00); db(0x08); db(0x31); db(0x42);
+ db(0x00); db(0x12); db(0x21); db(0x4a); db(0x00); db(0x0e); db(0x4a); db(0x80);
+ db(0x4c); db(0xdf); db(0x44); db(0x04); db(0x4e); db(0x75); db(0x48); db(0xe7);
+ db(0x30); db(0x22); db(0x24); db(0x48); db(0x24); db(0x00); db(0x26); db(0x01);
+ db(0x2c); db(0x78); db(0x00); db(0x04); db(0x61); db(0x00); db(0xff); db(0x6a);
+ db(0x22); db(0x03); db(0x61); db(0x00); db(0xff); db(0xb2); db(0x67); db(0x18);
+ db(0x20); db(0x4a); db(0x22); db(0x40); db(0x24); db(0x40); db(0x20); db(0x02);
+ db(0x72); db(0x00); db(0x4e); db(0xae); db(0xfe); db(0x44); db(0x22); db(0x00);
+ db(0x70); db(0x00); db(0x4a); db(0x81); db(0x66); db(0x02); db(0x20); db(0x0a);
+ db(0x4a); db(0x80); db(0x4c); db(0xdf); db(0x44); db(0x0c); db(0x4e); db(0x75);
+ db(0x48); db(0xe7); db(0x38); db(0x32); db(0x2c); db(0x78); db(0x00); db(0x04);
+ db(0x28); db(0x00); db(0x24); db(0x08); db(0x26); db(0x09); db(0x20); db(0x3c);
+ db(0x00); db(0x00); db(0x08); db(0x5c); db(0x22); db(0x3c); db(0x00); db(0x01);
+ db(0x00); db(0x01); db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x4a); db(0x80);
+ db(0x67); db(0x00); db(0x00); db(0x34); db(0x24); db(0x40); db(0x15); db(0x7c);
+ db(0x00); db(0x01); db(0x00); db(0x08); db(0x15); db(0x44); db(0x00); db(0x09);
+ db(0x25); db(0x42); db(0x00); db(0x0a); db(0x47); db(0xea); db(0x00); db(0x5c);
+ db(0x25); db(0x4b); db(0x00); db(0x3a); db(0x47); db(0xeb); db(0x08); db(0x00);
+ db(0x25); db(0x4b); db(0x00); db(0x3e); db(0x25); db(0x4b); db(0x00); db(0x36);
+ db(0x22); db(0x4a); db(0x24); db(0x43); db(0x97); db(0xcb); db(0x24); db(0x09);
+ db(0x4e); db(0xae); db(0xfe); db(0xe6); db(0x20); db(0x02); db(0x4c); db(0xdf);
+ db(0x4c); db(0x1c); db(0x4e); db(0x75); db(0x41); db(0xfa); db(0x16); db(0xe8);
+ db(0x43); db(0xfa); db(0x01); db(0x50); db(0x70); db(0x13); db(0x61); db(0x00);
+ db(0xff); db(0x98); db(0x4e); db(0x75); db(0x9e); db(0xfc); db(0x00); db(0x18);
+ db(0x42); db(0x92); db(0x42); db(0xaa); db(0x00); db(0x0e); db(0x42); db(0xaa);
+ db(0x00); db(0x12); db(0x20); db(0x4a); db(0x22); db(0x4f); db(0x70); db(0x05);
+ db(0x22); db(0xd8); db(0x51); db(0xc8); db(0xff); db(0xfc); db(0x0c); db(0x6e);
+ db(0x00); db(0x24); db(0x00); db(0x14); db(0x64); db(0x24); db(0x22); db(0x6d);
+ db(0x02); db(0x0c); db(0x33); db(0x7c); db(0x00); db(0x0a); db(0x00); db(0x1c);
+ db(0x13); db(0x7c); db(0x00); db(0x01); db(0x00); db(0x1e); db(0x4e); db(0xae);
+ db(0xfe); db(0x38); db(0x22); db(0x6d); db(0x02); db(0x0c); db(0x2f); db(0x69);
+ db(0x00); db(0x20); db(0x00); db(0x0e); db(0x2f); db(0x69); db(0x00); db(0x24);
+ db(0x00); db(0x12); db(0x22); db(0x6d); db(0x02); db(0x08); db(0x33); db(0x7c);
+ db(0x00); db(0x0b); db(0x00); db(0x1c); db(0x23); db(0x7c); db(0x00); db(0x00);
+ db(0x00); db(0x16); db(0x00); db(0x24); db(0x13); db(0x7c); db(0x00); db(0x01);
+ db(0x00); db(0x1e); db(0x23); db(0x4f); db(0x00); db(0x28); db(0x4e); db(0xae);
+ db(0xfe); db(0x38); db(0xde); db(0xfc); db(0x00); db(0x18); db(0x4e); db(0x75);
+ db(0x48); db(0xe7); db(0xf8); db(0xfe); db(0x2a); db(0x48); db(0x95); db(0xca);
+ db(0x97); db(0xcb); db(0x99); db(0xcc); db(0x78); db(0x00); db(0x2c); db(0x6d);
+ db(0x00); db(0x18); db(0x20); db(0x6d); db(0x00); db(0x14); db(0x20); db(0x28);
+ db(0x00); db(0x3c); db(0x67); db(0x5c); db(0x20); db(0x40); db(0x41); db(0xe8);
+ db(0x00); db(0x2c); db(0x28); db(0x48); db(0x4e); db(0xae); db(0xfc); db(0xe8);
+ db(0x72); db(0xff); db(0x74); db(0xff); db(0xb2); db(0x80); db(0x67); db(0x48);
+ db(0x26); db(0x00); db(0x2c); db(0x6d); db(0x00); db(0x14); db(0x41); db(0xed);
+ db(0x00); db(0xc0); db(0x70); db(0x66); db(0x4e); db(0xae); db(0xff); db(0x7c);
+ db(0x41); db(0xed); db(0x00); db(0xc0); db(0x38); db(0x28); db(0x00); db(0x64);
+ db(0x2c); db(0x6d); db(0x00); db(0x18); db(0x91); db(0xc8); db(0x43); db(0xed);
+ db(0x00); db(0x38); db(0x70); db(0x00); db(0x30); db(0x3c); db(0x00); db(0x58);
+ db(0x22); db(0x3c); db(0x80); db(0x00); db(0x10); db(0x00); db(0x24); db(0x03);
+ db(0x4e); db(0xae); db(0xfd); db(0x0c); db(0x72); db(0xff); db(0x74); db(0xff);
+ db(0x4a); db(0x80); db(0x6b); db(0x0c); db(0x45); db(0xed); db(0x00); db(0x38);
+ db(0x22); db(0x2a); db(0x00); db(0x32); db(0x24); db(0x2a); db(0x00); db(0x36);
+ db(0x20); db(0x2c); db(0x00); db(0x1c); db(0xb8); db(0x6d); db(0x00); db(0x2c);
+ db(0x66); db(0x12); db(0xb0); db(0xad); db(0x00); db(0x28); db(0x66); db(0x0c);
+ db(0xb2); db(0xad); db(0x00); db(0x20); db(0x66); db(0x06); db(0xb4); db(0xad);
+ db(0x00); db(0x24); db(0x67); db(0x40); db(0x2b); db(0x40); db(0x00); db(0x28);
+ db(0x2b); db(0x41); db(0x00); db(0x20); db(0x2b); db(0x42); db(0x00); db(0x24);
+ db(0x3b); db(0x44); db(0x00); db(0x2c); db(0x91); db(0xc8); db(0x43); db(0xed);
+ db(0x00); db(0x90); db(0x70); db(0x00); db(0x30); db(0x3c); db(0x00); db(0x58);
+ db(0x22); db(0x3c); db(0x80); db(0x00); db(0x00); db(0x00); db(0x24); db(0x03);
+ db(0x4e); db(0xae); db(0xfd); db(0x0c); db(0x4a); db(0x80); db(0x6b); db(0x04);
+ db(0x47); db(0xed); db(0x00); db(0x90); db(0x34); db(0x2d); db(0x00); db(0x2c);
+ db(0x30); db(0x3c); db(0xff); db(0x38); db(0x72); db(0x01); db(0x61); db(0x00);
+ db(0x14); db(0xd8); db(0x4e); db(0x90); db(0x4c); db(0xdf); db(0x7f); db(0x1f);
+ db(0x4e); db(0x75); db(0x2c); db(0x78); db(0x00); db(0x04); db(0x3e); db(0x2e);
+ db(0x00); db(0x14); db(0x70); db(0xff); db(0x4e); db(0xae); db(0xfe); db(0xb6);
+ db(0x7c); db(0x00); db(0x01); db(0xc6); db(0x93); db(0xc9); db(0x4e); db(0xae);
+ db(0xfe); db(0xda); db(0x24); db(0x40); db(0x70); db(0x14); db(0x22); db(0x4a);
+ db(0x4e); db(0xae); db(0xfe); db(0xd4); db(0x70); db(0x00); db(0x30); db(0x3c);
+ db(0x02); db(0x14); db(0x22); db(0x3c); db(0x00); db(0x01); db(0x00); db(0x01);
+ db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x2a); db(0x40); db(0x30); db(0x3c);
+ db(0x3e); db(0x00); db(0x61); db(0x00); db(0x14); db(0xa4); db(0x2b); db(0x48);
+ db(0x02); db(0x10); db(0x28); db(0x48); db(0x47); db(0xed); db(0x00); db(0x16);
+ db(0x27); db(0x4e); db(0x00); db(0x10); db(0x27); db(0x4a); db(0x00); db(0x08);
+ db(0x27); db(0x46); db(0x00); db(0x0c); db(0x70); db(0xff); db(0x37); db(0x40);
+ db(0x00); db(0x00); db(0x30); db(0x3c); db(0xff); db(0x38); db(0x72); db(0x05);
+ db(0x61); db(0x00); db(0x14); db(0x6e); db(0x20); db(0x0c); db(0x4e); db(0x90);
+ db(0x43); db(0xed); db(0x00); db(0x00); db(0x13); db(0x7c); db(0x00); db(0x02);
+ db(0x00); db(0x08); db(0x13); db(0x7c); db(0x00); db(0x05); db(0x00); db(0x09);
+ db(0x41); db(0xfa); db(0x15); db(0x1c); db(0x23); db(0x48); db(0x00); db(0x0a);
+ db(0x41); db(0xfa); db(0x03); db(0x2e); db(0x23); db(0x48); db(0x00); db(0x12);
+ db(0x23); db(0x4d); db(0x00); db(0x0e); db(0x70); db(0x05); db(0x4e); db(0xae);
+ db(0xff); db(0x58); db(0x20); db(0x06); db(0x4e); db(0xae); db(0xfe); db(0xc2);
+ db(0x70); db(0x00); db(0x53); db(0xab); db(0x00); db(0x1c); db(0x6a); db(0x06);
+ db(0x70); db(0x0a); db(0x27); db(0x40); db(0x00); db(0x1c); db(0x4a); db(0xab);
+ db(0x00); db(0x14); db(0x66); db(0x22); db(0x4a); db(0xab); db(0x00); db(0x1c);
+ db(0x66); db(0xe0); db(0x43); db(0xfa); db(0x15); db(0x6c); db(0x70); db(0x00);
+ db(0x4e); db(0xae); db(0xfd); db(0xd8); db(0x27); db(0x40); db(0x00); db(0x14);
+ db(0x67); db(0xd0); db(0x22); db(0x00); db(0x30); db(0x3c); db(0x3f); db(0xf4);
+ db(0x61); db(0x00); db(0x14); db(0x16); db(0x20); db(0x81); db(0x4a); db(0xab);
+ db(0x00); db(0x18); db(0x66); db(0x24); db(0x4a); db(0xab); db(0x00); db(0x1c);
+ db(0x66); db(0xb8); db(0x43); db(0xfa); db(0x15); db(0x56); db(0x70); db(0x00);
+ db(0x4e); db(0xae); db(0xfd); db(0xd8); db(0x27); db(0x40); db(0x00); db(0x18);
+ db(0x67); db(0x00); db(0xff); db(0xa8); db(0x22); db(0x00); db(0x30); db(0x3c);
+ db(0x3f); db(0xf8); db(0x61); db(0x00); db(0x13); db(0xec); db(0x20); db(0x81);
+ db(0x4a); db(0xad); db(0x02); db(0x08); db(0x66); db(0x3a); db(0x4a); db(0xab);
+ db(0x00); db(0x1c); db(0x66); db(0x8e); db(0x4e); db(0xae); db(0xff); db(0x7c);
+ db(0x41); db(0xee); db(0x01); db(0x5e); db(0x43); db(0xfa); db(0x13); db(0xe4);
+ db(0x4e); db(0xae); db(0xfe); db(0xec); db(0x24); db(0x00); db(0x4e); db(0xae);
+ db(0xff); db(0x76); db(0x4a); db(0x82); db(0x67); db(0x00); db(0xff); db(0x74);
+ db(0x41); db(0xfa); db(0x13); db(0xd0); db(0x70); db(0x00); db(0x72); db(0x00);
+ db(0x61); db(0x00); db(0xfc); db(0xec); db(0x2b); db(0x40); db(0x02); db(0x08);
+ db(0x67); db(0x00); db(0x02); db(0x52); db(0x60); db(0x00); db(0xff); db(0x5c);
+ db(0x4a); db(0xad); db(0x02); db(0x0c); db(0x66); db(0x48); db(0x4a); db(0xab);
+ db(0x00); db(0x1c); db(0x66); db(0x00); db(0xff); db(0x4e); db(0x4e); db(0xae);
+ db(0xff); db(0x7c); db(0x41); db(0xee); db(0x01); db(0x5e); db(0x43); db(0xfa);
+ db(0x13); db(0xaf); db(0x4e); db(0xae); db(0xfe); db(0xec); db(0x24); db(0x00);
+ db(0x4e); db(0xae); db(0xff); db(0x76); db(0x4a); db(0x82); db(0x67); db(0x00);
+ db(0xff); db(0x32); db(0x41); db(0xfa); db(0x13); db(0x9b); db(0x70); db(0x00);
+ db(0x72); db(0x00); db(0x61); db(0x00); db(0xfc); db(0xaa); db(0x2b); db(0x40);
+ db(0x02); db(0x0c); db(0x67); db(0x00); db(0x02); db(0x10); db(0x30); db(0x3c);
+ db(0xff); db(0x38); db(0x72); db(0x00); db(0x61); db(0x00); db(0x13); db(0x52);
+ db(0x4e); db(0x90); db(0x60); db(0x00); db(0xff); db(0x0e); db(0x0c); db(0x47);
+ db(0x00); db(0x24); db(0x65); db(0x18); db(0x0c); db(0x47); db(0x00); db(0x32);
+ db(0x64); db(0x12); db(0x53); db(0xab); db(0x00); db(0x34); db(0x6a); db(0x0c);
+ db(0x20); db(0x4b); db(0x61); db(0x00); db(0xfd); db(0x8c); db(0x70); db(0x32);
+ db(0x27); db(0x40); db(0x00); db(0x34); db(0x45); db(0xed); db(0x01); db(0x3c);
+ db(0x10); db(0x2c); db(0x00); db(0x00); db(0x0c); db(0x47); db(0x00); db(0x27);
+ db(0x65); db(0x00); db(0x01); db(0x0a); db(0x08); db(0x00); db(0x00); db(0x01);
+ db(0x67); db(0x00); db(0x01); db(0x02); db(0x41); db(0xed); db(0x01); db(0x68);
+ db(0x25); db(0x48); db(0x00); db(0x0a); db(0x15); db(0x7c); db(0x00); db(0x13);
+ db(0x00); db(0x04); db(0x15); db(0x7c); db(0x00); db(0x03); db(0x00); db(0x05);
+ db(0x42); db(0x90); db(0x42); db(0xa8); db(0x00); db(0x04); db(0x42); db(0xa8);
+ db(0x00); db(0x08); db(0x42); db(0x68); db(0x00); db(0x0c); db(0x42); db(0x6a);
+ db(0x00); db(0x06); db(0x61); db(0x00); db(0x01); db(0xa2); db(0x31); db(0x6c);
+ db(0x00); db(0x0a); db(0x00); db(0x0e); db(0x42); db(0x68); db(0x00); db(0x10);
+ db(0x31); db(0x6c); db(0x00); db(0x0c); db(0x00); db(0x12); db(0x42); db(0x68);
+ db(0x00); db(0x14); db(0x31); db(0x6c); db(0x00); db(0x04); db(0x00); db(0x16);
+ db(0x42); db(0x68); db(0x00); db(0x18); db(0x31); db(0x6c); db(0x00); db(0x06);
+ db(0x00); db(0x1a); db(0x43); db(0xed); db(0x01); db(0x88); db(0x21); db(0x49);
+ db(0x00); db(0x1c); db(0x22); db(0xfc); db(0x80); db(0x03); db(0xa0); db(0x06);
+ db(0x30); db(0x2c); db(0x00); db(0x20); db(0x48); db(0xc0); db(0xe1); db(0x80);
+ db(0x22); db(0xc0); db(0x22); db(0xfc); db(0x80); db(0x03); db(0xa0); db(0x07);
+ db(0x22); db(0xec); db(0x00); db(0x22); db(0x70); db(0x00); db(0x30); db(0x2c);
+ db(0x00); db(0x10); db(0x6b); db(0x08); db(0x22); db(0xfc); db(0x80); db(0x03);
+ db(0xa0); db(0x09); db(0x22); db(0xc0); db(0x30); db(0x2c); db(0x00); db(0x12);
+ db(0x6b); db(0x08); db(0x22); db(0xfc); db(0x80); db(0x03); db(0xa0); db(0x0a);
+ db(0x22); db(0xc0); db(0x30); db(0x2c); db(0x00); db(0x08); db(0x6b); db(0x14);
+ db(0x22); db(0xfc); db(0x80); db(0x03); db(0xa0); db(0x02); db(0x22); db(0xc0);
+ db(0x30); db(0x2c); db(0x00); db(0x0e); db(0x22); db(0xfc); db(0x80); db(0x03);
+ db(0xa0); db(0x01); db(0x22); db(0xc0); db(0x30); db(0x2c); db(0x00); db(0x14);
+ db(0x6b); db(0x10); db(0x22); db(0xfc); db(0x80); db(0x03); db(0xa0); db(0x03);
+ db(0x30); db(0x2c); db(0x00); db(0x1a); db(0x48); db(0xc0); db(0xe1); db(0x80);
+ db(0x22); db(0xc0); db(0x30); db(0x2c); db(0x00); db(0x16); db(0x6b); db(0x10);
+ db(0x22); db(0xfc); db(0x80); db(0x03); db(0xa0); db(0x04); db(0x30); db(0x2c);
+ db(0x00); db(0x1c); db(0x48); db(0xc0); db(0xe1); db(0x80); db(0x22); db(0xc0);
+ db(0x30); db(0x2c); db(0x00); db(0x18); db(0x6b); db(0x10); db(0x22); db(0xfc);
+ db(0x80); db(0x03); db(0xa0); db(0x05); db(0x30); db(0x2c); db(0x00); db(0x1e);
+ db(0x48); db(0xc0); db(0xe1); db(0x80); db(0x22); db(0xc0); db(0x70); db(0x00);
+ db(0x30); db(0x2c); db(0x00); db(0x26); db(0x6b); db(0x08); db(0x22); db(0xfc);
+ db(0x80); db(0x03); db(0xa0); db(0x08); db(0x22); db(0xc0); db(0x42); db(0x91);
+ db(0x61); db(0x00); db(0xfc); db(0x02); db(0x10); db(0x2c); db(0x00); db(0x00);
+ db(0x08); db(0x00); db(0x00); db(0x01); db(0x66); db(0x08); db(0x08); db(0x00);
+ db(0x00); db(0x00); db(0x67); db(0x00); db(0xfd); db(0xc6); db(0x20); db(0x6b);
+ db(0x00); db(0x14); db(0x30); db(0x2c); db(0x00); db(0x28); db(0x32); db(0x28);
+ db(0x00); db(0x30); db(0xd2); db(0x41); db(0x90); db(0x41); db(0x6a); db(0x02);
+ db(0x70); db(0x00); db(0x35); db(0x40); db(0x00); db(0x0a); db(0x30); db(0x2c);
+ db(0x00); db(0x2a); db(0x32); db(0x28); db(0x00); db(0x2e); db(0xd2); db(0x41);
  db(0x90); db(0x41); db(0x6a); db(0x02); db(0x70); db(0x00); db(0x35); db(0x40);
- db(0x00); db(0x0a); db(0x30); db(0x2c); db(0x00); db(0x2a); db(0x32); db(0x28);
- db(0x00); db(0x2e); db(0xd2); db(0x41); db(0x90); db(0x41); db(0x6a); db(0x02);
- db(0x70); db(0x00); db(0x35); db(0x40); db(0x00); db(0x0c); db(0x08); db(0x2c);
- db(0x00); db(0x01); db(0x00); db(0x00); db(0x67); db(0x42); db(0x36); db(0x3c);
- db(0x00); db(0x68); db(0x74); db(0x01); db(0x28); db(0x2c); db(0x00); db(0x22);
- db(0x20); db(0x04); db(0xc0); db(0x82); db(0x22); db(0x2b); db(0x00); db(0x04);
- db(0xc2); db(0x82); db(0xb2); db(0x80); db(0x67); db(0x1c); db(0x35); db(0x7c);
- db(0x02); db(0x00); db(0x00); db(0x04); db(0x32); db(0x03); db(0x4a); db(0x00);
- db(0x66); db(0x04); db(0x08); db(0xc1); db(0x00); db(0x07); db(0x35); db(0x41);
- db(0x00); db(0x06); db(0x61); db(0x00); db(0x00); db(0x56); db(0x61); db(0x00);
- db(0xfb); db(0x88); db(0x52); db(0x43); db(0xd4); db(0x42); db(0x0c); db(0x42);
- db(0x00); db(0x08); db(0x66); db(0xcc); db(0x27); db(0x44); db(0x00); db(0x04);
- db(0x08); db(0x2c); db(0x00); db(0x00); db(0x00); db(0x00); db(0x67); db(0x00);
- db(0xfd); db(0x46); db(0x35); db(0x7c); db(0x04); db(0x00); db(0x00); db(0x04);
- db(0x42); db(0x6a); db(0x00); db(0x06); db(0x61); db(0x00); db(0x00); db(0x2c);
- db(0x0c); db(0x6e); db(0x00); db(0x24); db(0x00); db(0x14); db(0x65); db(0x18);
- db(0x2f); db(0x0e); db(0x2c); db(0x6d); db(0x02); db(0x08); db(0x2c); db(0x6e);
- db(0x00); db(0x14); db(0x4e); db(0xae); db(0xff); db(0xd6); db(0x2c); db(0x5f);
- db(0x02); db(0x40); db(0x7f); db(0xff); db(0x81); db(0x6a); db(0x00); db(0x08);
- db(0x61); db(0x00); db(0xfb); db(0x3e); db(0x60); db(0x00); db(0xfd); db(0x10);
- db(0x4e); db(0x75); db(0x22); db(0x2c); db(0x00); db(0x22); db(0x70); db(0x00);
- db(0x08); db(0x01); db(0x00); db(0x00); db(0x67); db(0x04); db(0x08); db(0xc0);
- db(0x00); db(0x0e); db(0x08); db(0x01); db(0x00); db(0x01); db(0x67); db(0x04);
- db(0x08); db(0xc0); db(0x00); db(0x0d); db(0x08); db(0x01); db(0x00); db(0x02);
- db(0x67); db(0x04); db(0x08); db(0xc0); db(0x00); db(0x0c); db(0x35); db(0x40);
- db(0x00); db(0x08); db(0x4e); db(0x75); db(0x4a); db(0xa9); db(0x02); db(0x08);
- db(0x67); db(0x18); db(0x4a); db(0xa9); db(0x02); db(0x0c); db(0x67); db(0x12);
- db(0x20); db(0x69); db(0x02); db(0x10); db(0x30); db(0x28); db(0x00); db(0x02);
- db(0xb0); db(0x69); db(0x00); db(0x16); db(0x67); db(0x18); db(0x33); db(0x40);
- db(0x00); db(0x16); db(0x2f); db(0x09); db(0x2c); db(0x69); db(0x00); db(0x26);
- db(0x20); db(0x29); db(0x00); db(0x22); db(0x22); db(0x69); db(0x00); db(0x1e);
- db(0x4e); db(0xae); db(0xfe); db(0xbc); db(0x22); db(0x5f); db(0x53); db(0x69);
- db(0x00); db(0x46); db(0x6a); db(0x10); db(0x33); db(0x7c); db(0x00); db(0x32);
- db(0x00); db(0x46); db(0x30); db(0x3c); db(0xff); db(0xff); db(0x61); db(0x00);
- db(0x0a); db(0x7c); db(0x50); db(0xd0); db(0x41); db(0xf9); db(0x00); db(0xdf);
- db(0xf0); db(0x00); db(0x70); db(0x00); db(0x4e); db(0x75); db(0x48); db(0xe7);
- db(0x00); db(0x06); db(0x30); db(0x3c); db(0xff); db(0x38); db(0x72); db(0x11);
- db(0x61); db(0x00); db(0x0a); db(0x52); db(0x4e); db(0x90); db(0x08); db(0x00);
- db(0x00); db(0x00); db(0x67); db(0x42); db(0x2c); db(0x78); db(0x00); db(0x04);
- db(0x20); db(0x3c); db(0x00); db(0x00); db(0x00); db(0x88); db(0x22); db(0x3c);
- db(0x00); db(0x01); db(0x00); db(0x01); db(0x4e); db(0xae); db(0xff); db(0x3a);
- db(0x4a); db(0x80); db(0x67); db(0x00); db(0x00); db(0x40); db(0x2a); db(0x40);
- db(0x2b); db(0x4e); db(0x00); db(0x14); db(0x30); db(0x3c); db(0xff); db(0x38);
- db(0x72); db(0x0e); db(0x61); db(0x00); db(0x0a); db(0x20); db(0x20); db(0x0d);
- db(0x4e); db(0x90); db(0x41); db(0xfa); db(0x0a); db(0xb9); db(0x43); db(0xfa);
- db(0x01); db(0x14); db(0x70); db(0xf6); db(0x22); db(0x3c); db(0x00); db(0x00);
- db(0x27); db(0x10); db(0x61); db(0x00); db(0xea); db(0xce); db(0x70); db(0x00);
- db(0x4c); db(0xdf); db(0x60); db(0x00); db(0x4e); db(0x75); db(0x30); db(0x3c);
- db(0xff); db(0x38); db(0x72); db(0x0a); db(0x61); db(0x00); db(0x09); db(0xf6);
- db(0x4e); db(0x90); db(0x4e); db(0x75); db(0x61); db(0xf0); db(0x20); db(0x0d);
- db(0x67); db(0x1c); db(0x2c); db(0x6d); db(0x00); db(0x14); db(0x20); db(0x2d);
- db(0x00); db(0x18); db(0x67); db(0x06); db(0x22); db(0x40); db(0x4e); db(0xae);
- db(0xfe); db(0x62); db(0x22); db(0x4d); db(0x20); db(0x3c); db(0x00); db(0x00);
- db(0x00); db(0x88); db(0x4e); db(0xae); db(0xff); db(0x2e); db(0x70); db(0x00);
- db(0x4e); db(0x75); db(0x48); db(0xe7); db(0x38); db(0x3e); db(0x2c); db(0x6d);
- db(0x00); db(0x18); db(0x41); db(0xfa); db(0x0a); db(0x47); db(0x22); db(0x08);
- db(0x24); db(0x3c); db(0x00); db(0x00); db(0x03); db(0xed); db(0x4e); db(0xae);
- db(0xff); db(0xe2); db(0x28); db(0x00); db(0x67); db(0x4c); db(0x45); db(0xed);
- db(0x00); db(0x68); db(0x42); db(0x92); db(0x34); db(0xaa); db(0x00); db(0x02);
- db(0x24); db(0x0a); db(0x54); db(0x82); db(0x76); db(0x02); db(0x22); db(0x04);
- db(0x4e); db(0xae); db(0xff); db(0xd6); db(0xb6); db(0x80); db(0x66); db(0x32);
- db(0x0c); db(0x92); db(0x50); db(0x4e); db(0x54); db(0x52); db(0x66); db(0xe4);
- db(0x24); db(0x0a); db(0x76); db(0x04); db(0x22); db(0x04); db(0x4e); db(0xae);
- db(0xff); db(0xd6); db(0x24); db(0x0a); db(0x76); db(0x20); db(0x22); db(0x04);
- db(0x4e); db(0xae); db(0xff); db(0xd6); db(0xb6); db(0x80); db(0x66); db(0x12);
- db(0x4a); db(0x6a); db(0x00); db(0x10); db(0x66); db(0xc4); db(0x30); db(0x3c);
- db(0xff); db(0x38); db(0x72); db(0x10); db(0x61); db(0x00); db(0x09); db(0x66);
- db(0x4e); db(0x90); db(0x22); db(0x04); db(0x67); db(0x04); db(0x4e); db(0xae);
- db(0xff); db(0xdc); db(0x4c); db(0xdf); db(0x7c); db(0x1c); db(0x4e); db(0x75);
- db(0x2c); db(0x6d); db(0x00); db(0x18); db(0x41); db(0xfa); db(0x09); db(0xba);
- db(0x22); db(0x08); db(0x74); db(0xfe); db(0x4e); db(0xae); db(0xff); db(0xac);
- db(0x22); db(0x00); db(0x67); db(0x34); db(0x4e); db(0xae); db(0xff); db(0xa6);
- db(0x2c); db(0x6d); db(0x00); db(0x14); db(0x45); db(0xed); db(0x00); db(0x38);
- db(0x70); db(0xff); db(0x4e); db(0xae); db(0xfe); db(0xb6); db(0x15); db(0x40);
- db(0x00); db(0x14); db(0x41); db(0xfa); db(0x09); db(0xaf); db(0x24); db(0x88);
- db(0x25); db(0x7c); db(0x00); db(0x00); db(0x00); db(0x12); db(0x00); db(0x0c);
- db(0x25); db(0x6d); db(0x00); db(0x08); db(0x00); db(0x10); db(0x2c); db(0x6d);
- db(0x00); db(0x18); db(0x22); db(0x0a); db(0x4e); db(0xae); db(0xfc); db(0x88);
- db(0x2c); db(0x6d); db(0x00); db(0x14); db(0x4e); db(0x75); db(0x00); db(0x00);
- db(0x00); db(0x00); db(0x00); db(0x10); db(0x00); db(0x00); db(0x00); db(0x00);
- db(0x30); db(0x3c); db(0xff); db(0x38); db(0x72); db(0x0d); db(0x61); db(0x00);
- db(0x08); db(0xf4); db(0x4e); db(0x90); db(0x4a); db(0x80); db(0x67); db(0x00);
- db(0xfe); db(0xfc); db(0x2a); db(0x40); db(0x2c); db(0x6d); db(0x00); db(0x14);
- db(0x93); db(0xc9); db(0x4e); db(0xae); db(0xfe); db(0xda); db(0x2b); db(0x40);
- db(0x00); db(0x08); db(0x43); db(0xfa); db(0x0a); db(0x0d); db(0x70); db(0x00);
- db(0x4e); db(0xae); db(0xfd); db(0xd8); db(0x2b); db(0x40); db(0x00); db(0x18);
- db(0x67); db(0x00); db(0xfe); db(0xda); db(0x2c); db(0x40); db(0x72); db(0x32);
- db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x41); db(0xfa); db(0x09); db(0x0e);
+ db(0x00); db(0x0c); db(0x08); db(0x2c); db(0x00); db(0x01); db(0x00); db(0x00);
+ db(0x67); db(0x42); db(0x36); db(0x3c); db(0x00); db(0x68); db(0x74); db(0x01);
+ db(0x28); db(0x2c); db(0x00); db(0x22); db(0x20); db(0x04); db(0xc0); db(0x82);
+ db(0x22); db(0x2b); db(0x00); db(0x04); db(0xc2); db(0x82); db(0xb2); db(0x80);
+ db(0x67); db(0x1c); db(0x35); db(0x7c); db(0x02); db(0x00); db(0x00); db(0x04);
+ db(0x32); db(0x03); db(0x4a); db(0x00); db(0x66); db(0x04); db(0x08); db(0xc1);
+ db(0x00); db(0x07); db(0x35); db(0x41); db(0x00); db(0x06); db(0x61); db(0x00);
+ db(0x00); db(0x56); db(0x61); db(0x00); db(0xfb); db(0x88); db(0x52); db(0x43);
+ db(0xd4); db(0x42); db(0x0c); db(0x42); db(0x00); db(0x08); db(0x66); db(0xcc);
+ db(0x27); db(0x44); db(0x00); db(0x04); db(0x08); db(0x2c); db(0x00); db(0x00);
+ db(0x00); db(0x00); db(0x67); db(0x00); db(0xfd); db(0x46); db(0x35); db(0x7c);
+ db(0x04); db(0x00); db(0x00); db(0x04); db(0x42); db(0x6a); db(0x00); db(0x06);
+ db(0x61); db(0x00); db(0x00); db(0x2c); db(0x0c); db(0x6e); db(0x00); db(0x24);
+ db(0x00); db(0x14); db(0x65); db(0x18); db(0x2f); db(0x0e); db(0x2c); db(0x6d);
+ db(0x02); db(0x08); db(0x2c); db(0x6e); db(0x00); db(0x14); db(0x4e); db(0xae);
+ db(0xff); db(0xd6); db(0x2c); db(0x5f); db(0x02); db(0x40); db(0x7f); db(0xff);
+ db(0x81); db(0x6a); db(0x00); db(0x08); db(0x61); db(0x00); db(0xfb); db(0x3e);
+ db(0x60); db(0x00); db(0xfd); db(0x10); db(0x4e); db(0x75); db(0x22); db(0x2c);
+ db(0x00); db(0x22); db(0x70); db(0x00); db(0x08); db(0x01); db(0x00); db(0x00);
+ db(0x67); db(0x04); db(0x08); db(0xc0); db(0x00); db(0x0e); db(0x08); db(0x01);
+ db(0x00); db(0x01); db(0x67); db(0x04); db(0x08); db(0xc0); db(0x00); db(0x0d);
+ db(0x08); db(0x01); db(0x00); db(0x02); db(0x67); db(0x04); db(0x08); db(0xc0);
+ db(0x00); db(0x0c); db(0x35); db(0x40); db(0x00); db(0x08); db(0x4e); db(0x75);
+ db(0x4a); db(0xa9); db(0x02); db(0x08); db(0x67); db(0x18); db(0x4a); db(0xa9);
+ db(0x02); db(0x0c); db(0x67); db(0x12); db(0x20); db(0x69); db(0x02); db(0x10);
+ db(0x30); db(0x28); db(0x00); db(0x02); db(0xb0); db(0x69); db(0x00); db(0x16);
+ db(0x67); db(0x18); db(0x33); db(0x40); db(0x00); db(0x16); db(0x2f); db(0x09);
+ db(0x2c); db(0x69); db(0x00); db(0x26); db(0x20); db(0x29); db(0x00); db(0x22);
+ db(0x22); db(0x69); db(0x00); db(0x1e); db(0x4e); db(0xae); db(0xfe); db(0xbc);
+ db(0x22); db(0x5f); db(0x53); db(0x69); db(0x00); db(0x46); db(0x6a); db(0x10);
+ db(0x33); db(0x7c); db(0x00); db(0x32); db(0x00); db(0x46); db(0x30); db(0x3c);
+ db(0xff); db(0xff); db(0x61); db(0x00); db(0x10); db(0xec); db(0x50); db(0xd0);
+ db(0x41); db(0xf9); db(0x00); db(0xdf); db(0xf0); db(0x00); db(0x70); db(0x00);
+ db(0x4e); db(0x75); db(0x48); db(0xe7); db(0x00); db(0x06); db(0x30); db(0x3c);
+ db(0xff); db(0x38); db(0x72); db(0x11); db(0x61); db(0x00); db(0x10); db(0xc2);
+ db(0x4e); db(0x90); db(0x08); db(0x00); db(0x00); db(0x00); db(0x67); db(0x42);
+ db(0x2c); db(0x78); db(0x00); db(0x04); db(0x20); db(0x3c); db(0x00); db(0x00);
+ db(0x00); db(0x88); db(0x22); db(0x3c); db(0x00); db(0x01); db(0x00); db(0x01);
+ db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x4a); db(0x80); db(0x67); db(0x00);
+ db(0x00); db(0x40); db(0x2a); db(0x40); db(0x2b); db(0x4e); db(0x00); db(0x14);
+ db(0x30); db(0x3c); db(0xff); db(0x38); db(0x72); db(0x0e); db(0x61); db(0x00);
+ db(0x10); db(0x90); db(0x20); db(0x0d); db(0x4e); db(0x90); db(0x41); db(0xfa);
+ db(0x11); db(0x38); db(0x43); db(0xfa); db(0x01); db(0x14); db(0x70); db(0xf6);
+ db(0x22); db(0x3c); db(0x00); db(0x00); db(0x27); db(0x10); db(0x61); db(0x00);
+ db(0xea); db(0xce); db(0x70); db(0x00); db(0x4c); db(0xdf); db(0x60); db(0x00);
+ db(0x4e); db(0x75); db(0x30); db(0x3c); db(0xff); db(0x38); db(0x72); db(0x0a);
+ db(0x61); db(0x00); db(0x10); db(0x66); db(0x4e); db(0x90); db(0x4e); db(0x75);
+ db(0x61); db(0xf0); db(0x20); db(0x0d); db(0x67); db(0x1c); db(0x2c); db(0x6d);
+ db(0x00); db(0x14); db(0x20); db(0x2d); db(0x00); db(0x18); db(0x67); db(0x06);
+ db(0x22); db(0x40); db(0x4e); db(0xae); db(0xfe); db(0x62); db(0x22); db(0x4d);
+ db(0x20); db(0x3c); db(0x00); db(0x00); db(0x00); db(0x88); db(0x4e); db(0xae);
+ db(0xff); db(0x2e); db(0x70); db(0x00); db(0x4e); db(0x75); db(0x48); db(0xe7);
+ db(0x38); db(0x3e); db(0x2c); db(0x6d); db(0x00); db(0x18); db(0x41); db(0xfa);
+ db(0x10); db(0xc6); db(0x22); db(0x08); db(0x24); db(0x3c); db(0x00); db(0x00);
+ db(0x03); db(0xed); db(0x4e); db(0xae); db(0xff); db(0xe2); db(0x28); db(0x00);
+ db(0x67); db(0x4c); db(0x45); db(0xed); db(0x00); db(0x68); db(0x42); db(0x92);
+ db(0x34); db(0xaa); db(0x00); db(0x02); db(0x24); db(0x0a); db(0x54); db(0x82);
+ db(0x76); db(0x02); db(0x22); db(0x04); db(0x4e); db(0xae); db(0xff); db(0xd6);
+ db(0xb6); db(0x80); db(0x66); db(0x32); db(0x0c); db(0x92); db(0x50); db(0x4e);
+ db(0x54); db(0x52); db(0x66); db(0xe4); db(0x24); db(0x0a); db(0x76); db(0x04);
+ db(0x22); db(0x04); db(0x4e); db(0xae); db(0xff); db(0xd6); db(0x24); db(0x0a);
+ db(0x76); db(0x20); db(0x22); db(0x04); db(0x4e); db(0xae); db(0xff); db(0xd6);
+ db(0xb6); db(0x80); db(0x66); db(0x12); db(0x4a); db(0x6a); db(0x00); db(0x10);
+ db(0x66); db(0xc4); db(0x30); db(0x3c); db(0xff); db(0x38); db(0x72); db(0x10);
+ db(0x61); db(0x00); db(0x0f); db(0xd6); db(0x4e); db(0x90); db(0x22); db(0x04);
+ db(0x67); db(0x04); db(0x4e); db(0xae); db(0xff); db(0xdc); db(0x4c); db(0xdf);
+ db(0x7c); db(0x1c); db(0x4e); db(0x75); db(0x2c); db(0x6d); db(0x00); db(0x18);
+ db(0x41); db(0xfa); db(0x10); db(0x39); db(0x22); db(0x08); db(0x74); db(0xfe);
+ db(0x4e); db(0xae); db(0xff); db(0xac); db(0x22); db(0x00); db(0x67); db(0x34);
+ db(0x4e); db(0xae); db(0xff); db(0xa6); db(0x2c); db(0x6d); db(0x00); db(0x14);
+ db(0x45); db(0xed); db(0x00); db(0x38); db(0x70); db(0xff); db(0x4e); db(0xae);
+ db(0xfe); db(0xb6); db(0x15); db(0x40); db(0x00); db(0x14); db(0x41); db(0xfa);
+ db(0x10); db(0x2e); db(0x24); db(0x88); db(0x25); db(0x7c); db(0x00); db(0x00);
+ db(0x00); db(0x12); db(0x00); db(0x0c); db(0x25); db(0x6d); db(0x00); db(0x08);
+ db(0x00); db(0x10); db(0x2c); db(0x6d); db(0x00); db(0x18); db(0x22); db(0x0a);
+ db(0x4e); db(0xae); db(0xfc); db(0x88); db(0x2c); db(0x6d); db(0x00); db(0x14);
+ db(0x4e); db(0x75); db(0x00); db(0x00); db(0x00); db(0x00); db(0x00); db(0x10);
+ db(0x00); db(0x00); db(0x00); db(0x00); db(0x30); db(0x3c); db(0xff); db(0x38);
+ db(0x72); db(0x0d); db(0x61); db(0x00); db(0x0f); db(0x64); db(0x4e); db(0x90);
+ db(0x4a); db(0x80); db(0x67); db(0x00); db(0xfe); db(0xfc); db(0x2a); db(0x40);
+ db(0x2c); db(0x6d); db(0x00); db(0x14); db(0x93); db(0xc9); db(0x4e); db(0xae);
+ db(0xfe); db(0xda); db(0x2b); db(0x40); db(0x00); db(0x08); db(0x43); db(0xfa);
+ db(0x10); db(0x8c); db(0x70); db(0x00); db(0x4e); db(0xae); db(0xfd); db(0xd8);
+ db(0x2b); db(0x40); db(0x00); db(0x18); db(0x67); db(0x00); db(0xfe); db(0xda);
+ db(0x2c); db(0x40); db(0x72); db(0x32); db(0x4e); db(0xae); db(0xff); db(0x3a);
+ db(0x41); db(0xfa); db(0x0f); db(0x8d); db(0x22); db(0x08); db(0x74); db(0xfe);
+ db(0x4e); db(0xae); db(0xff); db(0xac); db(0x4a); db(0x80); db(0x67); db(0xea);
+ db(0x22); db(0x00); db(0x4e); db(0xae); db(0xff); db(0xa6); db(0x72); db(0x32);
+ db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x41); db(0xfa); db(0x0f); db(0x77);
  db(0x22); db(0x08); db(0x74); db(0xfe); db(0x4e); db(0xae); db(0xff); db(0xac);
- db(0x4a); db(0x80); db(0x67); db(0xea); db(0x22); db(0x00); db(0x4e); db(0xae);
- db(0xff); db(0xa6); db(0x72); db(0x32); db(0x4e); db(0xae); db(0xff); db(0x3a);
- db(0x41); db(0xfa); db(0x08); db(0xf8); db(0x22); db(0x08); db(0x74); db(0xfe);
- db(0x4e); db(0xae); db(0xff); db(0xac); db(0x4a); db(0x80); db(0x67); db(0x00);
- db(0xfe); db(0xa4); db(0x22); db(0x00); db(0x4e); db(0xae); db(0xff); db(0xa6);
- db(0x2c); db(0x6d); db(0x00); db(0x14); db(0x61); db(0x00); db(0xf7); db(0xb6);
- db(0x72); db(0x00); db(0x32); db(0x3c); db(0x00); db(0x34); db(0x61); db(0x00);
- db(0xf7); db(0xfa); db(0x28); db(0x40); db(0x4a); db(0x80); db(0x67); db(0x00);
- db(0xfe); db(0x84); db(0x70); db(0x00); db(0x08); db(0xc0); db(0x00); db(0x0d);
- db(0x4e); db(0xae); db(0xfe); db(0xc2); db(0x72); db(0x00); db(0x20); db(0x2d);
- db(0x00); db(0x0c); db(0x41); db(0xfa); db(0x08); db(0xd6); db(0x22); db(0x4c);
- db(0x4e); db(0xae); db(0xfe); db(0x44); db(0x4a); db(0x80); db(0x66); db(0xe2);
- db(0x20); db(0x6c); db(0x00); db(0x14); db(0x0c); db(0x68); db(0x00); db(0x25);
- db(0x00); db(0x14); db(0x64); db(0x0c); db(0x61); db(0x00); db(0xfe); db(0x48);
- db(0x70); db(0x00); db(0x4e); db(0xae); db(0xfe); db(0xc2); db(0x60); db(0xf8);
- db(0x61); db(0x00); db(0xfe); db(0xe6); db(0x41); db(0xed); db(0x00); db(0x1c);
- db(0x29); db(0x48); db(0x00); db(0x28); db(0x70); db(0x01); db(0x29); db(0x40);
- db(0x00); db(0x24); db(0x39); db(0x7c); db(0x00); db(0x0c); db(0x00); db(0x1c);
- db(0x2b); db(0x4d); db(0x00); db(0x2c); db(0x41); db(0xfa); db(0x01); db(0x60);
- db(0x2b); db(0x48); db(0x00); db(0x24); db(0x22); db(0x4c); db(0x4e); db(0xae);
- db(0xfe); db(0x38); db(0x30); db(0x3c); db(0xff); db(0x38); db(0x72); db(0x0f);
- db(0x61); db(0x00); db(0x08); db(0x0a); db(0x4e); db(0x90); db(0x4a); db(0xad);
- db(0x00); db(0x00); db(0x66); db(0x1c); db(0x70); db(0x00); db(0x74); db(0x00);
- db(0x14); db(0x2d); db(0x00); db(0x4c); db(0x05); db(0xc0); db(0x08); db(0xc0);
- db(0x00); db(0x0d); db(0x4e); db(0xae); db(0xfe); db(0xc2); db(0x05); db(0x00);
- db(0x67); db(0x06); db(0x61); db(0x00); db(0xfe); db(0x1e); db(0x60); db(0xe4);
- db(0x20); db(0x2d); db(0x00); db(0x00); db(0x67); db(0x00); db(0x00); db(0x76);
- db(0x72); db(0x01); db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x2b); db(0x40);
- db(0x00); db(0x04); db(0x30); db(0x3c); db(0xff); db(0x38); db(0x72); db(0x0c);
- db(0x61); db(0x00); db(0x07); db(0xca); db(0x4e); db(0x90); db(0x4a); db(0x80);
- db(0x67); db(0x40); db(0x4a); db(0xad); db(0x00); db(0x04); db(0x67); db(0x3a);
- db(0x39); db(0x7c); db(0x00); db(0x03); db(0x00); db(0x1c); db(0x42); db(0x2c);
- db(0x00); db(0x1f); db(0x42); db(0xac); db(0x00); db(0x20); db(0x29); db(0x6d);
- db(0x00); db(0x00); db(0x00); db(0x24); db(0x29); db(0x6d); db(0x00); db(0x04);
- db(0x00); db(0x28); db(0x42); db(0xac); db(0x00); db(0x2c); db(0x42); db(0xac);
- db(0x00); db(0x30); db(0x22); db(0x4c); db(0x4e); db(0xae); db(0xfe); db(0x38);
- db(0x2b); db(0x6c); db(0x00); db(0x30); db(0x00); db(0x10); db(0x39); db(0x7c);
- db(0x00); db(0x04); db(0x00); db(0x1c); db(0x22); db(0x4c); db(0x4e); db(0xae);
- db(0xfe); db(0x38); db(0x20); db(0x2d); db(0x00); db(0x00); db(0x42); db(0xad);
- db(0x00); db(0x00); db(0x22); db(0x2d); db(0x00); db(0x04); db(0x67); db(0x00);
- db(0xff); db(0x74); db(0x22); db(0x41); db(0x4e); db(0xae); db(0xff); db(0x2e);
- db(0x60); db(0x00); db(0xff); db(0x6a); db(0x39); db(0x7c); db(0x00); db(0x02);
- db(0x00); db(0x1c); db(0x41); db(0xed); db(0x00); db(0x30); db(0x42); db(0x90);
- db(0x42); db(0xa8); db(0x00); db(0x04); db(0x42); db(0x2c); db(0x00); db(0x1f);
- db(0x42); db(0xac); db(0x00); db(0x2c); db(0x42); db(0xac); db(0x00); db(0x30);
- db(0x29); db(0x48); db(0x00); db(0x28); db(0x70); db(0x08); db(0x29); db(0x40);
+ db(0x4a); db(0x80); db(0x67); db(0x00); db(0xfe); db(0xa4); db(0x22); db(0x00);
+ db(0x4e); db(0xae); db(0xff); db(0xa6); db(0x2c); db(0x6d); db(0x00); db(0x14);
+ db(0x61); db(0x00); db(0xf7); db(0xb6); db(0x72); db(0x00); db(0x32); db(0x3c);
+ db(0x00); db(0x34); db(0x61); db(0x00); db(0xf7); db(0xfa); db(0x28); db(0x40);
+ db(0x4a); db(0x80); db(0x67); db(0x00); db(0xfe); db(0x84); db(0x70); db(0x00);
+ db(0x08); db(0xc0); db(0x00); db(0x0d); db(0x4e); db(0xae); db(0xfe); db(0xc2);
+ db(0x72); db(0x00); db(0x20); db(0x2d); db(0x00); db(0x0c); db(0x41); db(0xfa);
+ db(0x0f); db(0x55); db(0x22); db(0x4c); db(0x4e); db(0xae); db(0xfe); db(0x44);
+ db(0x4a); db(0x80); db(0x66); db(0xe2); db(0x20); db(0x6c); db(0x00); db(0x14);
+ db(0x0c); db(0x68); db(0x00); db(0x25); db(0x00); db(0x14); db(0x64); db(0x0c);
+ db(0x61); db(0x00); db(0xfe); db(0x48); db(0x70); db(0x00); db(0x4e); db(0xae);
+ db(0xfe); db(0xc2); db(0x60); db(0xf8); db(0x61); db(0x00); db(0xfe); db(0xe6);
+ db(0x41); db(0xed); db(0x00); db(0x1c); db(0x29); db(0x48); db(0x00); db(0x28);
+ db(0x70); db(0x01); db(0x29); db(0x40); db(0x00); db(0x24); db(0x39); db(0x7c);
+ db(0x00); db(0x0c); db(0x00); db(0x1c); db(0x2b); db(0x4d); db(0x00); db(0x2c);
+ db(0x41); db(0xfa); db(0x01); db(0x60); db(0x2b); db(0x48); db(0x00); db(0x24);
+ db(0x22); db(0x4c); db(0x4e); db(0xae); db(0xfe); db(0x38); db(0x30); db(0x3c);
+ db(0xff); db(0x38); db(0x72); db(0x0f); db(0x61); db(0x00); db(0x0e); db(0x7a);
+ db(0x4e); db(0x90); db(0x4a); db(0xad); db(0x00); db(0x00); db(0x66); db(0x1c);
+ db(0x70); db(0x00); db(0x74); db(0x00); db(0x14); db(0x2d); db(0x00); db(0x4c);
+ db(0x05); db(0xc0); db(0x08); db(0xc0); db(0x00); db(0x0d); db(0x4e); db(0xae);
+ db(0xfe); db(0xc2); db(0x05); db(0x00); db(0x67); db(0x06); db(0x61); db(0x00);
+ db(0xfe); db(0x1e); db(0x60); db(0xe4); db(0x20); db(0x2d); db(0x00); db(0x00);
+ db(0x67); db(0x00); db(0x00); db(0x76); db(0x72); db(0x01); db(0x4e); db(0xae);
+ db(0xff); db(0x3a); db(0x2b); db(0x40); db(0x00); db(0x04); db(0x30); db(0x3c);
+ db(0xff); db(0x38); db(0x72); db(0x0c); db(0x61); db(0x00); db(0x0e); db(0x3a);
+ db(0x4e); db(0x90); db(0x4a); db(0x80); db(0x67); db(0x40); db(0x4a); db(0xad);
+ db(0x00); db(0x04); db(0x67); db(0x3a); db(0x39); db(0x7c); db(0x00); db(0x03);
+ db(0x00); db(0x1c); db(0x42); db(0x2c); db(0x00); db(0x1f); db(0x42); db(0xac);
+ db(0x00); db(0x20); db(0x29); db(0x6d); db(0x00); db(0x00); db(0x00); db(0x24);
+ db(0x29); db(0x6d); db(0x00); db(0x04); db(0x00); db(0x28); db(0x42); db(0xac);
+ db(0x00); db(0x2c); db(0x42); db(0xac); db(0x00); db(0x30); db(0x22); db(0x4c);
+ db(0x4e); db(0xae); db(0xfe); db(0x38); db(0x2b); db(0x6c); db(0x00); db(0x30);
+ db(0x00); db(0x10); db(0x39); db(0x7c); db(0x00); db(0x04); db(0x00); db(0x1c);
+ db(0x22); db(0x4c); db(0x4e); db(0xae); db(0xfe); db(0x38); db(0x20); db(0x2d);
+ db(0x00); db(0x00); db(0x42); db(0xad); db(0x00); db(0x00); db(0x22); db(0x2d);
+ db(0x00); db(0x04); db(0x67); db(0x00); db(0xff); db(0x74); db(0x22); db(0x41);
+ db(0x4e); db(0xae); db(0xff); db(0x2e); db(0x60); db(0x00); db(0xff); db(0x6a);
+ db(0x39); db(0x7c); db(0x00); db(0x02); db(0x00); db(0x1c); db(0x41); db(0xed);
+ db(0x00); db(0x30); db(0x42); db(0x90); db(0x42); db(0xa8); db(0x00); db(0x04);
+ db(0x42); db(0x2c); db(0x00); db(0x1f); db(0x42); db(0xac); db(0x00); db(0x2c);
+ db(0x42); db(0xac); db(0x00); db(0x30); db(0x29); db(0x48); db(0x00); db(0x28);
+ db(0x70); db(0x08); db(0x29); db(0x40); db(0x00); db(0x24); db(0x22); db(0x4c);
+ db(0x4e); db(0xae); db(0xfe); db(0x38); db(0x0c); db(0xad); db(0x46); db(0x4f);
+ db(0x52); db(0x4d); db(0x00); db(0x30); db(0x66); db(0x52); db(0x20); db(0x2d);
+ db(0x00); db(0x34); db(0x67); db(0x4c); db(0x6b); db(0x4a); db(0x2b); db(0x6c);
+ db(0x00); db(0x30); db(0x00); db(0x10); db(0x50); db(0x80); db(0x24); db(0x00);
+ db(0x72); db(0x01); db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x4a); db(0x80);
+ db(0x67); db(0x36); db(0x24); db(0x40); db(0x20); db(0x4a); db(0x20); db(0xed);
+ db(0x00); db(0x30); db(0x20); db(0xed); db(0x00); db(0x34); db(0x29); db(0x48);
+ db(0x00); db(0x28); db(0x20); db(0x02); db(0x51); db(0x80); db(0x29); db(0x40);
  db(0x00); db(0x24); db(0x22); db(0x4c); db(0x4e); db(0xae); db(0xfe); db(0x38);
- db(0x0c); db(0xad); db(0x46); db(0x4f); db(0x52); db(0x4d); db(0x00); db(0x30);
- db(0x66); db(0x52); db(0x20); db(0x2d); db(0x00); db(0x34); db(0x67); db(0x4c);
- db(0x6b); db(0x4a); db(0x2b); db(0x6c); db(0x00); db(0x30); db(0x00); db(0x10);
- db(0x50); db(0x80); db(0x24); db(0x00); db(0x72); db(0x01); db(0x4e); db(0xae);
- db(0xff); db(0x3a); db(0x4a); db(0x80); db(0x67); db(0x36); db(0x24); db(0x40);
- db(0x20); db(0x4a); db(0x20); db(0xed); db(0x00); db(0x30); db(0x20); db(0xed);
- db(0x00); db(0x34); db(0x29); db(0x48); db(0x00); db(0x28); db(0x20); db(0x02);
- db(0x51); db(0x80); db(0x29); db(0x40); db(0x00); db(0x24); db(0x22); db(0x4c);
- db(0x4e); db(0xae); db(0xfe); db(0x38); db(0x30); db(0x3c); db(0xff); db(0x38);
- db(0x72); db(0x0b); db(0x61); db(0x00); db(0x06); db(0xf0); db(0x20); db(0x2c);
- db(0x00); db(0x20); db(0x4e); db(0x90); db(0x22); db(0x4a); db(0x20); db(0x02);
- db(0x4e); db(0xae); db(0xff); db(0x2e); db(0x4a); db(0xac); db(0x00); db(0x20);
- db(0x67); db(0x00); db(0xfe); db(0xda); db(0x41); db(0xed); db(0x00); db(0x30);
- db(0x29); db(0x48); db(0x00); db(0x28); db(0x70); db(0x01); db(0x29); db(0x40);
- db(0x00); db(0x24); db(0x42); db(0xac); db(0x00); db(0x20); db(0x22); db(0x4c);
- db(0x4e); db(0xae); db(0xfe); db(0x38); db(0x60); db(0xde); db(0x41); db(0xe8);
- db(0xff); db(0xe4); db(0x20); db(0x29); db(0x00); db(0x08); db(0xb0); db(0xa8);
- db(0x00); db(0x10); db(0x67); db(0x1a); db(0x21); db(0x40); db(0x00); db(0x10);
- db(0x2f); db(0x0e); db(0x2c); db(0x68); db(0x00); db(0x14); db(0x22); db(0x68);
- db(0x00); db(0x08); db(0x70); db(0x00); db(0x08); db(0xc0); db(0x00); db(0x0d);
- db(0x4e); db(0xae); db(0xfe); db(0xbc); db(0x2c); db(0x5f); db(0x70); db(0x00);
- db(0x4e); db(0x75); db(0x2c); db(0x78); db(0x00); db(0x04); db(0x74); db(0xff);
- db(0x30); db(0x3c); db(0xff); db(0x38); db(0x72); db(0x11); db(0x61); db(0x00);
- db(0x06); db(0x84); db(0x4e); db(0x90); db(0x08); db(0x00); db(0x00); db(0x01);
- db(0x67); db(0x38); db(0x74); db(0x00); db(0x4e); db(0xae); db(0xff); db(0x7c);
- db(0x41); db(0xee); db(0x01); db(0x5e); db(0x43); db(0xfa); db(0x06); db(0xaa);
- db(0x4e); db(0xae); db(0xfe); db(0xec); db(0x4a); db(0x80); db(0x67); db(0x1e);
- db(0x20); db(0x40); db(0x43); db(0xfa); db(0x00); db(0x22); db(0x24); db(0x68);
- db(0xff); db(0xe4); db(0x21); db(0x49); db(0xff); db(0xe4); db(0x22); db(0x48);
- db(0x30); db(0x3c); db(0xff); db(0x38); db(0x72); db(0x65); db(0x61); db(0x00);
- db(0x06); db(0x4c); db(0x4e); db(0x90); db(0x74); db(0x01); db(0x4e); db(0xae);
- db(0xff); db(0x76); db(0x20); db(0x02); db(0x4e); db(0x75); db(0x59); db(0x8f);
- db(0x48); db(0xe7); db(0xc0); db(0x80); db(0x30); db(0x3c); db(0xff); db(0x38);
- db(0x72); db(0x66); db(0x61); db(0x00); db(0x06); db(0x30); db(0x4e); db(0x90);
- db(0x4c); db(0xdf); db(0x01); db(0x03); db(0x4e); db(0x75); db(0x2c); db(0x78);
- db(0x00); db(0x04); db(0x41); db(0xfa); db(0x07); db(0x48); db(0x43); db(0xfa);
- db(0x00); db(0x14); db(0x70); db(0x0f); db(0x22); db(0x3c); db(0x00); db(0x00);
- db(0x1f); db(0x40); db(0x61); db(0x00); db(0xe6); db(0xd6); db(0x4e); db(0x75);
- db(0x00); db(0x00); db(0x00); db(0x10); db(0x00); db(0x00); db(0x00); db(0x00);
- db(0x2c); db(0x78); db(0x00); db(0x04); db(0x70); db(0x00); db(0x43); db(0xfa);
- db(0x07); db(0x31); db(0x4e); db(0xae); db(0xfd); db(0xd8); db(0x72); db(0x02);
- db(0x30); db(0x3c); db(0xff); db(0x78); db(0x61); db(0x00); db(0x05); db(0xee);
- db(0x24); db(0x48); db(0x72); db(0x01); db(0x4e); db(0x90); db(0x4a); db(0x81);
- db(0x67); db(0x0c); db(0x26); db(0x41); db(0x4e); db(0xae); db(0xfe); db(0x08);
- db(0x72); db(0x02); db(0x20); db(0x4b); db(0x4e); db(0x92); db(0x22); db(0x4e);
- db(0x2c); db(0x78); db(0x00); db(0x04); db(0x4e); db(0xae); db(0xfe); db(0x62);
- db(0x4e); db(0x75); db(0x4e); db(0x75); db(0xbc); db(0xfc); db(0x00); db(0x00);
- db(0x67); db(0x06); db(0x4e); db(0xae); db(0xff); db(0x70); db(0x4e); db(0x75);
- db(0x48); db(0xe7); db(0x3f); db(0x3e); db(0x24); db(0x48); db(0x2c); db(0x78);
- db(0x00); db(0x04); db(0x20); db(0x3c); db(0x00); db(0x00); db(0x01); db(0x00);
+ db(0x30); db(0x3c); db(0xff); db(0x38); db(0x72); db(0x0b); db(0x61); db(0x00);
+ db(0x0d); db(0x60); db(0x20); db(0x2c); db(0x00); db(0x20); db(0x4e); db(0x90);
+ db(0x22); db(0x4a); db(0x20); db(0x02); db(0x4e); db(0xae); db(0xff); db(0x2e);
+ db(0x4a); db(0xac); db(0x00); db(0x20); db(0x67); db(0x00); db(0xfe); db(0xda);
+ db(0x41); db(0xed); db(0x00); db(0x30); db(0x29); db(0x48); db(0x00); db(0x28);
+ db(0x70); db(0x01); db(0x29); db(0x40); db(0x00); db(0x24); db(0x42); db(0xac);
+ db(0x00); db(0x20); db(0x22); db(0x4c); db(0x4e); db(0xae); db(0xfe); db(0x38);
+ db(0x60); db(0xde); db(0x41); db(0xe8); db(0xff); db(0xe4); db(0x20); db(0x29);
+ db(0x00); db(0x08); db(0xb0); db(0xa8); db(0x00); db(0x10); db(0x67); db(0x1a);
+ db(0x21); db(0x40); db(0x00); db(0x10); db(0x2f); db(0x0e); db(0x2c); db(0x68);
+ db(0x00); db(0x14); db(0x22); db(0x68); db(0x00); db(0x08); db(0x70); db(0x00);
+ db(0x08); db(0xc0); db(0x00); db(0x0d); db(0x4e); db(0xae); db(0xfe); db(0xbc);
+ db(0x2c); db(0x5f); db(0x70); db(0x00); db(0x4e); db(0x75); db(0x2c); db(0x78);
+ db(0x00); db(0x04); db(0x74); db(0xff); db(0x30); db(0x3c); db(0xff); db(0x38);
+ db(0x72); db(0x11); db(0x61); db(0x00); db(0x0c); db(0xf4); db(0x4e); db(0x90);
+ db(0x08); db(0x00); db(0x00); db(0x01); db(0x67); db(0x38); db(0x74); db(0x00);
+ db(0x4e); db(0xae); db(0xff); db(0x7c); db(0x41); db(0xee); db(0x01); db(0x5e);
+ db(0x43); db(0xfa); db(0x0d); db(0x1a); db(0x4e); db(0xae); db(0xfe); db(0xec);
+ db(0x4a); db(0x80); db(0x67); db(0x1e); db(0x20); db(0x40); db(0x43); db(0xfa);
+ db(0x00); db(0x22); db(0x24); db(0x68); db(0xff); db(0xe4); db(0x21); db(0x49);
+ db(0xff); db(0xe4); db(0x22); db(0x48); db(0x30); db(0x3c); db(0xff); db(0x38);
+ db(0x72); db(0x65); db(0x61); db(0x00); db(0x0c); db(0xbc); db(0x4e); db(0x90);
+ db(0x74); db(0x01); db(0x4e); db(0xae); db(0xff); db(0x76); db(0x20); db(0x02);
+ db(0x4e); db(0x75); db(0x59); db(0x8f); db(0x48); db(0xe7); db(0xc0); db(0x80);
+ db(0x30); db(0x3c); db(0xff); db(0x38); db(0x72); db(0x66); db(0x61); db(0x00);
+ db(0x0c); db(0xa0); db(0x4e); db(0x90); db(0x4c); db(0xdf); db(0x01); db(0x03);
+ db(0x4e); db(0x75); db(0x2c); db(0x78); db(0x00); db(0x04); db(0x41); db(0xfa);
+ db(0x0d); db(0xc7); db(0x43); db(0xfa); db(0x00); db(0x14); db(0x70); db(0x0f);
+ db(0x22); db(0x3c); db(0x00); db(0x00); db(0x1f); db(0x40); db(0x61); db(0x00);
+ db(0xe6); db(0xd6); db(0x4e); db(0x75); db(0x00); db(0x00); db(0x00); db(0x10);
+ db(0x00); db(0x00); db(0x00); db(0x00); db(0x2c); db(0x78); db(0x00); db(0x04);
+ db(0x70); db(0x00); db(0x43); db(0xfa); db(0x0d); db(0xb0); db(0x4e); db(0xae);
+ db(0xfd); db(0xd8); db(0x72); db(0x02); db(0x30); db(0x3c); db(0xff); db(0x78);
+ db(0x61); db(0x00); db(0x0c); db(0x5e); db(0x24); db(0x48); db(0x72); db(0x01);
+ db(0x4e); db(0x90); db(0x4a); db(0x81); db(0x67); db(0x0c); db(0x26); db(0x41);
+ db(0x4e); db(0xae); db(0xfe); db(0x08); db(0x72); db(0x02); db(0x20); db(0x4b);
+ db(0x4e); db(0x92); db(0x22); db(0x4e); db(0x2c); db(0x78); db(0x00); db(0x04);
+ db(0x4e); db(0xae); db(0xfe); db(0x62); db(0x4e); db(0x75); db(0x4e); db(0x75);
+ db(0xbc); db(0xfc); db(0x00); db(0x00); db(0x67); db(0x06); db(0x4e); db(0xae);
+ db(0xff); db(0x70); db(0x4e); db(0x75); db(0x48); db(0xe7); db(0x3f); db(0x3e);
+ db(0x24); db(0x48); db(0x2c); db(0x78); db(0x00); db(0x04); db(0x20); db(0x3c);
+ db(0x00); db(0x00); db(0x01); db(0x00); db(0x22); db(0x3c); db(0x00); db(0x01);
+ db(0x00); db(0x01); db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x26); db(0x40);
+ db(0x49); db(0xeb); db(0x00); db(0x2c); db(0x4b); db(0xec); db(0x00); db(0x10);
+ db(0x4d); db(0xed); db(0x00); db(0x44); db(0x22); db(0x4d); db(0x41); db(0xea);
+ db(0x00); db(0x10); db(0x70); db(0x10); db(0x22); db(0xd8); db(0x51); db(0xc8);
+ db(0xff); db(0xfc); db(0x20); db(0x4e); db(0x22); db(0x52); db(0x52); db(0x88);
+ db(0x10); db(0xd9); db(0x66); db(0xfc); db(0x20); db(0x08); db(0x56); db(0x80);
+ db(0x02); db(0x00); db(0x00); db(0xfc); db(0x2c); db(0x00); db(0x20); db(0x08);
+ db(0x55); db(0x80); db(0x90); db(0x8e); db(0x1c); db(0x80); db(0x20); db(0x46);
+ db(0x22); db(0x6a); db(0x00); db(0x04); db(0x52); db(0x88); db(0x10); db(0xd9);
+ db(0x66); db(0xfc); db(0x20); db(0x08); db(0x55); db(0x80); db(0x90); db(0x86);
+ db(0x20); db(0x46); db(0x10); db(0x80); db(0x28); db(0xaa); db(0x00); db(0x08);
+ db(0x20); db(0x06); db(0xe4); db(0x88); db(0x29); db(0x40); db(0x00); db(0x04);
+ db(0x41); db(0xea); db(0x00); db(0x10); db(0x20); db(0x0d); db(0xe4); db(0x88);
+ db(0x29); db(0x40); db(0x00); db(0x08); db(0x29); db(0x6a); db(0x00); db(0x0c);
+ db(0x00); db(0x0c); db(0x20); db(0x0c); db(0xe4); db(0x88); db(0x27); db(0x40);
+ db(0x00); db(0x1c); db(0x20); db(0x0e); db(0xe4); db(0x88); db(0x27); db(0x40);
+ db(0x00); db(0x28); db(0x70); db(0x0a); db(0x27); db(0x40); db(0x00); db(0x18);
+ db(0x27); db(0x7c); db(0x00); db(0x00); db(0x0f); db(0xa0); db(0x00); db(0x14);
+ db(0x20); db(0x0b); db(0x4c); db(0xdf); db(0x7c); db(0xfc); db(0x4e); db(0x75);
+ db(0xbc); db(0xfc); db(0x00); db(0x00); db(0x67); db(0x06); db(0x4e); db(0xae);
+ db(0xff); db(0x6a); db(0x4e); db(0x75); db(0x48); db(0xe7); db(0x38); db(0x3e);
+ db(0x24); db(0x48); db(0x2c); db(0x78); db(0x00); db(0x04); db(0x43); db(0xfa);
+ db(0x0c); db(0xac); db(0x4e); db(0xae); db(0xfe); db(0x68); db(0x2a); db(0x40);
+ db(0x20); db(0x6d); db(0x00); db(0x22); db(0x20); db(0x28); db(0x00); db(0x18);
+ db(0xe5); db(0x88); db(0x26); db(0x40); db(0x24); db(0xab); db(0x00); db(0x04);
+ db(0x20); db(0x0a); db(0xe4); db(0x88); db(0x27); db(0x40); db(0x00); db(0x04);
+ db(0x22); db(0x4d); db(0x2c); db(0x78); db(0x00); db(0x04); db(0x4e); db(0xae);
+ db(0xfe); db(0x62); db(0x4c); db(0xdf); db(0x7c); db(0x1c); db(0x4e); db(0x75);
+ db(0x00); db(0x00); db(0x00); db(0x16); db(0x00); db(0x00); db(0x00); db(0x00);
+ db(0x00); db(0x00); db(0x00); db(0x16); db(0x24); db(0x01); db(0x2c); db(0x78);
+ db(0x00); db(0x04); db(0x93); db(0xc9); db(0x4e); db(0xae); db(0xfe); db(0xda);
+ db(0x20); db(0x40); db(0x41); db(0xe8); db(0x00); db(0x5c); db(0xe5); db(0x8a);
+ db(0x22); db(0x42); db(0x22); db(0x51); db(0x4e); db(0xae); db(0xfe); db(0x92);
+ db(0x22); db(0x02); db(0x43); db(0xfa); db(0x00); db(0x0e); db(0x30); db(0x3c);
+ db(0xff); db(0x68); db(0x61); db(0x00); db(0x0b); db(0x04); db(0x4e); db(0x90);
+ db(0x4e); db(0xd0); db(0x70); db(0x30); db(0x60); db(0x0a); db(0x70); db(0x28);
+ db(0x60); db(0x06); db(0x20); db(0x06); db(0x60); db(0x02); db(0x20); db(0x06);
+ db(0x12); db(0xd8); db(0x53); db(0x80); db(0x6e); db(0xfa); db(0x4e); db(0x75);
+ db(0x00); db(0x00); db(0x00); db(0x00); db(0x00); db(0x00); db(0x00); db(0x01);
+ db(0x00); db(0x00); db(0x00); db(0x04); db(0x00); db(0x00); db(0x00); db(0x02);
+ db(0x48); db(0xe7); db(0x00); db(0x22); db(0x2c); db(0x78); db(0x00); db(0x04);
+ db(0x20); db(0x3c); db(0x00); db(0x00); db(0xff); db(0xfc); db(0x61); db(0x00);
+ db(0x0a); db(0xd8); db(0x24); db(0x48); db(0x20); db(0x08); db(0x42); db(0x40);
+ db(0x20); db(0x40); db(0x21); db(0x4e); db(0x3f); db(0xfc); db(0x70); db(0x1a);
  db(0x22); db(0x3c); db(0x00); db(0x01); db(0x00); db(0x01); db(0x4e); db(0xae);
- db(0xff); db(0x3a); db(0x26); db(0x40); db(0x49); db(0xeb); db(0x00); db(0x2c);
- db(0x4b); db(0xec); db(0x00); db(0x10); db(0x4d); db(0xed); db(0x00); db(0x44);
- db(0x22); db(0x4d); db(0x41); db(0xea); db(0x00); db(0x10); db(0x70); db(0x10);
- db(0x22); db(0xd8); db(0x51); db(0xc8); db(0xff); db(0xfc); db(0x20); db(0x4e);
- db(0x22); db(0x52); db(0x52); db(0x88); db(0x10); db(0xd9); db(0x66); db(0xfc);
- db(0x20); db(0x08); db(0x56); db(0x80); db(0x02); db(0x00); db(0x00); db(0xfc);
- db(0x2c); db(0x00); db(0x20); db(0x08); db(0x55); db(0x80); db(0x90); db(0x8e);
- db(0x1c); db(0x80); db(0x20); db(0x46); db(0x22); db(0x6a); db(0x00); db(0x04);
- db(0x52); db(0x88); db(0x10); db(0xd9); db(0x66); db(0xfc); db(0x20); db(0x08);
- db(0x55); db(0x80); db(0x90); db(0x86); db(0x20); db(0x46); db(0x10); db(0x80);
- db(0x28); db(0xaa); db(0x00); db(0x08); db(0x20); db(0x06); db(0xe4); db(0x88);
- db(0x29); db(0x40); db(0x00); db(0x04); db(0x41); db(0xea); db(0x00); db(0x10);
- db(0x20); db(0x0d); db(0xe4); db(0x88); db(0x29); db(0x40); db(0x00); db(0x08);
- db(0x29); db(0x6a); db(0x00); db(0x0c); db(0x00); db(0x0c); db(0x20); db(0x0c);
- db(0xe4); db(0x88); db(0x27); db(0x40); db(0x00); db(0x1c); db(0x20); db(0x0e);
- db(0xe4); db(0x88); db(0x27); db(0x40); db(0x00); db(0x28); db(0x70); db(0x0a);
- db(0x27); db(0x40); db(0x00); db(0x18); db(0x27); db(0x7c); db(0x00); db(0x00);
- db(0x0f); db(0xa0); db(0x00); db(0x14); db(0x20); db(0x0b); db(0x4c); db(0xdf);
- db(0x7c); db(0xfc); db(0x4e); db(0x75); db(0xbc); db(0xfc); db(0x00); db(0x00);
- db(0x67); db(0x06); db(0x4e); db(0xae); db(0xff); db(0x6a); db(0x4e); db(0x75);
- db(0x48); db(0xe7); db(0x38); db(0x3e); db(0x24); db(0x48); db(0x2c); db(0x78);
- db(0x00); db(0x04); db(0x43); db(0xfa); db(0x06); db(0x2d); db(0x4e); db(0xae);
- db(0xfe); db(0x68); db(0x2a); db(0x40); db(0x20); db(0x6d); db(0x00); db(0x22);
- db(0x20); db(0x28); db(0x00); db(0x18); db(0xe5); db(0x88); db(0x26); db(0x40);
- db(0x24); db(0xab); db(0x00); db(0x04); db(0x20); db(0x0a); db(0xe4); db(0x88);
- db(0x27); db(0x40); db(0x00); db(0x04); db(0x22); db(0x4d); db(0x2c); db(0x78);
- db(0x00); db(0x04); db(0x4e); db(0xae); db(0xfe); db(0x62); db(0x4c); db(0xdf);
- db(0x7c); db(0x1c); db(0x4e); db(0x75); db(0x00); db(0x00); db(0x00); db(0x16);
- db(0x00); db(0x00); db(0x00); db(0x00); db(0x00); db(0x00); db(0x00); db(0x16);
- db(0x24); db(0x01); db(0x2c); db(0x78); db(0x00); db(0x04); db(0x93); db(0xc9);
- db(0x4e); db(0xae); db(0xfe); db(0xda); db(0x20); db(0x40); db(0x41); db(0xe8);
- db(0x00); db(0x5c); db(0xe5); db(0x8a); db(0x22); db(0x42); db(0x22); db(0x51);
- db(0x4e); db(0xae); db(0xfe); db(0x92); db(0x22); db(0x02); db(0x43); db(0xfa);
- db(0x00); db(0x0e); db(0x30); db(0x3c); db(0xff); db(0x68); db(0x61); db(0x00);
- db(0x04); db(0x94); db(0x4e); db(0x90); db(0x4e); db(0xd0); db(0x70); db(0x30);
- db(0x60); db(0x0a); db(0x70); db(0x28); db(0x60); db(0x06); db(0x20); db(0x06);
- db(0x60); db(0x02); db(0x20); db(0x06); db(0x12); db(0xd8); db(0x53); db(0x80);
- db(0x6e); db(0xfa); db(0x4e); db(0x75); db(0x00); db(0x00); db(0x00); db(0x00);
- db(0x00); db(0x00); db(0x00); db(0x01); db(0x00); db(0x00); db(0x00); db(0x04);
- db(0x00); db(0x00); db(0x00); db(0x02); db(0x48); db(0xe7); db(0x00); db(0x22);
- db(0x2c); db(0x78); db(0x00); db(0x04); db(0x20); db(0x3c); db(0x00); db(0x00);
- db(0xff); db(0xfc); db(0x61); db(0x00); db(0x04); db(0x68); db(0x24); db(0x48);
- db(0x20); db(0x08); db(0x42); db(0x40); db(0x20); db(0x40); db(0x21); db(0x4e);
- db(0x3f); db(0xfc); db(0x70); db(0x1a); db(0x22); db(0x3c); db(0x00); db(0x01);
- db(0x00); db(0x01); db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x22); db(0x40);
- db(0x41); db(0xfa); db(0x05); db(0xf2); db(0x23); db(0x48); db(0x00); db(0x0a);
- db(0x23); db(0x4a); db(0x00); db(0x0e); db(0x41); db(0xfa); db(0x01); db(0x30);
- db(0x23); db(0x48); db(0x00); db(0x12); db(0x33); db(0x7c); db(0x02); db(0x7a);
- db(0x00); db(0x08); db(0x70); db(0x0d); db(0x4e); db(0xae); db(0xff); db(0x58);
- db(0x4c); db(0xdf); db(0x44); db(0x00); db(0x4e); db(0x75); db(0x48); db(0xe7);
- db(0xc0); db(0xc0); db(0x20); db(0x3c); db(0x00); db(0x00); db(0xf0); db(0x00);
- db(0x61); db(0x00); db(0x04); db(0x1a); db(0x22); db(0x48); db(0x20); db(0x3c);
- db(0x00); db(0x00); db(0x40); db(0x00); db(0x61); db(0x00); db(0x04); db(0x0e);
- db(0x70); db(0x03); db(0x4a); db(0x69); db(0x00); db(0x02); db(0x67); db(0x0e);
+ db(0xff); db(0x3a); db(0x22); db(0x40); db(0x41); db(0xfa); db(0x0c); db(0x71);
+ db(0x23); db(0x48); db(0x00); db(0x0a); db(0x23); db(0x4a); db(0x00); db(0x0e);
+ db(0x41); db(0xfa); db(0x01); db(0x30); db(0x23); db(0x48); db(0x00); db(0x12);
+ db(0x33); db(0x7c); db(0x02); db(0x7a); db(0x00); db(0x08); db(0x70); db(0x0d);
+ db(0x4e); db(0xae); db(0xff); db(0x58); db(0x4c); db(0xdf); db(0x44); db(0x00);
+ db(0x4e); db(0x75); db(0x48); db(0xe7); db(0xc0); db(0xc0); db(0x20); db(0x3c);
+ db(0x00); db(0x00); db(0xf0); db(0x00); db(0x61); db(0x00); db(0x0a); db(0x8a);
+ db(0x22); db(0x48); db(0x20); db(0x3c); db(0x00); db(0x00); db(0x40); db(0x00);
+ db(0x61); db(0x00); db(0x0a); db(0x7e); db(0x70); db(0x03); db(0x4a); db(0x69);
+ db(0x00); db(0x02); db(0x67); db(0x0e); db(0xd0); db(0xfc); db(0x20); db(0x00);
+ db(0xd2); db(0xfc); db(0x00); db(0x08); db(0x51); db(0xc8); db(0xff); db(0xf0);
+ db(0x60); db(0xd4); db(0x48); db(0xe8); db(0x00); db(0xfc); db(0x00); db(0x0c);
+ db(0x48); db(0xe8); db(0x7c); db(0x00); db(0x00); db(0x2c); db(0x21); db(0x6f);
+ db(0x00); db(0x00); db(0x00); db(0x04); db(0x21); db(0x6f); db(0x00); db(0x04);
+ db(0x00); db(0x08); db(0x21); db(0x6f); db(0x00); db(0x08); db(0x00); db(0x24);
+ db(0x21); db(0x6f); db(0x00); db(0x0c); db(0x00); db(0x28); db(0x24); db(0x48);
+ db(0x26); db(0x49); db(0x2c); db(0x78); db(0x00); db(0x04); db(0x42); db(0xaa);
+ db(0x00); db(0x4c); db(0x4a); db(0x13); db(0x67); db(0x0a); db(0x93); db(0xc9);
+ db(0x4e); db(0xae); db(0xfe); db(0xda); db(0x25); db(0x40); db(0x00); db(0x4c);
+ db(0x36); db(0xaf); db(0x00); db(0x10); db(0x2a); db(0x3c); db(0x80); db(0x00);
+ db(0x00); db(0x00); db(0x38); db(0x3c); db(0x27); db(0x10); db(0x4a); db(0x2b);
+ db(0x00); db(0x02); db(0x66); db(0x50); db(0x0c); db(0x2b); db(0x00); db(0xfe);
+ db(0x00); db(0x07); db(0x66); db(0x18); db(0x17); db(0x7c); db(0x00); db(0x04);
+ db(0x00); db(0x07); db(0x20); db(0x4a); db(0x22); db(0x4b); db(0x70); db(0x01);
+ db(0x61); db(0x00); db(0x01); db(0x32); db(0x17); db(0x7c); db(0x00); db(0x03);
+ db(0x00); db(0x07); db(0x60); db(0xda); db(0x4a); db(0xaa); db(0x00); db(0x4c);
+ db(0x66); db(0x1e); db(0x0c); db(0x85); db(0x80); db(0x00); db(0x00); db(0x00);
+ db(0x66); db(0xcc); db(0x53); db(0x44); db(0x6a); db(0xc8); db(0x93); db(0xc9);
+ db(0x4e); db(0xae); db(0xfe); db(0xda); db(0x22); db(0x40); db(0x70); db(0x88);
+ db(0x4e); db(0xae); db(0xfe); db(0xd4); db(0x2a); db(0x00); db(0x60); db(0xb6);
+ db(0x20); db(0x3c); db(0x00); db(0x00); db(0x01); db(0x00); db(0x4e); db(0xae);
+ db(0xfe); db(0xc2); db(0x60); db(0xaa); db(0x0c); db(0x85); db(0x80); db(0x00);
+ db(0x00); db(0x00); db(0x67); db(0x0e); db(0x93); db(0xc9); db(0x4e); db(0xae);
+ db(0xfe); db(0xda); db(0x22); db(0x40); db(0x20); db(0x05); db(0x4e); db(0xae);
+ db(0xfe); db(0xd4); db(0x17); db(0x7c); db(0x00); db(0x01); db(0x00); db(0x02);
+ db(0x20); db(0x4a); db(0x22); db(0x4b); db(0x4c); db(0xe8); db(0x00); db(0xff);
+ db(0x00); db(0x04); db(0x4c); db(0xe8); db(0x7c); db(0x00); db(0x00); db(0x2c);
+ db(0x2f); db(0x28); db(0x00); db(0x24); db(0x2f); db(0x28); db(0x00); db(0x28);
+ db(0x42); db(0xa8); db(0x00); db(0x4c); db(0x42); db(0x69); db(0x00); db(0x02);
+ db(0x22); db(0x5f); db(0x20); db(0x5f); db(0x4f); db(0xef); db(0x00); db(0x12);
+ db(0x4e); db(0x75); db(0x48); db(0xe7); db(0x30); db(0x30); db(0x76); db(0x00);
+ db(0x24); db(0x49); db(0x4a); db(0x2a); db(0x00); db(0x01); db(0x67); db(0x4c);
+ db(0x76); db(0x01); db(0x20); db(0x0a); db(0x42); db(0x40); db(0x20); db(0x40);
+ db(0x72); db(0x04); db(0x22); db(0x48); db(0x2c); db(0x68); db(0x3f); db(0xfc);
+ db(0xd1); db(0xfc); db(0x00); db(0x00); db(0x40); db(0x00); db(0xd3); db(0xfc);
+ db(0x00); db(0x00); db(0xf0); db(0x00); db(0x4a); db(0x29); db(0x00); db(0x03);
+ db(0x67); db(0x1e); db(0x0c); db(0x29); db(0x00); db(0xff); db(0x00); db(0x07);
+ db(0x66); db(0x16); db(0x70); db(0x00); db(0x61); db(0x76); db(0x67); db(0x08);
+ db(0x13); db(0x7c); db(0x00); db(0xfd); db(0x00); db(0x07); db(0x60); db(0xca);
+ db(0x13); db(0x7c); db(0x00); db(0x01); db(0x00); db(0x07); db(0x60); db(0xc2);
  db(0xd0); db(0xfc); db(0x20); db(0x00); db(0xd2); db(0xfc); db(0x00); db(0x08);
- db(0x51); db(0xc8); db(0xff); db(0xf0); db(0x60); db(0xd4); db(0x48); db(0xe8);
- db(0x00); db(0xfc); db(0x00); db(0x0c); db(0x48); db(0xe8); db(0x7c); db(0x00);
- db(0x00); db(0x2c); db(0x21); db(0x6f); db(0x00); db(0x00); db(0x00); db(0x04);
- db(0x21); db(0x6f); db(0x00); db(0x04); db(0x00); db(0x08); db(0x21); db(0x6f);
- db(0x00); db(0x08); db(0x00); db(0x24); db(0x21); db(0x6f); db(0x00); db(0x0c);
- db(0x00); db(0x28); db(0x24); db(0x48); db(0x26); db(0x49); db(0x2c); db(0x78);
- db(0x00); db(0x04); db(0x42); db(0xaa); db(0x00); db(0x4c); db(0x4a); db(0x13);
- db(0x67); db(0x0a); db(0x93); db(0xc9); db(0x4e); db(0xae); db(0xfe); db(0xda);
- db(0x25); db(0x40); db(0x00); db(0x4c); db(0x36); db(0xaf); db(0x00); db(0x10);
- db(0x2a); db(0x3c); db(0x80); db(0x00); db(0x00); db(0x00); db(0x38); db(0x3c);
- db(0x27); db(0x10); db(0x4a); db(0x2b); db(0x00); db(0x02); db(0x66); db(0x50);
- db(0x0c); db(0x2b); db(0x00); db(0xfe); db(0x00); db(0x07); db(0x66); db(0x18);
- db(0x17); db(0x7c); db(0x00); db(0x04); db(0x00); db(0x07); db(0x20); db(0x4a);
- db(0x22); db(0x4b); db(0x70); db(0x01); db(0x61); db(0x00); db(0x01); db(0x32);
- db(0x17); db(0x7c); db(0x00); db(0x03); db(0x00); db(0x07); db(0x60); db(0xda);
- db(0x4a); db(0xaa); db(0x00); db(0x4c); db(0x66); db(0x1e); db(0x0c); db(0x85);
- db(0x80); db(0x00); db(0x00); db(0x00); db(0x66); db(0xcc); db(0x53); db(0x44);
- db(0x6a); db(0xc8); db(0x93); db(0xc9); db(0x4e); db(0xae); db(0xfe); db(0xda);
- db(0x22); db(0x40); db(0x70); db(0x88); db(0x4e); db(0xae); db(0xfe); db(0xd4);
- db(0x2a); db(0x00); db(0x60); db(0xb6); db(0x20); db(0x3c); db(0x00); db(0x00);
- db(0x01); db(0x00); db(0x4e); db(0xae); db(0xfe); db(0xc2); db(0x60); db(0xaa);
- db(0x0c); db(0x85); db(0x80); db(0x00); db(0x00); db(0x00); db(0x67); db(0x0e);
- db(0x93); db(0xc9); db(0x4e); db(0xae); db(0xfe); db(0xda); db(0x22); db(0x40);
- db(0x20); db(0x05); db(0x4e); db(0xae); db(0xfe); db(0xd4); db(0x17); db(0x7c);
- db(0x00); db(0x01); db(0x00); db(0x02); db(0x20); db(0x4a); db(0x22); db(0x4b);
- db(0x4c); db(0xe8); db(0x00); db(0xff); db(0x00); db(0x04); db(0x4c); db(0xe8);
- db(0x7c); db(0x00); db(0x00); db(0x2c); db(0x2f); db(0x28); db(0x00); db(0x24);
- db(0x2f); db(0x28); db(0x00); db(0x28); db(0x42); db(0xa8); db(0x00); db(0x4c);
- db(0x42); db(0x69); db(0x00); db(0x02); db(0x22); db(0x5f); db(0x20); db(0x5f);
- db(0x4f); db(0xef); db(0x00); db(0x12); db(0x4e); db(0x75); db(0x48); db(0xe7);
- db(0x30); db(0x30); db(0x76); db(0x00); db(0x24); db(0x49); db(0x4a); db(0x2a);
- db(0x00); db(0x01); db(0x67); db(0x4c); db(0x76); db(0x01); db(0x20); db(0x0a);
- db(0x42); db(0x40); db(0x20); db(0x40); db(0x72); db(0x04); db(0x22); db(0x48);
- db(0x2c); db(0x68); db(0x3f); db(0xfc); db(0xd1); db(0xfc); db(0x00); db(0x00);
- db(0x40); db(0x00); db(0xd3); db(0xfc); db(0x00); db(0x00); db(0xf0); db(0x00);
- db(0x4a); db(0x29); db(0x00); db(0x03); db(0x67); db(0x1e); db(0x0c); db(0x29);
- db(0x00); db(0xff); db(0x00); db(0x07); db(0x66); db(0x16); db(0x70); db(0x00);
- db(0x61); db(0x76); db(0x67); db(0x08); db(0x13); db(0x7c); db(0x00); db(0xfd);
- db(0x00); db(0x07); db(0x60); db(0xca); db(0x13); db(0x7c); db(0x00); db(0x01);
- db(0x00); db(0x07); db(0x60); db(0xc2); db(0xd0); db(0xfc); db(0x20); db(0x00);
- db(0xd2); db(0xfc); db(0x00); db(0x08); db(0x51); db(0xc9); db(0xff); db(0xd2);
- db(0x4a); db(0x2a); db(0x00); db(0x02); db(0x67); db(0x4a); db(0x76); db(0x01);
- db(0x20); db(0x0a); db(0x42); db(0x40); db(0x24); db(0x40); db(0x26); db(0x40);
- db(0x2c); db(0x6a); db(0x3f); db(0xfc); db(0xd5); db(0xfc); db(0x00); db(0x00);
- db(0x40); db(0x00); db(0xd7); db(0xfc); db(0x00); db(0x00); db(0xf0); db(0x00);
- db(0x74); db(0x03); db(0x20); db(0x2a); db(0x00); db(0x4c); db(0x67); db(0x1c);
- db(0x4a); db(0x2b); db(0x00); db(0x03); db(0x67); db(0x16); db(0x4a); db(0x2b);
- db(0x00); db(0x02); db(0x6a); db(0x10); db(0x42); db(0xaa); db(0x00); db(0x4c);
- db(0x22); db(0x40); db(0x20); db(0x3c); db(0x00); db(0x00); db(0x01); db(0x00);
- db(0x4e); db(0xae); db(0xfe); db(0xbc); db(0xd4); db(0xfc); db(0x20); db(0x00);
- db(0xd6); db(0xfc); db(0x00); db(0x08); db(0x51); db(0xca); db(0xff); db(0xd4);
- db(0x20); db(0x03); db(0x4c); db(0xdf); db(0x0c); db(0x0c); db(0x4e); db(0x75);
- db(0x48); db(0xe7); db(0x7c); db(0x7c); db(0x3a); db(0x00); db(0x49); db(0xe8);
- db(0x00); db(0x54); db(0x4b); db(0xe9); db(0x00); db(0x04); db(0x38); db(0x15);
- db(0xd8); db(0x44); db(0x47); db(0xfa); db(0x00); db(0x54); db(0x32); db(0x33);
- db(0x40); db(0x00); db(0x66); db(0x36); db(0x4a); db(0x45); db(0x67); db(0x14);
- db(0x32); db(0x3c); db(0x00); db(0x9c); db(0x0c); db(0x44); db(0x00); db(0x24);
- db(0x67); db(0x28); db(0x32); db(0x3c); db(0x00); db(0xb6); db(0x0c); db(0x44);
- db(0x00); db(0x26); db(0x67); db(0x1e); db(0x20); db(0x3c); db(0x00); db(0x00);
- db(0xff); db(0xf4); db(0x61); db(0x00); db(0x02); db(0x20); db(0x20); db(0x10);
- db(0x67); db(0x10); db(0x22); db(0x40); db(0x20); db(0x3c); db(0x00); db(0x00);
- db(0x01); db(0x00); db(0x4e); db(0xae); db(0xfe); db(0xbc); db(0x70); db(0x01);
- db(0x60); db(0x10); db(0xd6); db(0xc1); db(0x4c); db(0xd4); db(0x07); db(0x00);
- db(0x4c); db(0xd4); db(0x00); db(0x07); db(0x4e); db(0x93); db(0x28); db(0x80);
- db(0x70); db(0x00); db(0x4c); db(0xdf); db(0x3e); db(0x3e); db(0x4e); db(0x75);
- db(0x00); db(0xca); db(0x00); db(0x2c); db(0x00); db(0x30); db(0x00); db(0x34);
- db(0x00); db(0x38); db(0x00); db(0x3c); db(0x00); db(0x42); db(0x00); db(0x48);
- db(0x00); db(0x4e); db(0x00); db(0x56); db(0x00); db(0x48); db(0x00); db(0x4e);
- db(0x00); db(0x56); db(0x00); db(0x5e); db(0x00); db(0x5e); db(0x00); db(0x70);
- db(0x00); db(0x78); db(0x00); db(0x80); db(0x00); db(0x00); db(0x00); db(0x00);
- db(0x00); db(0xc6); db(0x00); db(0x88); db(0x20); db(0x81); db(0x4e); db(0x75);
- db(0x30); db(0x81); db(0x4e); db(0x75); db(0x10); db(0x81); db(0x4e); db(0x75);
- db(0x20); db(0x10); db(0x4e); db(0x75); db(0x70); db(0x00); db(0x30); db(0x10);
- db(0x4e); db(0x75); db(0x70); db(0x00); db(0x10); db(0x10); db(0x4e); db(0x75);
- db(0x20); db(0x02); db(0x4e); db(0xee); db(0xfd); db(0x90); db(0x20); db(0x02);
- db(0xd0); db(0x80); db(0x4e); db(0xee); db(0xfd); db(0x90); db(0x20); db(0x02);
- db(0xe5); db(0x88); db(0x4e); db(0xee); db(0xfd); db(0x90); db(0x70); db(0x00);
- db(0x53); db(0x42); db(0x67); db(0x06); db(0x52); db(0x40); db(0x12); db(0xd8);
- db(0x66); db(0xf4); db(0x42); db(0x29); db(0xff); db(0xff); db(0x4e); db(0x75);
- db(0x20); db(0xc1); db(0x53); db(0x82); db(0x66); db(0xfa); db(0x4e); db(0x75);
- db(0x30); db(0xc1); db(0x53); db(0x82); db(0x66); db(0xfa); db(0x4e); db(0x75);
- db(0x10); db(0xc1); db(0x53); db(0x82); db(0x66); db(0xfa); db(0x4e); db(0x75);
- db(0x70); db(0x00); db(0x10); db(0x18); db(0x53); db(0x40); db(0x6b); db(0x08);
- db(0x53); db(0x42); db(0x6b); db(0x04); db(0x12); db(0xd8); db(0x60); db(0xf4);
- db(0x42); db(0x11); db(0x4e); db(0x75); db(0x48); db(0xe7); db(0x3f); db(0x3e);
- db(0x2c); db(0x48); db(0xd0); db(0xc1); db(0x48); db(0x7a); db(0x00); db(0x0a);
- db(0x2f); db(0x08); db(0x4c); db(0xd2); db(0x3f); db(0xff); db(0x4e); db(0x75);
- db(0x4c); db(0xdf); db(0x7c); db(0xfc); db(0x4e); db(0x75); db(0x48); db(0xe7);
- db(0x3f); db(0x3e); db(0x48); db(0x7a); db(0xff); db(0xf4); db(0x2f); db(0x08);
- db(0x4c); db(0xd1); db(0x7f); db(0xff); db(0x4e); db(0x75); db(0x20); db(0x05);
- db(0x4e); db(0x75); db(0x48); db(0xe7); db(0xff); db(0xfe); db(0x28); db(0x48);
- db(0x2a); db(0x4c); db(0x2e); db(0x01); db(0x7a); db(0x00); db(0x38); db(0x1c);
- db(0x7c); db(0x00); db(0x3c); db(0x1c); db(0xd8); db(0x44); db(0x47); db(0xfa);
- db(0xff); db(0x20); db(0xd6); db(0xf3); db(0x40); db(0x00); db(0x4c); db(0xd4);
- db(0x07); db(0x00); db(0x4c); db(0xd4); db(0x00); db(0x07); db(0x4e); db(0x93);
- db(0x28); db(0x80); db(0x2a); db(0x00); db(0x4a); db(0x46); db(0x67); db(0x14);
- db(0x36); db(0x06); db(0x02); db(0x46); db(0x00); db(0x0f); db(0xe0); db(0x4b);
- db(0xc6); db(0xfc); db(0x00); db(0x14); db(0xe5); db(0x4e); db(0xd6); db(0x46);
- db(0x2b); db(0x80); db(0x30); db(0x04); db(0xd8); db(0xfc); db(0x00); db(0x10);
- db(0x53); db(0x87); db(0x66); db(0xc2); db(0x4c); db(0xdf); db(0x7f); db(0xff);
- db(0x4e); db(0x75); db(0x2a); db(0x48); db(0x7e); db(0x14); db(0x2c); db(0x78);
- db(0x00); db(0x04); db(0x4e); db(0xae); db(0xff); db(0x7c); db(0x30); db(0x3c);
- db(0xff); db(0x38); db(0x61); db(0x00); db(0x00); db(0xc8); db(0x24); db(0x0d);
- db(0x72); db(0x13); db(0x4e); db(0x90); db(0x4a); db(0x80); db(0x67); db(0x00);
- db(0x00); db(0x98); db(0x26); db(0x40); db(0x28); db(0x5b); db(0x20); db(0x4c);
- db(0x22); db(0x4d); db(0x30); db(0x3c); db(0x3f); db(0xff); db(0x22); db(0xd8);
- db(0x51); db(0xc8); db(0xff); db(0xfc); db(0x22); db(0x0d); db(0x92); db(0x8c);
- db(0x20); db(0x4b); db(0x70); db(0x00); db(0x30); db(0x18); db(0x67); db(0x0e);
- db(0x43); db(0xf4); db(0x08); db(0x00); db(0xd3); db(0x91); db(0x43); db(0xf5);
- db(0x08); db(0x00); db(0xd3); db(0x91); db(0x60); db(0xec); db(0x70); db(0x00);
- db(0x20); db(0x18); db(0x67); db(0x06); db(0x22); db(0x40); db(0xd3); db(0x91);
- db(0x60); db(0xf4); db(0x70); db(0x00); db(0x61); db(0x00); db(0x00); db(0x7e);
- db(0x43); db(0xfa); db(0x00); db(0x7a); db(0x93); db(0xc8); db(0xd3); db(0xcd);
- db(0x32); db(0xfc); db(0x41); db(0xf9); db(0x22); db(0xcc); db(0x32); db(0xfc);
- db(0x02); db(0x80); db(0x22); db(0xfc); db(0x00); db(0x00); db(0xff); db(0xff);
- db(0x22); db(0xbc); db(0xd1); db(0xc0); db(0x4e); db(0x75); db(0x41); db(0xfa);
- db(0x00); db(0x40); db(0x70); db(0x00); db(0x30); db(0x18); db(0x67); db(0x14);
- db(0x06); db(0x40); db(0x00); db(0x0c); db(0x43); db(0xf4); db(0x08); db(0x00);
- db(0x32); db(0xfc); db(0x4e); db(0xf9); db(0x45); db(0xf5); db(0x08); db(0x00);
- db(0x22); db(0x8a); db(0x60); db(0xe6); db(0x0c); db(0x6e); db(0x00); db(0x24);
- db(0x00); db(0x14); db(0x65); db(0x04); db(0x4e); db(0xae); db(0xfd); db(0x84);
- db(0x30); db(0x3c); db(0xff); db(0x38); db(0x61); db(0x00); db(0x00); db(0x2e);
- db(0x24); db(0x0d); db(0x72); db(0x14); db(0x4e); db(0x90); db(0x7e); db(0x00);
- db(0x4e); db(0xae); db(0xff); db(0x76); db(0x20); db(0x07); db(0x4e); db(0x75);
- db(0x0e); db(0xc4); db(0x13); db(0xb6); db(0x05); db(0x8c); db(0x02); db(0xd0);
- db(0x03); db(0x56); db(0x00); db(0x00); db(0x41); db(0xfa); db(0xde); db(0x6e);
- db(0x02); db(0x80); db(0x00); db(0x00); db(0xff); db(0xff); db(0xd1); db(0xc0);
- db(0x4e); db(0x75); db(0x00); db(0x00); db(0x41); db(0xfa); db(0xde); db(0x5e);
- db(0x02); db(0x80); db(0x00); db(0x00); db(0xff); db(0xff); db(0xd1); db(0xc0);
- db(0x4e); db(0x75); db(0x4e); db(0x71); db(0x4e); db(0x71); db(0x69); db(0x6e);
- db(0x70); db(0x75); db(0x74); db(0x2e); db(0x64); db(0x65); db(0x76); db(0x69);
- db(0x63); db(0x65); db(0x00); db(0x74); db(0x69); db(0x6d); db(0x65); db(0x72);
- db(0x2e); db(0x64); db(0x65); db(0x76); db(0x69); db(0x63); db(0x65); db(0x00);
- db(0x63); db(0x6f); db(0x6e); db(0x73); db(0x6f); db(0x6c); db(0x65); db(0x2e);
- db(0x64); db(0x65); db(0x76); db(0x69); db(0x63); db(0x65); db(0x00); db(0x44);
- db(0x45); db(0x56); db(0x53); db(0x00); db(0x44); db(0x45); db(0x56); db(0x53);
- db(0x3a); db(0x00); db(0x44); db(0x45); db(0x56); db(0x53); db(0x3a); db(0x63);
- db(0x6c); db(0x69); db(0x70); db(0x62); db(0x6f); db(0x61); db(0x72); db(0x64);
- db(0x2e); db(0x64); db(0x65); db(0x76); db(0x69); db(0x63); db(0x65); db(0x00);
- db(0x52); db(0x41); db(0x4d); db(0x3a); db(0x00); db(0x4e); db(0x49); db(0x4c);
- db(0x3a); db(0x00); db(0x63); db(0x6c); db(0x69); db(0x70); db(0x62); db(0x6f);
+ db(0x51); db(0xc9); db(0xff); db(0xd2); db(0x4a); db(0x2a); db(0x00); db(0x02);
+ db(0x67); db(0x4a); db(0x76); db(0x01); db(0x20); db(0x0a); db(0x42); db(0x40);
+ db(0x24); db(0x40); db(0x26); db(0x40); db(0x2c); db(0x6a); db(0x3f); db(0xfc);
+ db(0xd5); db(0xfc); db(0x00); db(0x00); db(0x40); db(0x00); db(0xd7); db(0xfc);
+ db(0x00); db(0x00); db(0xf0); db(0x00); db(0x74); db(0x03); db(0x20); db(0x2a);
+ db(0x00); db(0x4c); db(0x67); db(0x1c); db(0x4a); db(0x2b); db(0x00); db(0x03);
+ db(0x67); db(0x16); db(0x4a); db(0x2b); db(0x00); db(0x02); db(0x6a); db(0x10);
+ db(0x42); db(0xaa); db(0x00); db(0x4c); db(0x22); db(0x40); db(0x20); db(0x3c);
+ db(0x00); db(0x00); db(0x01); db(0x00); db(0x4e); db(0xae); db(0xfe); db(0xbc);
+ db(0xd4); db(0xfc); db(0x20); db(0x00); db(0xd6); db(0xfc); db(0x00); db(0x08);
+ db(0x51); db(0xca); db(0xff); db(0xd4); db(0x20); db(0x03); db(0x4c); db(0xdf);
+ db(0x0c); db(0x0c); db(0x4e); db(0x75); db(0x48); db(0xe7); db(0x7c); db(0x7c);
+ db(0x3a); db(0x00); db(0x49); db(0xe8); db(0x00); db(0x54); db(0x4b); db(0xe9);
+ db(0x00); db(0x04); db(0x38); db(0x15); db(0xd8); db(0x44); db(0x47); db(0xfa);
+ db(0x00); db(0x54); db(0x32); db(0x33); db(0x40); db(0x00); db(0x66); db(0x36);
+ db(0x4a); db(0x45); db(0x67); db(0x14); db(0x32); db(0x3c); db(0x00); db(0x9c);
+ db(0x0c); db(0x44); db(0x00); db(0x24); db(0x67); db(0x28); db(0x32); db(0x3c);
+ db(0x00); db(0xb6); db(0x0c); db(0x44); db(0x00); db(0x26); db(0x67); db(0x1e);
+ db(0x20); db(0x3c); db(0x00); db(0x00); db(0xff); db(0xf4); db(0x61); db(0x00);
+ db(0x08); db(0x90); db(0x20); db(0x10); db(0x67); db(0x10); db(0x22); db(0x40);
+ db(0x20); db(0x3c); db(0x00); db(0x00); db(0x01); db(0x00); db(0x4e); db(0xae);
+ db(0xfe); db(0xbc); db(0x70); db(0x01); db(0x60); db(0x10); db(0xd6); db(0xc1);
+ db(0x4c); db(0xd4); db(0x07); db(0x00); db(0x4c); db(0xd4); db(0x00); db(0x07);
+ db(0x4e); db(0x93); db(0x28); db(0x80); db(0x70); db(0x00); db(0x4c); db(0xdf);
+ db(0x3e); db(0x3e); db(0x4e); db(0x75); db(0x00); db(0xca); db(0x00); db(0x2c);
+ db(0x00); db(0x30); db(0x00); db(0x34); db(0x00); db(0x38); db(0x00); db(0x3c);
+ db(0x00); db(0x42); db(0x00); db(0x48); db(0x00); db(0x4e); db(0x00); db(0x56);
+ db(0x00); db(0x48); db(0x00); db(0x4e); db(0x00); db(0x56); db(0x00); db(0x5e);
+ db(0x00); db(0x5e); db(0x00); db(0x70); db(0x00); db(0x78); db(0x00); db(0x80);
+ db(0x00); db(0x00); db(0x00); db(0x00); db(0x00); db(0xc6); db(0x00); db(0x88);
+ db(0x20); db(0x81); db(0x4e); db(0x75); db(0x30); db(0x81); db(0x4e); db(0x75);
+ db(0x10); db(0x81); db(0x4e); db(0x75); db(0x20); db(0x10); db(0x4e); db(0x75);
+ db(0x70); db(0x00); db(0x30); db(0x10); db(0x4e); db(0x75); db(0x70); db(0x00);
+ db(0x10); db(0x10); db(0x4e); db(0x75); db(0x20); db(0x02); db(0x4e); db(0xee);
+ db(0xfd); db(0x90); db(0x20); db(0x02); db(0xd0); db(0x80); db(0x4e); db(0xee);
+ db(0xfd); db(0x90); db(0x20); db(0x02); db(0xe5); db(0x88); db(0x4e); db(0xee);
+ db(0xfd); db(0x90); db(0x70); db(0x00); db(0x53); db(0x42); db(0x67); db(0x06);
+ db(0x52); db(0x40); db(0x12); db(0xd8); db(0x66); db(0xf4); db(0x42); db(0x29);
+ db(0xff); db(0xff); db(0x4e); db(0x75); db(0x20); db(0xc1); db(0x53); db(0x82);
+ db(0x66); db(0xfa); db(0x4e); db(0x75); db(0x30); db(0xc1); db(0x53); db(0x82);
+ db(0x66); db(0xfa); db(0x4e); db(0x75); db(0x10); db(0xc1); db(0x53); db(0x82);
+ db(0x66); db(0xfa); db(0x4e); db(0x75); db(0x70); db(0x00); db(0x10); db(0x18);
+ db(0x53); db(0x40); db(0x6b); db(0x08); db(0x53); db(0x42); db(0x6b); db(0x04);
+ db(0x12); db(0xd8); db(0x60); db(0xf4); db(0x42); db(0x11); db(0x4e); db(0x75);
+ db(0x48); db(0xe7); db(0x3f); db(0x3e); db(0x2c); db(0x48); db(0xd0); db(0xc1);
+ db(0x48); db(0x7a); db(0x00); db(0x0a); db(0x2f); db(0x08); db(0x4c); db(0xd2);
+ db(0x3f); db(0xff); db(0x4e); db(0x75); db(0x4c); db(0xdf); db(0x7c); db(0xfc);
+ db(0x4e); db(0x75); db(0x48); db(0xe7); db(0x3f); db(0x3e); db(0x48); db(0x7a);
+ db(0xff); db(0xf4); db(0x2f); db(0x08); db(0x4c); db(0xd1); db(0x7f); db(0xff);
+ db(0x4e); db(0x75); db(0x20); db(0x05); db(0x4e); db(0x75); db(0x48); db(0xe7);
+ db(0xff); db(0xfe); db(0x28); db(0x48); db(0x2a); db(0x4c); db(0x2e); db(0x01);
+ db(0x7a); db(0x00); db(0x38); db(0x1c); db(0x7c); db(0x00); db(0x3c); db(0x1c);
+ db(0xd8); db(0x44); db(0x47); db(0xfa); db(0xff); db(0x20); db(0xd6); db(0xf3);
+ db(0x40); db(0x00); db(0x4c); db(0xd4); db(0x07); db(0x00); db(0x4c); db(0xd4);
+ db(0x00); db(0x07); db(0x4e); db(0x93); db(0x28); db(0x80); db(0x2a); db(0x00);
+ db(0x4a); db(0x46); db(0x67); db(0x14); db(0x36); db(0x06); db(0x02); db(0x46);
+ db(0x00); db(0x0f); db(0xe0); db(0x4b); db(0xc6); db(0xfc); db(0x00); db(0x14);
+ db(0xe5); db(0x4e); db(0xd6); db(0x46); db(0x2b); db(0x80); db(0x30); db(0x04);
+ db(0xd8); db(0xfc); db(0x00); db(0x10); db(0x53); db(0x87); db(0x66); db(0xc2);
+ db(0x4c); db(0xdf); db(0x7f); db(0xff); db(0x4e); db(0x75); db(0x2a); db(0x48);
+ db(0x7e); db(0x14); db(0x2c); db(0x78); db(0x00); db(0x04); db(0x4e); db(0xae);
+ db(0xff); db(0x7c); db(0x30); db(0x3c); db(0xff); db(0x38); db(0x61); db(0x00);
+ db(0x07); db(0x38); db(0x24); db(0x0d); db(0x72); db(0x13); db(0x4e); db(0x90);
+ db(0x4a); db(0x80); db(0x67); db(0x00); db(0x00); db(0x98); db(0x26); db(0x40);
+ db(0x28); db(0x5b); db(0x20); db(0x4c); db(0x22); db(0x4d); db(0x30); db(0x3c);
+ db(0x3f); db(0xff); db(0x22); db(0xd8); db(0x51); db(0xc8); db(0xff); db(0xfc);
+ db(0x22); db(0x0d); db(0x92); db(0x8c); db(0x20); db(0x4b); db(0x70); db(0x00);
+ db(0x30); db(0x18); db(0x67); db(0x0e); db(0x43); db(0xf4); db(0x08); db(0x00);
+ db(0xd3); db(0x91); db(0x43); db(0xf5); db(0x08); db(0x00); db(0xd3); db(0x91);
+ db(0x60); db(0xec); db(0x70); db(0x00); db(0x20); db(0x18); db(0x67); db(0x06);
+ db(0x22); db(0x40); db(0xd3); db(0x91); db(0x60); db(0xf4); db(0x70); db(0x00);
+ db(0x61); db(0x00); db(0x06); db(0xee); db(0x43); db(0xfa); db(0x06); db(0xea);
+ db(0x93); db(0xc8); db(0xd3); db(0xcd); db(0x32); db(0xfc); db(0x41); db(0xf9);
+ db(0x22); db(0xcc); db(0x32); db(0xfc); db(0x02); db(0x80); db(0x22); db(0xfc);
+ db(0x00); db(0x00); db(0xff); db(0xff); db(0x22); db(0xbc); db(0xd1); db(0xc0);
+ db(0x4e); db(0x75); db(0x41); db(0xfa); db(0x00); db(0x40); db(0x70); db(0x00);
+ db(0x30); db(0x18); db(0x67); db(0x14); db(0x06); db(0x40); db(0x00); db(0x0c);
+ db(0x43); db(0xf4); db(0x08); db(0x00); db(0x32); db(0xfc); db(0x4e); db(0xf9);
+ db(0x45); db(0xf5); db(0x08); db(0x00); db(0x22); db(0x8a); db(0x60); db(0xe6);
+ db(0x0c); db(0x6e); db(0x00); db(0x24); db(0x00); db(0x14); db(0x65); db(0x04);
+ db(0x4e); db(0xae); db(0xfd); db(0x84); db(0x30); db(0x3c); db(0xff); db(0x38);
+ db(0x61); db(0x00); db(0x06); db(0x9e); db(0x24); db(0x0d); db(0x72); db(0x14);
+ db(0x4e); db(0x90); db(0x7e); db(0x00); db(0x4e); db(0xae); db(0xff); db(0x76);
+ db(0x20); db(0x07); db(0x4e); db(0x75); db(0x0e); db(0xc8); db(0x13); db(0xba);
+ db(0x05); db(0x90); db(0x02); db(0xd4); db(0x03); db(0x5a); db(0x00); db(0x00);
+ db(0x2c); db(0x78); db(0x00); db(0x04); db(0x70); db(0x30); db(0x72); db(0x01);
+ db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x4a); db(0x80); db(0x67); db(0x6c);
+ db(0x26); db(0x40); db(0x41); db(0xfa); db(0x00); db(0x6a); db(0x22); db(0x4b);
+ db(0x70); db(0x2f); db(0x12); db(0xd8); db(0x51); db(0xc8); db(0xff); db(0xfc);
+ db(0x41); db(0xfa); db(0x00); db(0x94); db(0x27); db(0x48); db(0x00); db(0x12);
+ db(0x41); db(0xfa); db(0x00); db(0x84); db(0x27); db(0x48); db(0x00); db(0x1e);
+ db(0x4e); db(0xae); db(0xff); db(0x7c); db(0x41); db(0xee); db(0x01); db(0x5e);
+ db(0x43); db(0xfa); db(0x06); db(0x72); db(0x4e); db(0xae); db(0xfe); db(0xec);
+ db(0x4a); db(0x80); db(0x67); db(0x10); db(0x22); db(0x40); db(0x20); db(0x0b);
+ db(0x30); db(0x7c); db(0xff); db(0xe2); db(0x4e); db(0xae); db(0xfe); db(0x5c);
+ db(0x27); db(0x40); db(0x00); db(0x28); db(0x41); db(0xee); db(0x01); db(0x7a);
+ db(0x43); db(0xfa); db(0x06); db(0x61); db(0x4e); db(0xae); db(0xfe); db(0xec);
+ db(0x4a); db(0x80); db(0x67); db(0x14); db(0x22); db(0x40); db(0x41); db(0xeb);
+ db(0x00); db(0x1c); db(0x20); db(0x08); db(0x30); db(0x7c); db(0xff); db(0xe2);
+ db(0x4e); db(0xae); db(0xfe); db(0x5c); db(0x27); db(0x40); db(0x00); db(0x2c);
+ db(0x4e); db(0xae); db(0xff); db(0x76); db(0x4e); db(0x75); db(0x0c); db(0x69);
+ db(0x00); db(0x0a); db(0x00); db(0x1c); db(0x67); db(0x08); db(0x0c); db(0x69);
+ db(0x00); db(0x0c); db(0x00); db(0x1c); db(0x66); db(0x06); db(0x4e); db(0xb9);
+ db(0x00); db(0x00); db(0x00); db(0x00); db(0x2f); db(0x3a); db(0x00); db(0x10);
+ db(0x4e); db(0x75); db(0x4e); db(0xb9); db(0x00); db(0x00); db(0x00); db(0x00);
+ db(0x2f); db(0x3a); db(0x00); db(0x08); db(0x4e); db(0x75); db(0x00); db(0x00);
+ db(0x00); db(0x00); db(0x00); db(0x00); db(0x00); db(0x00); db(0x48); db(0xe7);
+ db(0xff); db(0xfe); db(0x24); db(0x48); db(0x60); db(0x08); db(0x48); db(0xe7);
+ db(0xff); db(0xfe); db(0x24); db(0x69); db(0x00); db(0x28); db(0x2c); db(0x78);
+ db(0x00); db(0x04); db(0x51); db(0x8f); db(0x28); db(0x4f); db(0x2f); db(0x0c);
+ db(0x2f); db(0x0a); db(0x61); db(0x00); db(0x03); db(0xdc); db(0x50); db(0x8f);
+ db(0x4a); db(0x80); db(0x67); db(0x1a); db(0x24); db(0x00); db(0x30); db(0x3c);
+ db(0xff); db(0x38); db(0x61); db(0x00); db(0x05); db(0xa4); db(0x72); db(0x15);
+ db(0x22); db(0x42); db(0x20); db(0x14); db(0x4e); db(0x90); db(0x22); db(0x42);
+ db(0x20); db(0x14); db(0x4e); db(0xae); db(0xff); db(0x2e); db(0x50); db(0x8f);
+ db(0x4c); db(0xdf); db(0x7f); db(0xff); db(0x4e); db(0x75); db(0x22); db(0x2f);
+ db(0x00); db(0x08); db(0x20); db(0x2f); db(0x00); db(0x04); db(0x4e); db(0xae);
+ db(0xff); db(0x3a); db(0x4e); db(0x75); db(0x48); db(0xe7); db(0x03); db(0x00);
+ db(0x1e); db(0x2f); db(0x00); db(0x0f); db(0x7c); db(0x00); db(0x08); db(0x07);
+ db(0x00); db(0x00); db(0x67); db(0x02); db(0x52); db(0x86); db(0x08); db(0x07);
+ db(0x00); db(0x01); db(0x67); db(0x02); db(0x52); db(0x86); db(0x08); db(0x07);
+ db(0x00); db(0x02); db(0x67); db(0x02); db(0x52); db(0x86); db(0x20); db(0x06);
+ db(0x4c); db(0xdf); db(0x00); db(0xc0); db(0x4e); db(0x75); db(0x2f); db(0x07);
+ db(0x2e); db(0x2f); db(0x00); db(0x08); db(0x70); db(0x40); db(0xbe); db(0x80);
+ db(0x6f); db(0x28); db(0x70); db(0x4a); db(0xbe); db(0x80); db(0x67); db(0x22);
+ db(0x70); db(0x5a); db(0xbe); db(0x80); db(0x67); db(0x1c); db(0x70); db(0x5b);
+ db(0xbe); db(0x80); db(0x67); db(0x16); db(0x70); db(0x5c); db(0xbe); db(0x80);
+ db(0x67); db(0x10); db(0x70); db(0x5d); db(0xbe); db(0x80); db(0x67); db(0x0a);
+ db(0x70); db(0x5e); db(0xbe); db(0x80); db(0x67); db(0x04); db(0x70); db(0x01);
+ db(0x60); db(0x02); db(0x70); db(0x00); db(0x2e); db(0x1f); db(0x4e); db(0x75);
+ db(0x9e); db(0xfc); db(0x00); db(0x14); db(0x48); db(0xe7); db(0x37); db(0x34);
+ db(0x2e); db(0x2f); db(0x00); db(0x44); db(0x24); db(0x6f); db(0x00); db(0x40);
+ db(0x26); db(0x6f); db(0x00); db(0x3c); db(0x2a); db(0x6f); db(0x00); db(0x38);
+ db(0x2c); db(0x07); db(0x70); db(0x3f); db(0xdc); db(0x80); db(0x2f); db(0x47);
+ db(0x00); db(0x28); db(0x20); db(0x2f); db(0x00); db(0x28); db(0xb0); db(0x86);
+ db(0x6e); db(0x00); db(0x00); db(0xfe); db(0x2f); db(0x00); db(0x61); db(0x96);
+ db(0x58); db(0x4f); db(0x4a); db(0x80); db(0x66); db(0x00); db(0x00); db(0xe6);
+ db(0x70); db(0x00); db(0x10); db(0x13); db(0x02); db(0x40); db(0xff); db(0xf8);
+ db(0x72); db(0x20); db(0x90); db(0x81); db(0x67); db(0x4a); db(0x72); db(0x20);
+ db(0x90); db(0x81); db(0x66); db(0x00); db(0x00); db(0xd0); db(0x70); db(0x00);
+ db(0x10); db(0x13); db(0x2f); db(0x00); db(0x61); db(0x00); db(0xff); db(0x46);
+ db(0x58); db(0x4f); db(0x72); db(0x00); db(0x01); db(0xc1); db(0x2a); db(0x01);
+ db(0x20); db(0x05); db(0xd0); db(0x80); db(0xd1); db(0xad); db(0x00); db(0x0c);
+ db(0x2f); db(0x52); db(0x00); db(0x30); db(0x42); db(0xaf); db(0x00); db(0x24);
+ db(0x20); db(0x2f); db(0x00); db(0x24); db(0xb0); db(0x85); db(0x6c); db(0x00);
+ db(0x00); db(0xa4); db(0x70); db(0x00); db(0x20); db(0x6f); db(0x00); db(0x30);
+ db(0x10); db(0x10); db(0xd1); db(0xad); db(0x00); db(0x0c); db(0x52); db(0xaf);
+ db(0x00); db(0x24); db(0x54); db(0xaf); db(0x00); db(0x30); db(0x60); db(0xe0);
+ db(0x70); db(0x00); db(0x10); db(0x13); db(0x2f); db(0x00); db(0x61); db(0x00);
+ db(0xff); db(0x04); db(0x58); db(0x4f); db(0x72); db(0x00); db(0x01); db(0xc1);
+ db(0x2a); db(0x01); db(0x20); db(0x05); db(0xd0); db(0x80); db(0xd1); db(0xad);
+ db(0x00); db(0x0c); db(0x2f); db(0x52); db(0x00); db(0x2c); db(0x42); db(0xaf);
+ db(0x00); db(0x24); db(0x20); db(0x2f); db(0x00); db(0x24); db(0xb0); db(0x85);
+ db(0x6c); db(0x62); db(0x20); db(0x6f); db(0x00); db(0x2c); db(0x10); db(0x10);
+ db(0x72); db(0x08); db(0xb0); db(0x01); db(0x66); db(0x44); db(0x72); db(0x00);
+ db(0x12); db(0x28); db(0x00); db(0x01); db(0x24); db(0x01); db(0xe8); db(0x82);
+ db(0x76); db(0x0f); db(0xc4); db(0x83); db(0x3f); db(0x42); db(0x00); db(0x22);
+ db(0x67); db(0x1e); db(0x3b); db(0x42); db(0x00); db(0x04); db(0x70); db(0x00);
+ db(0x10); db(0x28); db(0x00); db(0x01); db(0x22); db(0x00); db(0xc2); db(0x83);
+ db(0x3f); db(0x41); db(0x00); db(0x22); db(0xb2); db(0x6d); db(0x00); db(0x02);
+ db(0x6f); db(0x20); db(0x3b); db(0x41); db(0x00); db(0x02); db(0x60); db(0x1a);
+ db(0x74); db(0x00); db(0x14); db(0x01); db(0xc4); db(0x83); db(0x3f); db(0x42);
+ db(0x00); db(0x22); db(0xb4); db(0x55); db(0x6f); db(0x0c); db(0x3a); db(0x82);
+ db(0x60); db(0x08); db(0x53); db(0x00); db(0x66); db(0x04); db(0x52); db(0x6d);
+ db(0x00); db(0x06); db(0x52); db(0xaf); db(0x00); db(0x24); db(0x54); db(0xaf);
+ db(0x00); db(0x2c); db(0x60); db(0x96); db(0x52); db(0xaf); db(0x00); db(0x28);
+ db(0x52); db(0x8b); db(0x58); db(0x8a); db(0x60); db(0x00); db(0xfe); db(0xfc);
+ db(0x4c); db(0xdf); db(0x2c); db(0xec); db(0xde); db(0xfc); db(0x00); db(0x14);
+ db(0x4e); db(0x75); db(0x48); db(0xe7); db(0x01); db(0x34); db(0x2e); db(0x2f);
+ db(0x00); db(0x1c); db(0x26); db(0x6f); db(0x00); db(0x18); db(0x2a); db(0x6f);
+ db(0x00); db(0x14); db(0x24); db(0x6d); db(0x00); db(0x10); db(0x20); db(0x4b);
+ db(0x22); db(0x6d); db(0x00); db(0x10); db(0x20); db(0x07); db(0x60); db(0x02);
+ db(0x12); db(0xd8); db(0x53); db(0x80); db(0x64); db(0xfa); db(0x20); db(0x6d);
+ db(0x00); db(0x10); db(0xd1); db(0xc7); db(0x2b); db(0x48); db(0x00); db(0x10);
+ db(0xdf); db(0xad); db(0x00); db(0x14); db(0x20); db(0x0a); db(0x4c); db(0xdf);
+ db(0x2c); db(0x80); db(0x4e); db(0x75); db(0x9e); db(0xfc); db(0x00); db(0x1c);
+ db(0x48); db(0xe7); db(0x07); db(0x34); db(0x2e); db(0x2f); db(0x00); db(0x4c);
+ db(0x24); db(0x6f); db(0x00); db(0x40); db(0x26); db(0x6f); db(0x00); db(0x3c);
+ db(0x2a); db(0x6f); db(0x00); db(0x38); db(0x2c); db(0x07); db(0x70); db(0x3f);
+ db(0xdc); db(0x80); db(0x2f); db(0x47); db(0x00); db(0x20); db(0x20); db(0x2f);
+ db(0x00); db(0x20); db(0xb0); db(0x86); db(0x6e); db(0x00); db(0x01); db(0xa0);
+ db(0x2f); db(0x00); db(0x61); db(0x00); db(0xfe); db(0x2a); db(0x58); db(0x4f);
+ db(0x4a); db(0x80); db(0x67); db(0x06); db(0x70); db(0x40); db(0xd0); db(0x80);
+ db(0x60); db(0x04); db(0x70); db(0x00); db(0x10); db(0x13); db(0x72); db(0x00);
+ db(0x12); db(0x00); db(0x02); db(0x41); db(0xff); db(0xf8); db(0x1f); db(0x40);
+ db(0x00); db(0x1a); db(0x4a); db(0x81); db(0x67); db(0x00); db(0x01); db(0x64);
+ db(0x70); db(0x20); db(0x92); db(0x80); db(0x67); db(0x00); db(0x00); db(0xa8);
+ db(0x70); db(0x20); db(0x92); db(0x80); db(0x67); db(0x04); db(0x60); db(0x00);
+ db(0x01); db(0x4e); db(0x70); db(0x00); db(0x10); db(0x13); db(0x2f); db(0x00);
+ db(0x61); db(0x00); db(0xfd); db(0xc2); db(0x72); db(0x00); db(0x01); db(0xc1);
+ db(0x2a); db(0x01); db(0x22); db(0x6f); db(0x00); db(0x48); db(0x20); db(0x51);
+ db(0x22); db(0x6f); db(0x00); db(0x4c); db(0x22); db(0xad); db(0x00); db(0x14);
+ db(0x20); db(0x05); db(0xd0); db(0x80); db(0x2e); db(0x80); db(0x2f); db(0x08);
+ db(0x2f); db(0x0d); db(0x2f); db(0x48); db(0x00); db(0x3c); db(0x61); db(0x00);
+ db(0xff); db(0x32); db(0x4f); db(0xef); db(0x00); db(0x0c); db(0x22); db(0x05);
+ db(0xd2); db(0x81); db(0x42); db(0xaf); db(0x00); db(0x1c); db(0x2f); db(0x40);
+ db(0x00); db(0x28); db(0x1f); db(0x41); db(0x00); db(0x1b); db(0x20); db(0x2f);
+ db(0x00); db(0x1c); db(0xb0); db(0x85); db(0x6c); db(0x00); db(0x01); db(0x04);
+ db(0x20); db(0x6f); db(0x00); db(0x30); db(0x10); db(0x10); db(0x20); db(0x6f);
+ db(0x00); db(0x28); db(0x10); db(0x80); db(0x11); db(0x6f); db(0x00); db(0x1b);
+ db(0x00); db(0x01); db(0x22); db(0x6f); db(0x00); db(0x44); db(0x20); db(0x51);
+ db(0x70); db(0x00); db(0x22); db(0x6f); db(0x00); db(0x30); db(0x10); db(0x29);
+ db(0x00); db(0x01); db(0xd0); db(0xc0); db(0x70); db(0x00); db(0x10); db(0x11);
+ db(0x2f); db(0x00); db(0x2f); db(0x08); db(0x2f); db(0x0d); db(0x61); db(0x00);
+ db(0xfe); db(0xe2); db(0x4f); db(0xef); db(0x00); db(0x0c); db(0x20); db(0x6f);
+ db(0x00); db(0x30); db(0x10); db(0x10); db(0xd1); db(0x2f); db(0x00); db(0x1b);
+ db(0x52); db(0xaf); db(0x00); db(0x1c); db(0x54); db(0xaf); db(0x00); db(0x30);
+ db(0x54); db(0xaf); db(0x00); db(0x28); db(0x60); db(0xa8); db(0x70); db(0x00);
+ db(0x10); db(0x13); db(0x2f); db(0x00); db(0x61); db(0x00); db(0xfd); db(0x26);
+ db(0x72); db(0x00); db(0x01); db(0xc1); db(0x2a); db(0x01); db(0x22); db(0x6f);
+ db(0x00); db(0x48); db(0x20); db(0x51); db(0x22); db(0x6f); db(0x00); db(0x4c);
+ db(0x22); db(0xad); db(0x00); db(0x14); db(0x20); db(0x05); db(0xd0); db(0x80);
+ db(0x2e); db(0x80); db(0x2f); db(0x08); db(0x2f); db(0x0d); db(0x2f); db(0x48);
+ db(0x00); db(0x38); db(0x61); db(0x00); db(0xfe); db(0x96); db(0x4f); db(0xef);
+ db(0x00); db(0x0c); db(0x22); db(0x05); db(0xd2); db(0x81); db(0x42); db(0xaf);
+ db(0x00); db(0x1c); db(0x2f); db(0x40); db(0x00); db(0x24); db(0x1f); db(0x41);
+ db(0x00); db(0x1b); db(0x20); db(0x2f); db(0x00); db(0x1c); db(0xb0); db(0x85);
+ db(0x6c); db(0x68); db(0x20); db(0x6f); db(0x00); db(0x2c); db(0x10); db(0x10);
+ db(0x20); db(0x6f); db(0x00); db(0x24); db(0x10); db(0x80); db(0x70); db(0x01);
+ db(0x20); db(0x6f); db(0x00); db(0x2c); db(0xb0); db(0x10); db(0x66); db(0x36);
+ db(0x20); db(0x6f); db(0x00); db(0x24); db(0x11); db(0x6f); db(0x00); db(0x1b);
+ db(0x00); db(0x01); db(0x22); db(0x6f); db(0x00); db(0x44); db(0x20); db(0x51);
+ db(0x70); db(0x00); db(0x22); db(0x6f); db(0x00); db(0x2c); db(0x10); db(0x29);
+ db(0x00); db(0x01); db(0xd0); db(0xc0); db(0x2f); db(0x2d); db(0x00); db(0x08);
+ db(0x2f); db(0x08); db(0x2f); db(0x0d); db(0x61); db(0x00); db(0xfe); db(0x3c);
+ db(0x4f); db(0xef); db(0x00); db(0x0c); db(0x20); db(0x2d); db(0x00); db(0x08);
+ db(0xd1); db(0x2f); db(0x00); db(0x1b); db(0x60); db(0x0a); db(0x22); db(0x6f);
+ db(0x00); db(0x24); db(0x13); db(0x68); db(0x00); db(0x01); db(0x00); db(0x01);
+ db(0x52); db(0xaf); db(0x00); db(0x1c); db(0x54); db(0xaf); db(0x00); db(0x2c);
+ db(0x54); db(0xaf); db(0x00); db(0x24); db(0x60); db(0x94); db(0x14); db(0xbc);
+ db(0x00); db(0x80); db(0x52); db(0xaf); db(0x00); db(0x20); db(0x52); db(0x8b);
+ db(0x52); db(0x8a); db(0x58); db(0xaf); db(0x00); db(0x44); db(0x58); db(0xaf);
+ db(0x00); db(0x48); db(0x60); db(0x00); db(0xfe); db(0x5a); db(0x4c); db(0xdf);
+ db(0x2c); db(0xe0); db(0xde); db(0xfc); db(0x00); db(0x1c); db(0x4e); db(0x75);
+ db(0x9e); db(0xfc); db(0x00); db(0x2c); db(0x48); db(0xe7); db(0x20); db(0x34);
+ db(0x26); db(0x6f); db(0x00); db(0x44); db(0x2a); db(0x6f); db(0x00); db(0x40);
+ db(0x20); db(0x0d); db(0x67); db(0x04); db(0x20); db(0x0b); db(0x66); db(0x06);
+ db(0x70); db(0x00); db(0x60); db(0x00); db(0x01); db(0xa2); db(0x4a); db(0x95);
+ db(0x67); db(0x2a); db(0x4a); db(0xad); db(0x00); db(0x10); db(0x67); db(0x24);
+ db(0x4a); db(0xad); db(0x00); db(0x04); db(0x67); db(0x1e); db(0x4a); db(0xad);
+ db(0x00); db(0x14); db(0x67); db(0x18); db(0x4a); db(0xad); db(0x00); db(0x08);
+ db(0x67); db(0x12); db(0x4a); db(0xad); db(0x00); db(0x18); db(0x67); db(0x0c);
+ db(0x4a); db(0xad); db(0x00); db(0x0c); db(0x67); db(0x06); db(0x4a); db(0xad);
+ db(0x00); db(0x1c); db(0x66); db(0x06); db(0x70); db(0x00); db(0x60); db(0x00);
+ db(0x01); db(0x6e); db(0x70); db(0x00); db(0x41); db(0xef); db(0x00); db(0x24);
+ db(0x72); db(0x17); db(0x10); db(0xc0); db(0x51); db(0xc9); db(0xff); db(0xfc);
+ db(0x2f); db(0x7c); db(0x00); db(0x00); db(0x02); db(0xa2); db(0x00); db(0x30);
+ db(0x2f); db(0x00); db(0x2f); db(0x2d); db(0x00); db(0x04); db(0x2f); db(0x15);
+ db(0x48); db(0x6f); db(0x00); db(0x30); db(0x61); db(0x00); db(0xfc); db(0x4a);
+ db(0x48); db(0x78); db(0x00); db(0x40); db(0x2f); db(0x2d); db(0x00); db(0x14);
+ db(0x2f); db(0x2d); db(0x00); db(0x10); db(0x48); db(0x6f); db(0x00); db(0x40);
+ db(0x61); db(0x00); db(0xfc); db(0x36); db(0x4f); db(0xef); db(0x00); db(0x20);
+ db(0x30); db(0x2f); db(0x00); db(0x2a); db(0x67); db(0x24); db(0x32); db(0x2f);
+ db(0x00); db(0x28); db(0x67); db(0x0a); db(0x34); db(0x2f); db(0x00); db(0x26);
+ db(0x52); db(0x42); db(0xc5); db(0xc1); db(0x60); db(0x0a); db(0x32); db(0x2f);
+ db(0x00); db(0x24); db(0x48); db(0xc1); db(0x52); db(0x81); db(0x24); db(0x01);
+ db(0x2f); db(0x42); db(0x00); db(0x2c); db(0xc1); db(0xc2); db(0xd1); db(0xaf);
+ db(0x00); db(0x30); db(0x42); db(0xa7); db(0x2f); db(0x2f); db(0x00); db(0x34);
+ db(0x61); db(0x00); db(0xfb); db(0x8c); db(0x50); db(0x4f); db(0x2f); db(0x40);
+ db(0x00); db(0x14); db(0x67); db(0x00); db(0x00); db(0xee); db(0x2f); db(0x40);
+ db(0x00); db(0x34); db(0x1f); db(0x7c); db(0x00); db(0x01); db(0x00); db(0x12);
+ db(0x20); db(0x2f); db(0x00); db(0x2c); db(0x1f); db(0x40); db(0x00); db(0x13);
+ db(0x48); db(0x78); db(0x00); db(0x02); db(0x48); db(0x6f); db(0x00); db(0x16);
+ db(0x48); db(0x6f); db(0x00); db(0x2c); db(0x61); db(0x00); db(0xfd); db(0x04);
+ db(0x48); db(0x78); db(0x00); db(0x40); db(0x2f); db(0x15); db(0x48); db(0x6f);
+ db(0x00); db(0x38); db(0x61); db(0x00); db(0xfc); db(0xf6); db(0x48); db(0x78);
+ db(0x00); db(0x40); db(0x2f); db(0x2d); db(0x00); db(0x10); db(0x48); db(0x6f);
+ db(0x00); db(0x44); db(0x2f); db(0x40); db(0x00); db(0x40); db(0x61); db(0x00);
+ db(0xfc); db(0xe2); db(0x48); db(0x78); db(0x01); db(0x00); db(0x2f); db(0x2d);
+ db(0x00); db(0x04); db(0x48); db(0x6f); db(0x00); db(0x50); db(0x2f); db(0x40);
+ db(0x00); db(0x48); db(0x61); db(0x00); db(0xfc); db(0xce); db(0x24); db(0x40);
+ db(0x48); db(0x78); db(0x01); db(0x00); db(0x2f); db(0x2d); db(0x00); db(0x14);
+ db(0x48); db(0x6f); db(0x00); db(0x5c); db(0x61); db(0x00); db(0xfc); db(0xbc);
+ db(0x48); db(0x78); db(0x00); db(0x08); db(0x2f); db(0x2d); db(0x00); db(0x08);
+ db(0x48); db(0x6f); db(0x00); db(0x68); db(0x2f); db(0x40); db(0x00); db(0x68);
+ db(0x61); db(0x00); db(0xfc); db(0xa8); db(0x4f); db(0xef); db(0x00); db(0x48);
+ db(0x48); db(0x78); db(0x00); db(0x08); db(0x2f); db(0x2d); db(0x00); db(0x18);
+ db(0x48); db(0x6f); db(0x00); db(0x2c); db(0x61); db(0x00); db(0xfc); db(0x94);
+ db(0x48); db(0x78); db(0x00); db(0x08); db(0x2f); db(0x2d); db(0x00); db(0x0c);
+ db(0x48); db(0x6f); db(0x00); db(0x38); db(0x61); db(0x00); db(0xfc); db(0x84);
+ db(0x48); db(0x78); db(0x00); db(0x08); db(0x2f); db(0x2d); db(0x00); db(0x1c);
+ db(0x48); db(0x6f); db(0x00); db(0x44); db(0x61); db(0x00); db(0xfc); db(0x74);
+ db(0x42); db(0x97); db(0x2f); db(0x0a); db(0x2f); db(0x2d); db(0x00); db(0x04);
+ db(0x2f); db(0x2f); db(0x00); db(0x48); db(0x2f); db(0x15); db(0x48); db(0x6f);
+ db(0x00); db(0x58); db(0x61); db(0x00); db(0xfc); db(0x98); db(0x48); db(0x78);
+ db(0x00); db(0x40); db(0x2f); db(0x2f); db(0x00); db(0x5c); db(0x2f); db(0x2d);
+ db(0x00); db(0x14); db(0x2f); db(0x2f); db(0x00); db(0x5c); db(0x2f); db(0x2d);
+ db(0x00); db(0x10); db(0x48); db(0x6f); db(0x00); db(0x70); db(0x61); db(0x00);
+ db(0xfc); db(0x7c); db(0x4f); db(0xef); db(0x00); db(0x50); db(0x26); db(0xaf);
+ db(0x00); db(0x30); db(0x20); db(0x2f); db(0x00); db(0x14); db(0x4c); db(0xdf);
+ db(0x2c); db(0x04); db(0xde); db(0xfc); db(0x00); db(0x2c); db(0x4e); db(0x75);
+ db(0x41); db(0xfa); db(0xd7); db(0xfa); db(0x02); db(0x80); db(0x00); db(0x00);
+ db(0xff); db(0xff); db(0xd1); db(0xc0); db(0x4e); db(0x75); db(0x00); db(0x00);
+ db(0x41); db(0xfa); db(0xd7); db(0xea); db(0x02); db(0x80); db(0x00); db(0x00);
+ db(0xff); db(0xff); db(0xd1); db(0xc0); db(0x4e); db(0x75); db(0x4e); db(0x71);
+ db(0x4e); db(0x71); db(0x69); db(0x6e); db(0x70); db(0x75); db(0x74); db(0x2e);
+ db(0x64); db(0x65); db(0x76); db(0x69); db(0x63); db(0x65); db(0x00); db(0x74);
+ db(0x69); db(0x6d); db(0x65); db(0x72); db(0x2e); db(0x64); db(0x65); db(0x76);
+ db(0x69); db(0x63); db(0x65); db(0x00); db(0x63); db(0x6f); db(0x6e); db(0x73);
+ db(0x6f); db(0x6c); db(0x65); db(0x2e); db(0x64); db(0x65); db(0x76); db(0x69);
+ db(0x63); db(0x65); db(0x00); db(0x6b); db(0x65); db(0x79); db(0x6d); db(0x61);
+ db(0x70); db(0x2e); db(0x6c); db(0x69); db(0x62); db(0x72); db(0x61); db(0x72);
+ db(0x79); db(0x00); db(0x44); db(0x45); db(0x56); db(0x53); db(0x00); db(0x44);
+ db(0x45); db(0x56); db(0x53); db(0x3a); db(0x00); db(0x44); db(0x45); db(0x56);
+ db(0x53); db(0x3a); db(0x63); db(0x6c); db(0x69); db(0x70); db(0x62); db(0x6f);
  db(0x61); db(0x72); db(0x64); db(0x2e); db(0x64); db(0x65); db(0x76); db(0x69);
- db(0x63); db(0x65); db(0x00); db(0x52); db(0x41); db(0x4d); db(0x3a); db(0x45);
- db(0x6e); db(0x76); db(0x2f); db(0x53); db(0x79); db(0x73); db(0x2f); db(0x50);
- db(0x6f); db(0x69); db(0x6e); db(0x74); db(0x65); db(0x72); db(0x2e); db(0x70);
- db(0x72); db(0x65); db(0x66); db(0x73); db(0x00); db(0x55); db(0x41); db(0x45);
- db(0x20); db(0x63); db(0x6c); db(0x69); db(0x70); db(0x62); db(0x6f); db(0x61);
- db(0x72); db(0x64); db(0x20); db(0x73); db(0x68); db(0x61); db(0x72); db(0x69);
- db(0x6e); db(0x67); db(0x00); db(0x55); db(0x41); db(0x45); db(0x20); db(0x6d);
- db(0x6f); db(0x75); db(0x73); db(0x65); db(0x20); db(0x64); db(0x72); db(0x69);
- db(0x76); db(0x65); db(0x72); db(0x00); db(0x55); db(0x41); db(0x45); db(0x20);
- db(0x68); db(0x65); db(0x61); db(0x72); db(0x74); db(0x20); db(0x62); db(0x65);
- db(0x61); db(0x74); db(0x00); db(0x55); db(0x41); db(0x45); db(0x20); db(0x66);
- db(0x73); db(0x00); db(0x55); db(0x41); db(0x45); db(0x20); db(0x66); db(0x73);
- db(0x20); db(0x61); db(0x75); db(0x74); db(0x6f); db(0x6d); db(0x6f); db(0x75);
- db(0x6e); db(0x74); db(0x65); db(0x72); db(0x00); db(0x55); db(0x41); db(0x45);
- db(0x20); db(0x66); db(0x73); db(0x20); db(0x77); db(0x6f); db(0x72); db(0x6b);
- db(0x65); db(0x72); db(0x00); db(0x55); db(0x41); db(0x45); db(0x20); db(0x74);
- db(0x72); db(0x61); db(0x70); db(0x20); db(0x77); db(0x6f); db(0x72); db(0x6b);
- db(0x65); db(0x72); db(0x00); db(0x55); db(0x41); db(0x45); db(0x20); db(0x66);
- db(0x73); db(0x20); db(0x61); db(0x75); db(0x74); db(0x6f); db(0x6d); db(0x6f);
- db(0x75); db(0x6e); db(0x74); db(0x20); db(0x70); db(0x72); db(0x6f); db(0x63);
- db(0x65); db(0x73); db(0x73); db(0x00); db(0x55); db(0x41); db(0x45); db(0x20);
- db(0x64); db(0x65); db(0x62); db(0x75); db(0x67); db(0x67); db(0x65); db(0x72);
- db(0x00); db(0x64); db(0x6f); db(0x73); db(0x2e); db(0x6c); db(0x69); db(0x62);
- db(0x72); db(0x61); db(0x72); db(0x79); db(0x00); db(0x69); db(0x6e); db(0x74);
- db(0x75); db(0x69); db(0x74); db(0x69); db(0x6f); db(0x6e); db(0x2e); db(0x6c);
- db(0x69); db(0x62); db(0x72); db(0x61); db(0x72); db(0x79); db(0x00); db(0x67);
- db(0x72); db(0x61); db(0x70); db(0x68); db(0x69); db(0x63); db(0x73); db(0x2e);
+ db(0x63); db(0x65); db(0x00); db(0x52); db(0x41); db(0x4d); db(0x3a); db(0x00);
+ db(0x4e); db(0x49); db(0x4c); db(0x3a); db(0x00); db(0x63); db(0x6c); db(0x69);
+ db(0x70); db(0x62); db(0x6f); db(0x61); db(0x72); db(0x64); db(0x2e); db(0x64);
+ db(0x65); db(0x76); db(0x69); db(0x63); db(0x65); db(0x00); db(0x52); db(0x41);
+ db(0x4d); db(0x3a); db(0x45); db(0x6e); db(0x76); db(0x2f); db(0x53); db(0x79);
+ db(0x73); db(0x2f); db(0x50); db(0x6f); db(0x69); db(0x6e); db(0x74); db(0x65);
+ db(0x72); db(0x2e); db(0x70); db(0x72); db(0x65); db(0x66); db(0x73); db(0x00);
+ db(0x55); db(0x41); db(0x45); db(0x20); db(0x63); db(0x6c); db(0x69); db(0x70);
+ db(0x62); db(0x6f); db(0x61); db(0x72); db(0x64); db(0x20); db(0x73); db(0x68);
+ db(0x61); db(0x72); db(0x69); db(0x6e); db(0x67); db(0x00); db(0x55); db(0x41);
+ db(0x45); db(0x20); db(0x6d); db(0x6f); db(0x75); db(0x73); db(0x65); db(0x20);
+ db(0x64); db(0x72); db(0x69); db(0x76); db(0x65); db(0x72); db(0x00); db(0x55);
+ db(0x41); db(0x45); db(0x20); db(0x68); db(0x65); db(0x61); db(0x72); db(0x74);
+ db(0x20); db(0x62); db(0x65); db(0x61); db(0x74); db(0x00); db(0x55); db(0x41);
+ db(0x45); db(0x20); db(0x66); db(0x73); db(0x00); db(0x55); db(0x41); db(0x45);
+ db(0x20); db(0x66); db(0x73); db(0x20); db(0x61); db(0x75); db(0x74); db(0x6f);
+ db(0x6d); db(0x6f); db(0x75); db(0x6e); db(0x74); db(0x65); db(0x72); db(0x00);
+ db(0x55); db(0x41); db(0x45); db(0x20); db(0x66); db(0x73); db(0x20); db(0x77);
+ db(0x6f); db(0x72); db(0x6b); db(0x65); db(0x72); db(0x00); db(0x55); db(0x41);
+ db(0x45); db(0x20); db(0x74); db(0x72); db(0x61); db(0x70); db(0x20); db(0x77);
+ db(0x6f); db(0x72); db(0x6b); db(0x65); db(0x72); db(0x00); db(0x55); db(0x41);
+ db(0x45); db(0x20); db(0x66); db(0x73); db(0x20); db(0x61); db(0x75); db(0x74);
+ db(0x6f); db(0x6d); db(0x6f); db(0x75); db(0x6e); db(0x74); db(0x20); db(0x70);
+ db(0x72); db(0x6f); db(0x63); db(0x65); db(0x73); db(0x73); db(0x00); db(0x55);
+ db(0x41); db(0x45); db(0x20); db(0x64); db(0x65); db(0x62); db(0x75); db(0x67);
+ db(0x67); db(0x65); db(0x72); db(0x00); db(0x64); db(0x6f); db(0x73); db(0x2e);
  db(0x6c); db(0x69); db(0x62); db(0x72); db(0x61); db(0x72); db(0x79); db(0x00);
- db(0x65); db(0x78); db(0x70); db(0x61); db(0x6e); db(0x73); db(0x69); db(0x6f);
+ db(0x69); db(0x6e); db(0x74); db(0x75); db(0x69); db(0x74); db(0x69); db(0x6f);
  db(0x6e); db(0x2e); db(0x6c); db(0x69); db(0x62); db(0x72); db(0x61); db(0x72);
- db(0x79); db(0x00); db(0x46); db(0x69); db(0x6c); db(0x65); db(0x53); db(0x79);
- db(0x73); db(0x74); db(0x65); db(0x6d); db(0x2e); db(0x72); db(0x65); db(0x73);
- db(0x6f); db(0x75); db(0x72); db(0x63); db(0x65); db(0x00); db(0x6d); db(0x65);
- db(0x67); db(0x61); db(0x63); db(0x68); db(0x69); db(0x70); db(0x20); db(0x6d);
- db(0x65); db(0x6d); db(0x6f); db(0x72); db(0x79); db(0x00); db(0x46); db(0x69);
- db(0x6c); db(0x65); db(0x20); db(0x53); db(0x79); db(0x73); db(0x74); db(0x65);
- db(0x6d); db(0x00); db(0x55); db(0x41); db(0x45); db(0x20); db(0x73); db(0x68);
- db(0x65); db(0x6c); db(0x6c); db(0x20); db(0x65); db(0x78); db(0x65); db(0x63);
- db(0x75); db(0x74); db(0x65); db(0x00); db(0x55); db(0x41); db(0x45); db(0x20);
- db(0x62); db(0x6f); db(0x61); db(0x72); db(0x64); db(0x00); db(0x00); db(0x00);
- db(0x00); db(0x00); db(0x03); db(0xf2);
+ db(0x79); db(0x00); db(0x67); db(0x72); db(0x61); db(0x70); db(0x68); db(0x69);
+ db(0x63); db(0x73); db(0x2e); db(0x6c); db(0x69); db(0x62); db(0x72); db(0x61);
+ db(0x72); db(0x79); db(0x00); db(0x65); db(0x78); db(0x70); db(0x61); db(0x6e);
+ db(0x73); db(0x69); db(0x6f); db(0x6e); db(0x2e); db(0x6c); db(0x69); db(0x62);
+ db(0x72); db(0x61); db(0x72); db(0x79); db(0x00); db(0x46); db(0x69); db(0x6c);
+ db(0x65); db(0x53); db(0x79); db(0x73); db(0x74); db(0x65); db(0x6d); db(0x2e);
+ db(0x72); db(0x65); db(0x73); db(0x6f); db(0x75); db(0x72); db(0x63); db(0x65);
+ db(0x00); db(0x6d); db(0x65); db(0x67); db(0x61); db(0x63); db(0x68); db(0x69);
+ db(0x70); db(0x20); db(0x6d); db(0x65); db(0x6d); db(0x6f); db(0x72); db(0x79);
+ db(0x00); db(0x46); db(0x69); db(0x6c); db(0x65); db(0x20); db(0x53); db(0x79);
+ db(0x73); db(0x74); db(0x65); db(0x6d); db(0x00); db(0x55); db(0x41); db(0x45);
+ db(0x20); db(0x73); db(0x68); db(0x65); db(0x6c); db(0x6c); db(0x20); db(0x65);
+ db(0x78); db(0x65); db(0x63); db(0x75); db(0x74); db(0x65); db(0x00); db(0x55);
+ db(0x41); db(0x45); db(0x20); db(0x62); db(0x6f); db(0x61); db(0x72); db(0x64);
+ db(0x00); db(0x00); db(0x00); db(0x00); db(0x00); db(0x00); db(0x03); db(0xf2);
 
diff --git a/filesys_helpers.asm b/filesys_helpers.asm
new file mode 100644 (file)
index 0000000..7f7b67e
--- /dev/null
@@ -0,0 +1,918 @@
+#if 0
+
+/*****************************************************************************
+ Name    : GetKeyMapData.c
+ Project : RetroPlatform Player
+ Support : http://www.retroplatform.com
+ Legal   : Copyright 2016 Cloanto Italia srl - All rights reserved. This
+         : file is multi-licensed under the terms of the Mozilla Public License
+         : version 2.0 as published by Mozilla Corporation and the GNU General
+         : Public License, version 2 or later, as published by the Free
+         : Software Foundation.
+ Authors : os
+ Created : 2016-07-12 09:58:12
+ Comment : this guest-side Amiga code allocates and initializes a keymap data buffer
+           which can be used in RP_IPC_TO_HOST_KEYBOARDLAYOUT notifications
+ *****************************************************************************/
+
+#include <exec/types.h>
+#include <exec/memory.h>
+#include <exec/io.h>
+#include <dos/dos.h>
+#include <devices/inputevent.h>
+#include <devices/console.h>
+#include <devices/keymap.h>
+#include <clib/exec_protos.h>
+#include <clib/dos_protos.h>
+#include <stdlib.h>
+#include <string.h>
+
+struct KeyStringData
+{
+       UBYTE nLength;
+       UBYTE nOffset;
+};
+
+struct KeyDeadData
+{
+       UBYTE nType;
+       UBYTE nValue;
+};
+
+struct KeyMapData
+{
+       int nHighestDeadKeyIndex;
+       int nHighestDoubleDeadKeyIndex;
+       int nDoubleDeadOffset;
+       int nDeadableKeyCount;
+       int nDeadableKeyDataCount;
+       ULONG nSize;
+       void *pData;
+       ULONG nDataPos;
+};
+
+struct KeyMapDataHeader
+{
+       UBYTE nVersion;
+       UBYTE nDeadableKeyDataCount;
+};
+#define KDH_VERSION 1 // current version
+
+
+
+/*****************************************************************************
+ Name      : GetQualifierCount
+ Arguments : UBYTE type - 
+ Return    : int        - 
+ Comment   : 
+ *****************************************************************************/
+
+static int GetQualifierCount(UBYTE type)
+{
+       int nCount = 0;
+       if (type & KCF_SHIFT)
+               nCount += 1;
+       if (type & KCF_ALT)
+               nCount += 1;
+       if (type & KCF_CONTROL)
+               nCount += 1;
+       return nCount;
+}
+
+/*****************************************************************************
+ Name      : ExcludeKey
+ Arguments : int nKey - 
+ Return    : int      - 
+ Comment   : 
+ *****************************************************************************/
+
+static int ExcludeKey(int nKey)
+{
+       return (nKey > 0x40 &&
+                  nKey != 0x4A && // numapd -
+                  nKey != 0x5A && // numapd {
+                  nKey != 0x5B && // numpad }
+                  nKey != 0x5C && // numpad /
+                  nKey != 0x5D && // numpad *
+                  nKey != 0x5E)   // numpad +
+                  ? 1 : 0;
+}
+
+/*****************************************************************************
+ Name      : GetKeyMapDataInfo
+ Arguments : struct KeyMapData *pKeyMapData - 
+           : const UBYTE *pKeyMapTypes      - 
+           : const ULONG *pKeyMap           - 
+           : int nFirstKey                  - 
+ Return    : void
+ Comment   : 
+ *****************************************************************************/
+
+static void GetKeyMapDataInfo(struct KeyMapData *pKeyMapData, const UBYTE *pKeyMapTypes, const ULONG *pKeyMap, int nFirstKey)
+{
+       const struct KeyStringData *pStringData;
+       const struct KeyDeadData *pDeadData;
+       int nLastKey, nCount, nIndex, nKey, i;
+
+       nLastKey = nFirstKey + 0x3F;
+       for (nKey = nFirstKey; nKey <= nLastKey; nKey++, pKeyMapTypes++, pKeyMap++)
+       {
+               if (ExcludeKey(nKey))
+                       continue;
+               switch (*pKeyMapTypes & ~KC_VANILLA)
+               {
+                       case KCF_STRING:
+                               nCount = 1 << GetQualifierCount(*pKeyMapTypes);
+                               pKeyMapData->nSize += nCount * sizeof(struct KeyStringData);
+                               pStringData = (const struct KeyStringData *)(*pKeyMap);
+                               for (i = 0; i < nCount; i++, pStringData++)
+                                       pKeyMapData->nSize += (ULONG)pStringData->nLength;
+                               break;
+                       case KCF_DEAD:
+                               nCount = 1 << GetQualifierCount(*pKeyMapTypes);
+                               pKeyMapData->nSize += nCount * sizeof(struct KeyDeadData);
+                               pDeadData = (const struct KeyDeadData *)(*pKeyMap);
+                               for (i = 0; i < nCount; i++, pDeadData++)
+                               {
+                                       if (pDeadData->nType == DPF_DEAD)
+                                       {
+                                               nIndex = (int)((pDeadData->nValue >> DP_2DFACSHIFT) & DP_2DINDEXMASK);
+                                               if (nIndex)
+                                               {
+                                                       pKeyMapData->nDoubleDeadOffset = nIndex;
+                                                       nIndex = (int)(pDeadData->nValue & DP_2DINDEXMASK);
+                                                       if (nIndex > pKeyMapData->nHighestDoubleDeadKeyIndex)
+                                                               pKeyMapData->nHighestDoubleDeadKeyIndex = nIndex;
+                                               }
+                                               else
+                                               {
+                                                       nIndex = (int)(pDeadData->nValue & DP_2DINDEXMASK);
+                                                       if (nIndex > pKeyMapData->nHighestDeadKeyIndex)
+                                                               pKeyMapData->nHighestDeadKeyIndex = nIndex;
+                                               }
+                                       }
+                                       else if (pDeadData->nType == DPF_MOD)
+                                               pKeyMapData->nDeadableKeyCount += 1;
+                               }
+                               break;
+               }
+       }
+}
+
+/*****************************************************************************
+ Name      : AddKeyMapData
+ Arguments : struct KeyMapData *pKeyMapData - 
+           : const void *pData              - 
+           : ULONG nSize                    - 
+ Return    : void *                         - 
+ Comment   : 
+ *****************************************************************************/
+
+static void *AddKeyMapData(struct KeyMapData *pKeyMapData, const void *pData, ULONG nSize)
+{
+       void *pCopiedData;
+       pCopiedData = pKeyMapData->pData;
+       memcpy(pKeyMapData->pData, pData, nSize);
+       pKeyMapData->pData = (UBYTE *)pKeyMapData->pData + nSize;
+       pKeyMapData->nDataPos += nSize;
+       return pCopiedData;
+}
+
+/*****************************************************************************
+ Name      : CopyKeyMapData
+ Arguments : struct KeyMapData *pKeyMapData - 
+           : const UBYTE *pKeyMapTypes      - 
+           : UBYTE *pKeyMapTypesDest        - 
+           : const ULONG *pKeyMap           - 
+           : ULONG *pKeyMapDest             - 
+           : int nFirstKey                  - 
+ Return    : void
+ Comment   : 
+ *****************************************************************************/
+
+static void CopyKeyMapData(struct KeyMapData *pKeyMapData, const UBYTE *pKeyMapTypes, UBYTE *pKeyMapTypesDest, const ULONG *pKeyMap, ULONG *pKeyMapDest, int nFirstKey)
+{
+       const struct KeyStringData *pStringData;
+       const struct KeyDeadData *pDeadData;
+       struct KeyStringData *pStringDataDest;
+       struct KeyDeadData *pDeadDataDest;
+       int nLastKey, nCount, nKey, i;
+       UBYTE nByteOffset, tp;
+
+       nLastKey = nFirstKey + 0x3F;
+       for (nKey = nFirstKey; nKey <= nLastKey; nKey++, pKeyMapTypes++, pKeyMapTypesDest++, pKeyMap++, pKeyMapDest++)
+       {
+               tp = ExcludeKey(nKey) ? KCF_NOP : *pKeyMapTypes;
+               switch (tp & ~KC_VANILLA)
+               {
+                       case KCF_STRING:
+                               nCount = 1 << GetQualifierCount(*pKeyMapTypes);
+                               pStringData = (const struct KeyStringData *)(*pKeyMap);
+                               *pKeyMapDest = pKeyMapData->nDataPos;
+                               pStringDataDest = AddKeyMapData(pKeyMapData, pStringData, nCount * sizeof(struct KeyStringData));
+                               nByteOffset = (UBYTE)(nCount * sizeof(struct KeyStringData));
+
+                               for (i = 0; i < nCount; i++, pStringData++, pStringDataDest++)
+                               {
+                                       pStringDataDest->nLength = pStringData->nLength;
+                                       pStringDataDest->nOffset = nByteOffset;
+                                       AddKeyMapData(pKeyMapData, (UBYTE *)*pKeyMap + pStringData->nOffset, pStringData->nLength);
+                                       nByteOffset += pStringData->nLength;
+                               }
+                               break;
+                       case KCF_DEAD:
+                               nCount = 1 << GetQualifierCount(*pKeyMapTypes);
+                               pDeadData = (const struct KeyDeadData *)(*pKeyMap);
+                               *pKeyMapDest = pKeyMapData->nDataPos;
+                               pDeadDataDest = AddKeyMapData(pKeyMapData, pDeadData, nCount * sizeof(struct KeyDeadData));
+                               nByteOffset = (UBYTE)(nCount * sizeof(struct KeyDeadData));
+
+                               for (i = 0; i < nCount; i++, pDeadData++, pDeadDataDest++)
+                               {
+                                       pDeadDataDest->nType = pDeadData->nType;
+                                       if (pDeadData->nType == DPF_MOD)
+                                       {
+                                               pDeadDataDest->nValue = nByteOffset;
+                                               AddKeyMapData(pKeyMapData, (UBYTE *)(*pKeyMap) + pDeadData->nValue, pKeyMapData->nDeadableKeyDataCount);
+                                               nByteOffset += (UBYTE)pKeyMapData->nDeadableKeyDataCount;
+                                       }
+                                       else pDeadDataDest->nValue = pDeadData->nValue;
+                               }
+                               break;
+                       default:
+                               *pKeyMapTypesDest = KCF_NOP;
+                               break;
+               }
+       }
+}
+
+/*****************************************************************************
+ Name      : GetKeyMapData
+ Arguments : const struct KeyMap *pKeyMap - 
+           : ULONG *pnSize                - 
+ Return    : void *                       - use FreeMem() to free the returned data
+ Comment   : 
+ *****************************************************************************/
+
+void *GetKeyMapData(const struct KeyMap *pKeyMap, ULONG *pnSize)
+{
+       struct KeyMapData kd;
+       struct KeyMapDataHeader kdh;
+       ULONG *pLoKeyMap, *pHiKeyMap;
+       UBYTE *pLoKeyMapTypes, *pHiKeyMapTypes;
+       void *pData;
+
+       if (!pKeyMap || !pnSize)
+               return NULL;
+
+       if (pKeyMap->km_LoKeyMapTypes == NULL ||
+               pKeyMap->km_HiKeyMapTypes == NULL ||
+               pKeyMap->km_LoKeyMap == NULL ||
+               pKeyMap->km_HiKeyMap == NULL ||
+               pKeyMap->km_LoCapsable == NULL ||
+               pKeyMap->km_HiCapsable == NULL ||
+               pKeyMap->km_LoRepeatable == NULL ||
+               pKeyMap->km_HiRepeatable == NULL)
+               return NULL;
+
+       memset(&kd, 0, sizeof(kd));
+       kd.nSize = (sizeof(struct KeyMapDataHeader) +
+                       0x40 + // km_LoKeyMapTypes data size
+                   0x40 + // km_HiKeyMapTypes data size
+                   (0x40 * sizeof(ULONG)) + // km_LoKeyMap data size
+                   (0x40 * sizeof(ULONG)) + // km_HiKeyMap data size
+                   8 + // km_LoCapsable data size
+                   8 + // km_HiCapsable data size
+                   8 + // km_LoRepeatable data size
+                   8); // km_HiRepeatable data size
+
+       GetKeyMapDataInfo(&kd, pKeyMap->km_LoKeyMapTypes, pKeyMap->km_LoKeyMap, 0);
+       GetKeyMapDataInfo(&kd, pKeyMap->km_HiKeyMapTypes, pKeyMap->km_HiKeyMap, 0x40);
+
+       if (kd.nDeadableKeyCount)
+       {
+               kd.nDeadableKeyDataCount = kd.nDoubleDeadOffset ? ((1 + kd.nHighestDoubleDeadKeyIndex) * kd.nDoubleDeadOffset) : (1 + kd.nHighestDeadKeyIndex);
+               kd.nSize += kd.nDeadableKeyCount * kd.nDeadableKeyDataCount;
+       }
+       pData = AllocMem(kd.nSize, MEMF_ANY);
+       if (pData)
+       {
+               kd.pData = pData;
+               kdh.nVersion = KDH_VERSION;
+               kdh.nDeadableKeyDataCount = kd.nDeadableKeyDataCount;
+               AddKeyMapData(&kd, &kdh, sizeof(struct KeyMapDataHeader));
+               pLoKeyMapTypes = AddKeyMapData(&kd, pKeyMap->km_LoKeyMapTypes, 0x40);
+               pHiKeyMapTypes = AddKeyMapData(&kd, pKeyMap->km_HiKeyMapTypes, 0x40);
+               pLoKeyMap = AddKeyMapData(&kd, pKeyMap->km_LoKeyMap, (0x40 * sizeof(ULONG)));
+               pHiKeyMap = AddKeyMapData(&kd, pKeyMap->km_HiKeyMap, (0x40 * sizeof(ULONG)));
+               AddKeyMapData(&kd, pKeyMap->km_LoCapsable, 8);
+               AddKeyMapData(&kd, pKeyMap->km_HiCapsable, 8);
+               AddKeyMapData(&kd, pKeyMap->km_LoRepeatable, 8);
+               AddKeyMapData(&kd, pKeyMap->km_HiRepeatable, 8);
+               CopyKeyMapData(&kd, pKeyMap->km_LoKeyMapTypes, pLoKeyMapTypes, pKeyMap->km_LoKeyMap, pLoKeyMap, 0);
+               CopyKeyMapData(&kd, pKeyMap->km_HiKeyMapTypes, pHiKeyMapTypes, pKeyMap->km_HiKeyMap, pHiKeyMap, 0x40);
+               *pnSize = kd.nSize;
+       }
+       return pData;
+}
+
+#endif
+
+xAllocMem
+       move.l 8(sp),d1
+       move.l 4(sp),d0
+       jsr -$c6(a6)
+       rts
+
+GetQualifierCount:
+              MOVEM.L        D6/D7,-(A7)              ;48e7 0300 
+___GetQualifierCount__1:
+              MOVE.B         $f(A7),D7                ;1e2f 000f 
+              MOVEQ.L        #$0,D6                   ;7c00 
+              BTST           #$0,D7                   ;0807 0000 
+              BEQ.B          ___GetQualifierCount__3  ;6702 
+___GetQualifierCount__2:
+              ADDQ.L         #$1,D6                   ;5286 
+___GetQualifierCount__3:
+              BTST           #$1,D7                   ;0807 0001 
+              BEQ.B          ___GetQualifierCount__5  ;6702 
+___GetQualifierCount__4:
+              ADDQ.L         #$1,D6                   ;5286 
+___GetQualifierCount__5:
+              BTST           #$2,D7                   ;0807 0002 
+              BEQ.B          ___GetQualifierCount__7  ;6702 
+___GetQualifierCount__6:
+              ADDQ.L         #$1,D6                   ;5286 
+___GetQualifierCount__7:
+              MOVE.L         D6,D0                    ;2006 
+___GetQualifierCount__8:
+___GetQualifierCount__9:
+              MOVEM.L        (A7)+,D6/D7              ;4cdf 00c0 
+              RTS                                     ;4e75 
+__const:
+__strings:
+ExcludeKey:
+              MOVE.L         D7,-(A7)                 ;2f07 
+___ExcludeKey__1:
+              MOVE.L         $8(A7),D7                ;2e2f 0008 
+              MOVEQ.L        #$40,D0                  ;7040 
+              CMP.L          D0,D7                    ;be80 
+              BLE.B          ___ExcludeKey__9         ;6f28 
+___ExcludeKey__2:
+              MOVEQ.L        #$4a,D0                  ;704a 
+              CMP.L          D0,D7                    ;be80 
+              BEQ.B          ___ExcludeKey__9         ;6722 
+___ExcludeKey__3:
+              MOVEQ.L        #$5a,D0                  ;705a 
+              CMP.L          D0,D7                    ;be80 
+              BEQ.B          ___ExcludeKey__9         ;671c 
+___ExcludeKey__4:
+              MOVEQ.L        #$5b,D0                  ;705b 
+              CMP.L          D0,D7                    ;be80 
+              BEQ.B          ___ExcludeKey__9         ;6716 
+___ExcludeKey__5:
+              MOVEQ.L        #$5c,D0                  ;705c 
+              CMP.L          D0,D7                    ;be80 
+              BEQ.B          ___ExcludeKey__9         ;6710 
+___ExcludeKey__6:
+              MOVEQ.L        #$5d,D0                  ;705d 
+              CMP.L          D0,D7                    ;be80 
+              BEQ.B          ___ExcludeKey__9         ;670a 
+___ExcludeKey__7:
+              MOVEQ.L        #$5e,D0                  ;705e 
+              CMP.L          D0,D7                    ;be80 
+              BEQ.B          ___ExcludeKey__9         ;6704 
+___ExcludeKey__8:
+              MOVEQ.L        #$1,D0                   ;7001 
+              BRA.B          ___ExcludeKey__10        ;6002 
+___ExcludeKey__9:
+              MOVEQ.L        #$0,D0                   ;7000 
+___ExcludeKey__10:
+___ExcludeKey__11:
+___ExcludeKey__12:
+              MOVE.L         (A7)+,D7                 ;2e1f 
+              RTS                                     ;4e75 
+GetKeyMapDataInfo:
+              SUB.W          #$14,A7                  ;9efc 0014 
+              MOVEM.L        D2/D3/D5/D6/D7/A2/A3/A5,-(A7);48e7 3734 
+___GetKeyMapDataInfo__1:
+              MOVE.L         $44(A7),D7               ;2e2f 0044 
+              MOVE.L         $40(A7),A2               ;246f 0040 
+              MOVE.L         $3c(A7),A3               ;266f 003c 
+              MOVE.L         $38(A7),A5               ;2a6f 0038 
+              MOVE.L         D7,D6                    ;2c07 
+              MOVEQ.L        #$3f,D0                  ;703f 
+              ADD.L          D0,D6                    ;dc80 
+              MOVE.L         D7,$24(A7)               ;2f47 0024 
+___GetKeyMapDataInfo__2:
+              MOVE.L         $24(A7),D0               ;202f 0024 
+              CMP.L          D6,D0                    ;b086 
+              BGT.W          ___GetKeyMapDataInfo__33 ;6e00 0104 
+___GetKeyMapDataInfo__3:
+              MOVE.L         D0,-(A7)                 ;2f00 
+              BSR.B          ExcludeKey               ;6196 
+___GetKeyMapDataInfo__4:
+              ADDQ.W         #$4,A7                   ;584f 
+              TST.L          D0                       ;4a80 
+              BNE.W          ___GetKeyMapDataInfo__31 ;6600 00ec 
+___GetKeyMapDataInfo__5:
+___GetKeyMapDataInfo__6:
+              MOVEQ.L        #$0,D0                   ;7000 
+              MOVE.B         (A3),D0                  ;1013 
+              ANDI.W         #$fffffff8,D0            ;0240 fff8 
+___GetKeyMapDataInfo__7:
+              MOVEQ.L        #$20,D1                  ;7220 
+              SUB.L          D1,D0                    ;9081 
+              BEQ.B          ___GetKeyMapDataInfo__16 ;674a 
+___GetKeyMapDataInfo__8:
+              MOVEQ.L        #$20,D1                  ;7220 
+              SUB.L          D1,D0                    ;9081 
+              BNE.W          ___GetKeyMapDataInfo__31 ;6600 00d6 
+___GetKeyMapDataInfo__9:
+___GetKeyMapDataInfo__10:
+              MOVEQ.L        #$0,D0                   ;7000 
+              MOVE.B         (A3),D0                  ;1013 
+              MOVE.L         D0,-(A7)                 ;2f00 
+              BSR.W          GetQualifierCount        ;6100 ff46 
+___GetKeyMapDataInfo__11:
+              ADDQ.W         #$4,A7                   ;584f 
+              MOVEQ.L        #$0,D1                   ;7200 
+              BSET           D0,D1                    ;01c1 
+              MOVE.L         D1,D5                    ;2a01 
+              MOVE.L         D5,D0                    ;2005 
+              ADD.L          D0,D0                    ;d080 
+              ADD.L          D0,$14(A5)               ;d1ad 0014 
+              MOVE.L         (A2),$30(A7)             ;2f52 0030 
+              CLR.L          $20(A7)                  ;42af 0020 
+___GetKeyMapDataInfo__12:
+              MOVE.L         $20(A7),D0               ;202f 0020 
+              CMP.L          D5,D0                    ;b085 
+              BGE.W          ___GetKeyMapDataInfo__31 ;6c00 00aa 
+___GetKeyMapDataInfo__13:
+              MOVEQ.L        #$0,D0                   ;7000 
+              MOVE.L         $30(A7),A0               ;206f 0030 
+              MOVE.B         (A0),D0                  ;1010 
+              ADD.L          D0,$14(A5)               ;d1ad 0014 
+___GetKeyMapDataInfo__14:
+              ADDQ.L         #$1,$20(A7)              ;52af 0020 
+              ADDQ.L         #$2,$30(A7)              ;54af 0030 
+              BRA.B          ___GetKeyMapDataInfo__12 ;60e0 
+___GetKeyMapDataInfo__15:
+___GetKeyMapDataInfo__16:
+              MOVEQ.L        #$0,D0                   ;7000 
+              MOVE.B         (A3),D0                  ;1013 
+              MOVE.L         D0,-(A7)                 ;2f00 
+              BSR.W          GetQualifierCount        ;6100 ff04 
+___GetKeyMapDataInfo__17:
+              ADDQ.W         #$4,A7                   ;584f 
+              MOVEQ.L        #$0,D1                   ;7200 
+              BSET           D0,D1                    ;01c1 
+              MOVE.L         D1,D5                    ;2a01 
+              MOVE.L         D5,D0                    ;2005 
+              ADD.L          D0,D0                    ;d080 
+              ADD.L          D0,$14(A5)               ;d1ad 0014 
+              MOVE.L         (A2),$2c(A7)             ;2f52 002c 
+              CLR.L          $20(A7)                  ;42af 0020 
+___GetKeyMapDataInfo__18:
+              MOVE.L         $20(A7),D0               ;202f 0020 
+              CMP.L          D5,D0                    ;b085 
+              BGE.B          ___GetKeyMapDataInfo__31 ;6c68 
+___GetKeyMapDataInfo__19:
+              MOVE.L         $2c(A7),A0               ;206f 002c 
+              MOVE.B         (A0),D0                  ;1010 
+              MOVEQ.L        #$8,D1                   ;7208 
+              CMP.B          D1,D0                    ;b001 
+              BNE.B          ___GetKeyMapDataInfo__27 ;664a 
+___GetKeyMapDataInfo__20:
+              MOVEQ.L        #$0,D1                   ;7200 
+              MOVE.B         $1(A0),D1                ;1228 0001 
+              MOVE.L         D1,D2                    ;2401 
+              ASR.L          #$4,D2                   ;e882 
+              MOVEQ.L        #$f,D3                   ;760f 
+              AND.L          D3,D2                    ;c483 
+              MOVEM.L        D2,$28(A7)               ;48ef 0004 0028 
+              BEQ.B          ___GetKeyMapDataInfo__24 ;6720 
+___GetKeyMapDataInfo__21:
+              MOVE.L         D2,$8(A5)                ;2b42 0008 
+              MOVEQ.L        #$0,D0                   ;7000 
+              MOVE.B         $1(A0),D0                ;1028 0001 
+              MOVE.L         D0,D1                    ;2200 
+              AND.L          D3,D1                    ;c283 
+              MOVEM.L        D1,$28(A7)               ;48ef 0002 0028 
+              CMP.L          $4(A5),D1                ;b2ad 0004 
+              BLE.B          ___GetKeyMapDataInfo__29 ;6f22 
+___GetKeyMapDataInfo__22:
+              MOVE.L         D1,$4(A5)                ;2b41 0004 
+___GetKeyMapDataInfo__23:
+              BRA.B          ___GetKeyMapDataInfo__29 ;601c 
+___GetKeyMapDataInfo__24:
+              MOVEQ.L        #$0,D2                   ;7400 
+              MOVE.B         D1,D2                    ;1401 
+              AND.L          D3,D2                    ;c483 
+              MOVEM.L        D2,$28(A7)               ;48ef 0004 0028 
+              CMP.L          (A5),D2                  ;b495 
+              BLE.B          ___GetKeyMapDataInfo__29 ;6f0c 
+___GetKeyMapDataInfo__25:
+              MOVE.L         D2,(A5)                  ;2a82 
+___GetKeyMapDataInfo__26:
+              BRA.B          ___GetKeyMapDataInfo__29 ;6008 
+___GetKeyMapDataInfo__27:
+              SUBQ.B         #$1,D0                   ;5300 
+              BNE.B          ___GetKeyMapDataInfo__29 ;6604 
+___GetKeyMapDataInfo__28:
+              ADDQ.L         #$1,$c(A5)               ;52ad 000c 
+___GetKeyMapDataInfo__29:
+              ADDQ.L         #$1,$20(A7)              ;52af 0020 
+              ADDQ.L         #$2,$2c(A7)              ;54af 002c 
+              BRA.B          ___GetKeyMapDataInfo__18 ;6090 
+___GetKeyMapDataInfo__30:
+___GetKeyMapDataInfo__31:
+              ADDQ.L         #$1,$24(A7)              ;52af 0024 
+              ADDQ.L         #$1,A3                   ;528b 
+              ADDQ.L         #$4,A2                   ;588a 
+              BRA.W          ___GetKeyMapDataInfo__2  ;6000 fef6 
+___GetKeyMapDataInfo__32:
+___GetKeyMapDataInfo__33:
+              MOVEM.L        (A7)+,D2/D3/D5/D6/D7/A2/A3/A5;4cdf 2cec 
+              ADD.W          #$14,A7                  ;defc 0014 
+              RTS                                     ;4e75 
+AddKeyMapData:
+              MOVEM.L        D7/A2/A3/A5,-(A7)        ;48e7 0134 
+___AddKeyMapData__1:
+              MOVE.L         $1c(A7),D7               ;2e2f 001c 
+              MOVE.L         $18(A7),A3               ;266f 0018 
+              MOVE.L         $14(A7),A5               ;2a6f 0014 
+              MOVE.L         $18(A5),A2               ;246d 0018 
+              MOVE.L         A3,A0                    ;204b 
+              MOVE.L         $18(A5),A1               ;226d 0018 
+              MOVE.L         D7,D0                    ;2007 
+              BRA.B          ___AddKeyMapData__3      ;6002 
+___AddKeyMapData__2:
+              MOVE.B         (A0)+,(A1)+              ;12d8 
+___AddKeyMapData__3:
+              SUBQ.L         #$1,D0                   ;5380 
+              BCC.B          ___AddKeyMapData__2      ;64fa 
+___AddKeyMapData__4:
+              MOVE.L         $18(A5),A0               ;206d 0018 
+              ADD.L          D7,A0                    ;d1c7 
+              MOVE.L         A0,$18(A5)               ;2b48 0018 
+              ADD.L          D7,$1c(A5)               ;dfad 001c 
+              MOVE.L         A2,D0                    ;200a 
+___AddKeyMapData__5:
+___AddKeyMapData__6:
+              MOVEM.L        (A7)+,D7/A2/A3/A5        ;4cdf 2c80 
+              RTS                                     ;4e75 
+CopyKeyMapData:
+              SUB.W          #$1c,A7                  ;9efc 001c 
+              MOVEM.L        D5/D6/D7/A2/A3/A5,-(A7)  ;48e7 0734 
+___CopyKeyMapData__1:
+              MOVE.L         $4c(A7),D7               ;2e2f 004c 
+              MOVE.L         $40(A7),A2               ;246f 0040 
+              MOVE.L         $3c(A7),A3               ;266f 003c 
+              MOVE.L         $38(A7),A5               ;2a6f 0038 
+              MOVE.L         D7,D6                    ;2c07 
+              MOVEQ.L        #$3f,D0                  ;703f 
+              ADD.L          D0,D6                    ;dc80 
+              MOVE.L         D7,$20(A7)               ;2f47 0020 
+___CopyKeyMapData__2:
+              MOVE.L         $20(A7),D0               ;202f 0020 
+              CMP.L          D6,D0                    ;b086 
+              BGT.W          ___CopyKeyMapData__32    ;6e00 0198 
+___CopyKeyMapData__3:
+              MOVE.L         D0,-(A7)                 ;2f00 
+              BSR.W          ExcludeKey               ;6100 fe24 
+___CopyKeyMapData__4:
+              ADDQ.W         #$4,A7                   ;584f 
+              TST.L          D0                       ;4a80 
+              BEQ.B          ___CopyKeyMapData__6     ;6706 
+___CopyKeyMapData__5:
+              MOVEQ.L        #$40,D0                  ;7040 
+              ADD.L          D0,D0                    ;d080 
+              BRA.B          ___CopyKeyMapData__7     ;6004 
+___CopyKeyMapData__6:
+              MOVEQ.L        #$0,D0                   ;7000 
+              MOVE.B         (A3),D0                  ;1013 
+___CopyKeyMapData__7:
+              MOVEQ.L        #$0,D1                   ;7200 
+              MOVE.B         D0,D1                    ;1200 
+              ANDI.W         #$fffffff8,D1            ;0241 fff8 
+              MOVE.B         D0,$1a(A7)               ;1f40 001a 
+___CopyKeyMapData__8:
+              MOVEQ.L        #$20,D0                  ;7020 
+              SUB.L          D0,D1                    ;9280 
+              BEQ.W          ___CopyKeyMapData__19    ;6700 00a6 
+___CopyKeyMapData__9:
+              MOVEQ.L        #$20,D0                  ;7020 
+              SUB.L          D0,D1                    ;9280 
+              BNE.W          ___CopyKeyMapData__29    ;6600 014e 
+___CopyKeyMapData__10:
+___CopyKeyMapData__11:
+              MOVEQ.L        #$0,D0                   ;7000 
+              MOVE.B         (A3),D0                  ;1013 
+              MOVE.L         D0,-(A7)                 ;2f00 
+              BSR.W          GetQualifierCount        ;6100 fdc4 
+___CopyKeyMapData__12:
+              MOVEQ.L        #$0,D1                   ;7200 
+              BSET           D0,D1                    ;01c1 
+              MOVE.L         D1,D5                    ;2a01 
+              MOVE.L         $48(A7),A1               ;226f 0048 
+              MOVE.L         (A1),A0                  ;2051 
+              MOVE.L         $4c(A7),A1               ;226f 004c 
+              MOVE.L         $1c(A5),(A1)             ;22ad 001c 
+              MOVE.L         D5,D0                    ;2005 
+              ADD.L          D0,D0                    ;d080 
+              MOVE.L         D0,(A7)                  ;2e80 
+              MOVE.L         A0,-(A7)                 ;2f08 
+              MOVE.L         A5,-(A7)                 ;2f0d 
+              MOVE.L         A0,$3c(A7)               ;2f48 003c 
+              BSR.W          AddKeyMapData            ;6100 ff3a 
+___CopyKeyMapData__13:
+              LEA            $c(A7),A7                ;4fef 000c 
+              MOVE.L         D5,D1                    ;2205 
+              ADD.L          D1,D1                    ;d281 
+              CLR.L          $1c(A7)                  ;42af 001c 
+              MOVE.L         D0,$28(A7)               ;2f40 0028 
+              MOVE.B         D1,$1b(A7)               ;1f41 001b 
+___CopyKeyMapData__14:
+              MOVE.L         $1c(A7),D0               ;202f 001c 
+              CMP.L          D5,D0                    ;b085 
+              BGE.W          ___CopyKeyMapData__30    ;6c00 0104 
+___CopyKeyMapData__15:
+              MOVE.L         $30(A7),A0               ;206f 0030 
+              MOVE.B         (A0),D0                  ;1010 
+              MOVE.L         $28(A7),A0               ;206f 0028 
+              MOVE.B         D0,(A0)                  ;1080 
+              MOVE.B         $1b(A7),$1(A0)           ;116f 001b 0001 
+              MOVE.L         $44(A7),A1               ;226f 0044 
+              MOVE.L         (A1),A0                  ;2051 
+              MOVEQ.L        #$0,D0                   ;7000 
+              MOVE.L         $30(A7),A1               ;226f 0030 
+              MOVE.B         $1(A1),D0                ;1029 0001 
+              ADD.W          D0,A0                    ;d0c0 
+              MOVEQ.L        #$0,D0                   ;7000 
+              MOVE.B         (A1),D0                  ;1011 
+              MOVE.L         D0,-(A7)                 ;2f00 
+              MOVE.L         A0,-(A7)                 ;2f08 
+              MOVE.L         A5,-(A7)                 ;2f0d 
+              BSR.W          AddKeyMapData            ;6100 feea 
+___CopyKeyMapData__16:
+              LEA            $c(A7),A7                ;4fef 000c 
+              MOVE.L         $30(A7),A0               ;206f 0030 
+              MOVE.B         (A0),D0                  ;1010 
+              ADD.B          D0,$1b(A7)               ;d12f 001b 
+___CopyKeyMapData__17:
+              ADDQ.L         #$1,$1c(A7)              ;52af 001c 
+              ADDQ.L         #$2,$30(A7)              ;54af 0030 
+              ADDQ.L         #$2,$28(A7)              ;54af 0028 
+              BRA.B          ___CopyKeyMapData__14    ;60a8 
+___CopyKeyMapData__18:
+___CopyKeyMapData__19:
+              MOVEQ.L        #$0,D0                   ;7000 
+              MOVE.B         (A3),D0                  ;1013 
+              MOVE.L         D0,-(A7)                 ;2f00 
+              BSR.W          GetQualifierCount        ;6100 fd28 
+___CopyKeyMapData__20:
+              MOVEQ.L        #$0,D1                   ;7200 
+              BSET           D0,D1                    ;01c1 
+              MOVE.L         D1,D5                    ;2a01 
+              MOVE.L         $48(A7),A1               ;226f 0048 
+              MOVE.L         (A1),A0                  ;2051 
+              MOVE.L         $4c(A7),A1               ;226f 004c 
+              MOVE.L         $1c(A5),(A1)             ;22ad 001c 
+              MOVE.L         D5,D0                    ;2005 
+              ADD.L          D0,D0                    ;d080 
+              MOVE.L         D0,(A7)                  ;2e80 
+              MOVE.L         A0,-(A7)                 ;2f08 
+              MOVE.L         A5,-(A7)                 ;2f0d 
+              MOVE.L         A0,$38(A7)               ;2f48 0038 
+              BSR.W          AddKeyMapData            ;6100 fe9e 
+___CopyKeyMapData__21:
+              LEA            $c(A7),A7                ;4fef 000c 
+              MOVE.L         D5,D1                    ;2205 
+              ADD.L          D1,D1                    ;d281 
+              CLR.L          $1c(A7)                  ;42af 001c 
+              MOVE.L         D0,$24(A7)               ;2f40 0024 
+              MOVE.B         D1,$1b(A7)               ;1f41 001b 
+___CopyKeyMapData__22:
+              MOVE.L         $1c(A7),D0               ;202f 001c 
+              CMP.L          D5,D0                    ;b085 
+              BGE.B          ___CopyKeyMapData__30    ;6c68 
+___CopyKeyMapData__23:
+              MOVE.L         $2c(A7),A0               ;206f 002c 
+              MOVE.B         (A0),D0                  ;1010 
+              MOVE.L         $24(A7),A0               ;206f 0024 
+              MOVE.B         D0,(A0)                  ;1080 
+              MOVEQ.L        #$1,D0                   ;7001 
+              MOVE.L         $2c(A7),A0               ;206f 002c 
+              CMP.B          (A0),D0                  ;b010 
+              BNE.B          ___CopyKeyMapData__26    ;6636 
+___CopyKeyMapData__24:
+              MOVE.L         $24(A7),A0               ;206f 0024 
+              MOVE.B         $1b(A7),$1(A0)           ;116f 001b 0001 
+              MOVE.L         $44(A7),A1               ;226f 0044 
+              MOVE.L         (A1),A0                  ;2051 
+              MOVEQ.L        #$0,D0                   ;7000 
+              MOVE.L         $2c(A7),A1               ;226f 002c 
+              MOVE.B         $1(A1),D0                ;1029 0001 
+              ADD.W          D0,A0                    ;d0c0 
+              MOVE.L         $10(A5),-(A7)            ;2f2d 0010 
+              MOVE.L         A0,-(A7)                 ;2f08 
+              MOVE.L         A5,-(A7)                 ;2f0d 
+              BSR.W          AddKeyMapData            ;6100 fe44 
+___CopyKeyMapData__25:
+              LEA            $c(A7),A7                ;4fef 000c 
+              MOVE.L         $10(A5),D0               ;202d 0010 
+              ADD.B          D0,$1b(A7)               ;d12f 001b 
+              BRA.B          ___CopyKeyMapData__27    ;600a 
+___CopyKeyMapData__26:
+              MOVE.L         $24(A7),A1               ;226f 0024 
+              MOVE.B         $1(A0),$1(A1)            ;1368 0001 0001 
+___CopyKeyMapData__27:
+              ADDQ.L         #$1,$1c(A7)              ;52af 001c 
+              ADDQ.L         #$2,$2c(A7)              ;54af 002c 
+              ADDQ.L         #$2,$24(A7)              ;54af 0024 
+              BRA.B          ___CopyKeyMapData__22    ;6094 
+___CopyKeyMapData__28:
+___CopyKeyMapData__29:
+              MOVE.B         #$80,(A2)                ;14bc 0080 
+___CopyKeyMapData__30:
+              ADDQ.L         #$1,$20(A7)              ;52af 0020 
+              ADDQ.L         #$1,A3                   ;528b 
+              ADDQ.L         #$1,A2                   ;528a 
+              ADDQ.L         #$4,$44(A7)              ;58af 0044 
+              ADDQ.L         #$4,$48(A7)              ;58af 0048 
+              BRA.W          ___CopyKeyMapData__2     ;6000 fe62 
+___CopyKeyMapData__31:
+___CopyKeyMapData__32:
+              MOVEM.L        (A7)+,D5/D6/D7/A2/A3/A5  ;4cdf 2ce0 
+              ADD.W          #$1c,A7                  ;defc 001c 
+              RTS                                     ;4e75 
+GetKeyMapData:
+              SUB.W          #$34,A7                  ;9efc 0034 
+              MOVEM.L        D2/A2/A3/A5,-(A7)        ;48e7 2034 
+___GetKeyMapData__1:
+              MOVE.L         $4c(A7),A3               ;266f 004c 
+              MOVE.L         $48(A7),A5               ;2a6f 0048 
+              MOVE.L         A5,D0                    ;200d 
+              BEQ.B          ___GetKeyMapData__3      ;6704 
+___GetKeyMapData__2:
+              MOVE.L         A3,D0                    ;200b 
+              BNE.B          ___GetKeyMapData__4      ;6606 
+___GetKeyMapData__3:
+              MOVEQ.L        #$0,D0                   ;7000 
+              BRA.W          ___GetKeyMapData__37     ;6000 01a8 
+___GetKeyMapData__4:
+              TST.L          (A5)                     ;4a95 
+              BEQ.B          ___GetKeyMapData__12     ;672a 
+___GetKeyMapData__5:
+              TST.L          $10(A5)                  ;4aad 0010 
+              BEQ.B          ___GetKeyMapData__12     ;6724 
+___GetKeyMapData__6:
+              TST.L          $4(A5)                   ;4aad 0004 
+              BEQ.B          ___GetKeyMapData__12     ;671e 
+___GetKeyMapData__7:
+              TST.L          $14(A5)                  ;4aad 0014 
+              BEQ.B          ___GetKeyMapData__12     ;6718 
+___GetKeyMapData__8:
+              TST.L          $8(A5)                   ;4aad 0008 
+              BEQ.B          ___GetKeyMapData__12     ;6712 
+___GetKeyMapData__9:
+              TST.L          $18(A5)                  ;4aad 0018 
+              BEQ.B          ___GetKeyMapData__12     ;670c 
+___GetKeyMapData__10:
+              TST.L          $c(A5)                   ;4aad 000c 
+              BEQ.B          ___GetKeyMapData__12     ;6706 
+___GetKeyMapData__11:
+              TST.L          $1c(A5)                  ;4aad 001c 
+              BNE.B          ___GetKeyMapData__13     ;6606 
+___GetKeyMapData__12:
+              MOVEQ.L        #$0,D0                   ;7000 
+              BRA.W          ___GetKeyMapData__37     ;6000 0174 
+___GetKeyMapData__13:
+              MOVEQ.L        #$0,D0                   ;7000 
+              LEA            $24(A7),A0               ;41ef 0024 
+              MOVEQ.L        #$1f,D1                  ;721f 
+___GetKeyMapData__14:
+              MOVE.B         D0,(A0)+                 ;10c0 
+              DBRA.B         D1,___GetKeyMapData__14  ;51c9 fffc 
+___GetKeyMapData__15:
+              MOVE.L         #$2a2,$38(A7)            ;2f7c 0000 02a2 0038 
+              MOVE.L         D0,-(A7)                 ;2f00 
+              MOVE.L         $4(A5),-(A7)             ;2f2d 0004 
+              MOVE.L         (A5),-(A7)               ;2f15 
+              PEA            $30(A7)                  ;486f 0030 
+              BSR.W          GetKeyMapDataInfo        ;6100 fc4c 
+___GetKeyMapData__16:
+              PEA            ($40).w                  ;4878 0040 
+              MOVE.L         $14(A5),-(A7)            ;2f2d 0014 
+              MOVE.L         $10(A5),-(A7)            ;2f2d 0010 
+              PEA            $40(A7)                  ;486f 0040 
+              BSR.W          GetKeyMapDataInfo        ;6100 fc38 
+___GetKeyMapData__17:
+              LEA            $20(A7),A7               ;4fef 0020 
+              MOVE.L         $30(A7),D0               ;202f 0030 
+              BEQ.B          ___GetKeyMapData__22     ;672a 
+___GetKeyMapData__18:
+              MOVE.L         $2c(A7),D1               ;222f 002c 
+              BEQ.B          ___GetKeyMapData__20     ;670e 
+___GetKeyMapData__19:
+              MOVE.L         $28(A7),D2               ;242f 0028 
+              ADDQ.L         #$1,D2                   ;5282 
+              MOVE.L         D2,D0                    ;2002 
+              BSR.W          _CXM33                   ;6100 0000 
+              BRA.B          ___GetKeyMapData__21     ;6006 
+___GetKeyMapData__20:
+              MOVE.L         $24(A7),D0               ;202f 0024 
+              ADDQ.L         #$1,D0                   ;5280 
+___GetKeyMapData__21:
+              MOVE.L         D0,$34(A7)               ;2f40 0034 
+              MOVE.L         $30(A7),D1               ;222f 0030 
+              BSR.W          _CXM33                   ;6100 0000 
+              ADD.L          D0,$38(A7)               ;d1af 0038 
+___GetKeyMapData__22:
+              CLR.L          -(A7)                    ;42a7 
+              MOVE.L         $3c(A7),-(A7)            ;2f2f 003c 
+              BSR.W          xAllocMem                ;6100 0000 
+              ADDQ.W         #$8,A7                   ;504f 
+              MOVE.L         D0,$14(A7)               ;2f40 0014 
+              BEQ.W          ___GetKeyMapData__35     ;6700 00ee 
+___GetKeyMapData__23:
+              MOVE.L         D0,$3c(A7)               ;2f40 003c 
+              MOVE.B         #$1,$12(A7)              ;1f7c 0001 0012 
+              MOVE.L         $34(A7),D0               ;202f 0034 
+              MOVE.B         D0,$13(A7)               ;1f40 0013 
+              PEA            ($2).w                   ;4878 0002 
+              PEA            $16(A7)                  ;486f 0016 
+              PEA            $2c(A7)                  ;486f 002c 
+              BSR.W          AddKeyMapData            ;6100 fd06 
+___GetKeyMapData__24:
+              PEA            ($40).w                  ;4878 0040 
+              MOVE.L         (A5),-(A7)               ;2f15 
+              PEA            $38(A7)                  ;486f 0038 
+              BSR.W          AddKeyMapData            ;6100 fcf8 
+___GetKeyMapData__25:
+              PEA            ($40).w                  ;4878 0040 
+              MOVE.L         $10(A5),-(A7)            ;2f2d 0010 
+              PEA            $44(A7)                  ;486f 0044 
+              MOVE.L         D0,$40(A7)               ;2f40 0040 
+              BSR.W          AddKeyMapData            ;6100 fce4 
+___GetKeyMapData__26:
+              PEA            ($100).w                 ;4878 0100 
+              MOVE.L         $4(A5),-(A7)             ;2f2d 0004 
+              PEA            $50(A7)                  ;486f 0050 
+              MOVE.L         D0,$48(A7)               ;2f40 0048 
+              BSR.W          AddKeyMapData            ;6100 fcd0 
+___GetKeyMapData__27:
+              MOVE.L         D0,A2                    ;2440 
+              PEA            ($100).w                 ;4878 0100 
+              MOVE.L         $14(A5),-(A7)            ;2f2d 0014 
+              PEA            $5c(A7)                  ;486f 005c 
+              BSR.W          AddKeyMapData            ;6100 fcbe 
+___GetKeyMapData__28:
+              PEA            ($8).w                   ;4878 0008 
+              MOVE.L         $8(A5),-(A7)             ;2f2d 0008 
+              PEA            $68(A7)                  ;486f 0068 
+              MOVE.L         D0,$68(A7)               ;2f40 0068 
+              BSR.W          AddKeyMapData            ;6100 fcaa 
+___GetKeyMapData__29:
+              LEA            $48(A7),A7               ;4fef 0048 
+              PEA            ($8).w                   ;4878 0008 
+              MOVE.L         $18(A5),-(A7)            ;2f2d 0018 
+              PEA            $2c(A7)                  ;486f 002c 
+              BSR.W          AddKeyMapData            ;6100 fc96 
+___GetKeyMapData__30:
+              PEA            ($8).w                   ;4878 0008 
+              MOVE.L         $c(A5),-(A7)             ;2f2d 000c 
+              PEA            $38(A7)                  ;486f 0038 
+              BSR.W          AddKeyMapData            ;6100 fc86 
+___GetKeyMapData__31:
+              PEA            ($8).w                   ;4878 0008 
+              MOVE.L         $1c(A5),-(A7)            ;2f2d 001c 
+              PEA            $44(A7)                  ;486f 0044 
+              BSR.W          AddKeyMapData            ;6100 fc76 
+___GetKeyMapData__32:
+              CLR.L          (A7)                     ;4297 
+              MOVE.L         A2,-(A7)                 ;2f0a 
+              MOVE.L         $4(A5),-(A7)             ;2f2d 0004 
+              MOVE.L         $48(A7),-(A7)            ;2f2f 0048 
+              MOVE.L         (A5),-(A7)               ;2f15 
+              PEA            $58(A7)                  ;486f 0058 
+              BSR.W          CopyKeyMapData           ;6100 fc9a 
+___GetKeyMapData__33:
+              PEA            ($40).w                  ;4878 0040 
+              MOVE.L         $5c(A7),-(A7)            ;2f2f 005c 
+              MOVE.L         $14(A5),-(A7)            ;2f2d 0014 
+              MOVE.L         $5c(A7),-(A7)            ;2f2f 005c 
+              MOVE.L         $10(A5),-(A7)            ;2f2d 0010 
+              PEA            $70(A7)                  ;486f 0070 
+              BSR.W          CopyKeyMapData           ;6100 fc7e 
+___GetKeyMapData__34:
+              LEA            $50(A7),A7               ;4fef 0050 
+              MOVE.L         $38(A7),(A3)             ;26af 0038 
+___GetKeyMapData__35:
+              MOVE.L         $14(A7),D0               ;202f 0014 
+___GetKeyMapData__36:
+___GetKeyMapData__37:
+              MOVEM.L        (A7)+,D2/A2/A3/A5        ;4cdf 2c04 
+              ADD.W          #$34,A7                  ;defc 0034 
+              RTS                                     ;4e75 
index 5adf2656dbcfa01a7c84d7dfe86954a44d5fcb08..4791bcd8a90a25af4628c7b7cd2d672e6fd550b2 100644 (file)
--- a/gayle.cpp
+++ b/gayle.cpp
@@ -32,6 +32,7 @@
 #include "idecontrollers.h"
 #include "pci_hw.h"
 #include "debug.h"
+#include "autoconf.h"
 
 #define PCMCIA_SRAM 1
 #define PCMCIA_IDE 2
@@ -591,7 +592,7 @@ static bool isdataflyerscsiplus(uaecptr addr, uae_u32 *v, int size)
 
 static bool isa4000t (uaecptr *paddr)
 {
-       if (currprefs.cs_mbdmac != 2)
+       if (!is_a4000t_scsi())
                return false;
        uaecptr addr = *paddr;
        if ((addr & 0xffff) >= (GAYLE_BASE_4000 & 0xffff))
@@ -607,7 +608,7 @@ static uae_u32 REGPARAM2 gayle_lget (uaecptr addr)
        int ide_reg;
        uae_u32 v;
 #ifdef NCR
-       if (currprefs.cs_mbdmac == 2 && (addr & 0xffff) == 0x3000)
+       if (is_a4000t_scsi() && (addr & 0xffff) == 0x3000)
                return 0xffffffff; // NCR DIP BANK
        if (isdataflyerscsiplus(addr, &v, 4)) {
                return v;
@@ -643,7 +644,7 @@ static uae_u32 REGPARAM2 gayle_wget (uaecptr addr)
        int ide_reg;
        uae_u32 v;
 #ifdef NCR
-       if (currprefs.cs_mbdmac == 2 && (addr & (0xffff - 1)) == 0x3000)
+       if (is_a4000t_scsi() && (addr & (0xffff - 1)) == 0x3000)
                return 0xffff; // NCR DIP BANK
        if (isdataflyerscsiplus(addr, &v, 2)) {
                return v;
@@ -671,7 +672,7 @@ static uae_u32 REGPARAM2 gayle_bget (uaecptr addr)
 {
        uae_u32 v;
 #ifdef NCR
-       if (currprefs.cs_mbdmac == 2 && (addr & (0xffff - 3)) == 0x3000)
+       if (is_a4000t_scsi() && (addr & (0xffff - 3)) == 0x3000)
                return 0xff; // NCR DIP BANK
        if (isdataflyerscsiplus(addr, &v, 1)) {
                return v;
@@ -1717,11 +1718,11 @@ void gayle_map_pcmcia (void)
                return;
        if (pcmcia_card == 0 || (gayle_cs & GAYLE_CS_DIS)) {
                map_banks_cond (&dummy_bank, 0xa0, 8, 0);
-               if (currprefs.chipmem_size <= 4 * 1024 * 1024 && getz2endaddr () <= 4 * 1024 * 1024)
+               if (currprefs.chipmem_size <= 4 * 1024 * 1024 && !expansion_get_autoconfig_by_address(&currprefs, 4 * 1024 * 1024))
                        map_banks_cond (&dummy_bank, PCMCIA_COMMON_START >> 16, PCMCIA_COMMON_SIZE >> 16, 0);
        } else {
                map_banks_cond (&gayle_attr_bank, 0xa0, 8, 0);
-               if (currprefs.chipmem_size <= 4 * 1024 * 1024 && getz2endaddr () <= 4 * 1024 * 1024)
+               if (currprefs.chipmem_size <= 4 * 1024 * 1024 && !expansion_get_autoconfig_by_address(&currprefs, 4 * 1024 * 1024))
                        map_banks_cond (&gayle_common_bank, PCMCIA_COMMON_START >> 16, PCMCIA_COMMON_SIZE >> 16, 0);
        }
 }
@@ -1754,20 +1755,29 @@ static void dumphdf (struct hardfiledata *hfd)
 }
 #endif
 
-int gayle_add_ide_unit (int ch, struct uaedev_config_info *ci)
+void gayle_add_ide_unit (int ch, struct uaedev_config_info *ci, struct romconfig *rc)
 {
        struct ide_hdf *ide;
 
        if (ch >= 2 * 2)
-               return -1;
+               return;
        ide = add_ide_unit (idedrive, TOTAL_IDE * 2, ch, ci, NULL);
-       if (ide == NULL)
-               return 0;
-       //dumphdf (&ide->hdhfd.hfd);
-       return 1;
 }
 
-int gayle_ne2000_unit(int insert)
+bool gayle_ide_init(struct autoconfig_info *aci)
+{
+       aci->addrbank = &expamem_nonautoconfig;
+       if (aci->prefs->cs_ide == 1) {
+               aci->start = GAYLE_BASE_1200;
+               aci->size = 0x10000;
+       } else {
+               aci->start = GAYLE_BASE_4000;
+               aci->size = 0x1000;
+       }
+       return true;
+}
+
+static int gayle_ne2000_unit(int insert)
 {
        if (insert)
                return initpcmcia(NULL, 0, PCMCIA_NE2000, 1, NULL);
@@ -1775,6 +1785,15 @@ int gayle_ne2000_unit(int insert)
                return freepcmcia(0);
 }
 
+bool gayle_init_ne2000_pcmcia(struct autoconfig_info *aci)
+{
+       aci->start = 0xa00000;
+       aci->size = 0x1000;
+       aci->addrbank = &expamem_nonautoconfig;
+       aci->parent_address_space = true;
+       return true;
+}
+
 int gayle_add_pcmcia_sram_unit (struct uaedev_config_info *uci)
 {
        return initpcmcia (uci->rootdir, uci->readonly, PCMCIA_SRAM, 1, NULL);
@@ -1801,6 +1820,18 @@ int gayle_modify_pcmcia_ide_unit (struct uaedev_config_info *uci, int insert)
                return freepcmcia (0);
 }
 
+void gayle_add_pcmcia_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
+{
+}
+bool gayle_pcmcia_init(struct autoconfig_info *aci)
+{
+       aci->start = 0x600000;
+       aci->size = 0xa80000 - aci->start;
+       aci->addrbank = &expamem_nonautoconfig;
+       return true;
+}
+
+
 static void initide (void)
 {
        gayle_its.idetable = idedrive;
@@ -1840,7 +1871,7 @@ void gayle_reset (int hardreset)
        if (currprefs.cs_ide == IDE_A4000)
                _tcscpy (bankname, _T("A4000 IDE"));
 #ifdef NCR
-       if (currprefs.cs_mbdmac == 2) {
+       if (is_a4000t_scsi()) {
                _tcscat (bankname, _T(" + NCR53C710 SCSI"));
                ncr_init();
                ncr_reset();
@@ -1930,9 +1961,9 @@ uae_u8 *restore_gayle_ide (uae_u8 *src)
        readonly = restore_u32 ();
        src = ide_restore_state(src, ide);
        if (ide->hdhfd.hfd.virtual_size)
-               gayle_add_ide_unit (num, NULL);
+               gayle_add_ide_unit (num, NULL, NULL);
        else
-               gayle_add_ide_unit (num, NULL);
+               gayle_add_ide_unit (num, NULL, NULL);
        xfree (path);
        return src;
 }
index 0a5aab50f6a964900d92d778c2c3ce5ed02c4b6c..0141f94e402924c82c5fb90b94262fbc343690fb 100644 (file)
 #define MEMLOGR 0
 #define MEMLOGW 0
 #define MEMLOGINDIRECT 0
+#define REGDEBUG 0
 #define MEMDEBUG 0
 #define MEMDEBUGMASK 0x7fffff
 #define MEMDEBUGTEST 0x1ff000
 #define PICASSOIV_DEBUG_IO 0
 
 #if MEMLOGR
-static bool memlogr = false;
-static bool memlogw = false;
+static bool memlogr = true;
+static bool memlogw = true;
 #endif
 
 #define BYTESWAP_WORD -1
@@ -177,6 +178,7 @@ static const struct gfxboard boards[] =
 
 struct rtggfxboard
 {
+       bool active;
        int rtg_index;
        struct rtgboardconfig *rbc;
        TCHAR memorybankname[40];
@@ -189,6 +191,8 @@ struct rtggfxboard
        uae_u8 expamem_lo;
        uae_u8 *automemory;
        uae_u32 banksize_mask;
+       uaecptr io_start, io_end;
+       uaecptr mem_start[2], mem_end[2];
 
        uae_u8 picassoiv_bank, picassoiv_flifi;
        uae_u8 p4autoconfig[256];
@@ -199,7 +203,7 @@ struct rtggfxboard
        uae_u32 p4_vram_bank[2];
 
        CirrusVGAState vga;
-       uae_u8 *vram, *vramrealstart;
+       uae_u8 *vram, *vramend, *vramrealstart;
        int vram_start_offset;
        uae_u32 gfxboardmem_start;
        bool monswitch_current, monswitch_new;
@@ -222,9 +226,25 @@ struct rtggfxboard
 
        const MemoryRegionOps *vgaio, *vgaram, *vgalowram, *vgammio;
        MemoryRegion vgaioregion, vgavramregion;
+       DisplaySurface gfxsurface, fakesurface;
+
+       addrbank gfxboard_bank_memory;
+       addrbank gfxboard_bank_memory_nojit;
+       addrbank gfxboard_bank_wbsmemory;
+       addrbank gfxboard_bank_lbsmemory;
+       addrbank gfxboard_bank_nbsmemory;
+       addrbank gfxboard_bank_registers;
+       addrbank gfxboard_bank_special;
+
+       addrbank *gfxmem_bank;
+       uae_u8 *vram_back;
 };
 
-static struct rtggfxboard rtggfxboards[1];
+static struct rtggfxboard rtggfxboards[MAX_RTG_BOARDS];
+static int rtg_visible = -1;
+static int total_active_gfx_boards;
+static int vram_ram_a8;
+static DisplaySurface fakesurface;
 
 DECLARE_MEMORY_FUNCTIONS(gfxboard);
 DECLARE_MEMORY_FUNCTIONS_WITH_SUFFIX(gfxboard, mem);
@@ -236,7 +256,7 @@ DECLARE_MEMORY_FUNCTIONS_WITH_SUFFIX(gfxboard, nbsmem);
 DECLARE_MEMORY_FUNCTIONS_WITH_SUFFIX(gfxboard, regs);
 DECLARE_MEMORY_FUNCTIONS_WITH_SUFFIX(gfxboards, regs);
 
-static addrbank gfxboard_bank_memory = {
+static const addrbank tmpl_gfxboard_bank_memory = {
        gfxboard_lget_mem, gfxboard_wget_mem, gfxboard_bget_mem,
        gfxboard_lput_mem, gfxboard_wput_mem, gfxboard_bput_mem,
        gfxboard_xlate, gfxboard_check, NULL, NULL, NULL,
@@ -244,7 +264,7 @@ static addrbank gfxboard_bank_memory = {
        ABFLAG_RAM | ABFLAG_THREADSAFE, 0, 0
 };
 
-static addrbank gfxboard_bank_memory_nojit = {
+static const addrbank tmpl_gfxboard_bank_memory_nojit = {
        gfxboard_lget_mem_nojit, gfxboard_wget_mem_nojit, gfxboard_bget_mem_nojit,
        gfxboard_lput_mem_nojit, gfxboard_wput_mem_nojit, gfxboard_bput_mem_nojit,
        gfxboard_xlate, gfxboard_check, NULL, NULL, NULL,
@@ -252,7 +272,7 @@ static addrbank gfxboard_bank_memory_nojit = {
        ABFLAG_RAM | ABFLAG_THREADSAFE, S_READ, S_WRITE
 };
 
-static addrbank gfxboard_bank_wbsmemory = {
+static const addrbank tmpl_gfxboard_bank_wbsmemory = {
        gfxboard_lget_wbsmem, gfxboard_wget_wbsmem, gfxboard_bget_wbsmem,
        gfxboard_lput_wbsmem, gfxboard_wput_wbsmem, gfxboard_bput_wbsmem,
        gfxboard_xlate, gfxboard_check, NULL, NULL, NULL,
@@ -260,7 +280,7 @@ static addrbank gfxboard_bank_wbsmemory = {
        ABFLAG_RAM | ABFLAG_THREADSAFE, S_READ, S_WRITE
 };
 
-static addrbank gfxboard_bank_lbsmemory = {
+static const addrbank tmpl_gfxboard_bank_lbsmemory = {
        gfxboard_lget_lbsmem, gfxboard_wget_lbsmem, gfxboard_bget_lbsmem,
        gfxboard_lput_lbsmem, gfxboard_wput_lbsmem, gfxboard_bput_lbsmem,
        gfxboard_xlate, gfxboard_check, NULL, NULL, NULL,
@@ -268,7 +288,7 @@ static addrbank gfxboard_bank_lbsmemory = {
        ABFLAG_RAM | ABFLAG_THREADSAFE, S_READ, S_WRITE
 };
 
-static addrbank gfxboard_bank_nbsmemory = {
+static const addrbank tmpl_gfxboard_bank_nbsmemory = {
        gfxboard_lget_nbsmem, gfxboard_wget_nbsmem, gfxboard_bget_bsmem,
        gfxboard_lput_nbsmem, gfxboard_wput_nbsmem, gfxboard_bput_bsmem,
        gfxboard_xlate, gfxboard_check, NULL, NULL, _T("Picasso IV banked VRAM"),
@@ -276,7 +296,7 @@ static addrbank gfxboard_bank_nbsmemory = {
        ABFLAG_RAM | ABFLAG_THREADSAFE, S_READ, S_WRITE
 };
 
-static addrbank gfxboard_bank_registers = {
+static const addrbank tmpl_gfxboard_bank_registers = {
        gfxboard_lget_regs, gfxboard_wget_regs, gfxboard_bget_regs,
        gfxboard_lput_regs, gfxboard_wput_regs, gfxboard_bput_regs,
        default_xlate, default_check, NULL, NULL, NULL,
@@ -284,7 +304,7 @@ static addrbank gfxboard_bank_registers = {
        ABFLAG_IO | ABFLAG_SAFE, S_READ, S_WRITE
 };
 
-static addrbank gfxboard_bank_special = {
+static const addrbank tmpl_gfxboard_bank_special = {
        gfxboards_lget_regs, gfxboards_wget_regs, gfxboards_bget_regs,
        gfxboards_lput_regs, gfxboards_wput_regs, gfxboards_bput_regs,
        default_xlate, default_check, NULL, NULL, _T("Picasso IV MISC"),
@@ -292,15 +312,36 @@ static addrbank gfxboard_bank_special = {
        ABFLAG_IO | ABFLAG_SAFE, S_READ, S_WRITE
 };
 
+void gfxboard_get_a8_vram(int index)
+{
+       addrbank *ab = gfxmem_banks[index];
+       if (vram_ram_a8 > 0) {
+               addrbank *prev = gfxmem_banks[vram_ram_a8 - 1];
+               ab->baseaddr = prev->baseaddr;
+       } else {
+               mapped_malloc(ab);
+               vram_ram_a8 = index + 1;
+       }
+}
+
+void gfxboard_free_vram(int index)
+{
+       addrbank *ab = gfxmem_banks[index];
+       if (vram_ram_a8 - 1 == index || vram_ram_a8 == 0) {
+               mapped_free(ab);
+       }
+       if (vram_ram_a8 - 1 == index)
+               vram_ram_a8 = 0;
+}
+
 static void init_board (struct rtggfxboard *gb)
 {
-       struct rtgboardconfig *rbc = &currprefs.rtgboards[gb->rtg_index];
-       gb->rbc = rbc;
+       struct rtgboardconfig *rbc = gb->rbc;
        int vramsize = gb->board->vrammax;
 
-
+       gb->active = true;
        gb->vga_width = 0;
-       mapped_free(&gfxmem_bank);
+       mapped_free(gb->gfxmem_bank);
        gb->vram_start_offset = 0;
        if (ISP4() && !gb->p4z2) // JIT direct compatibility hack
                gb->vram_start_offset = 0x01000000;
@@ -310,25 +351,63 @@ static void init_board (struct rtggfxboard *gb)
        gb->vram_offset[0] = gb->vram_offset[1] = 0;
        gb->vram_enabled = true;
        gb->vram_offset_enabled = false;
+       gb->gfxmem_bank->allocated = vramsize;
+       gb->gfxmem_bank->start = gb->gfxboardmem_start;
        if (gb->board->manufacturer) {
-               gfxmem_bank.label = gb->board->configtype == 3 ? _T("z3_gfx") : _T("z2_gfx");
+               gb->gfxmem_bank->label = _T("*");
+               mapped_malloc(gb->gfxmem_bank);
        } else {
-               gfxmem_bank.label = _T("ram_a8");
+               gb->gfxmem_bank->label = _T("ram_a8");
+               gb->vram_back = xmalloc(uae_u8, vramsize);
+               gfxboard_get_a8_vram(gb->rbc->rtg_index);
        }
-       gfxmem_bank.allocated = vramsize;
-       mapped_malloc (&gfxmem_bank);
-       gb->vram = gfxmem_bank.baseaddr;
+       gb->vram = gb->gfxmem_bank->baseaddr;
+       gb->vramend = gb->gfxmem_bank->baseaddr + vramsize;
        gb->vramrealstart = gb->vram;
        gb->vram += gb->vram_start_offset;
-       gfxmem_bank.baseaddr = gb->vram;
-       gfxmem_bank.allocated = rbc->rtgmem_size;
+       gb->vramend += gb->vram_start_offset;
+       gb->gfxmem_bank->baseaddr = gb->vram;
+       gb->gfxmem_bank->allocated = rbc->rtgmem_size;
        gb->vga.vga.vram_size_mb = rbc->rtgmem_size >> 20;
        gb->vgaioregion.opaque = &gb->vgaioregionptr;
+       gb->vgaioregion.data = gb;
        gb->vgavramregion.opaque = &gb->vgavramregionptr;
+       gb->vgavramregion.data = gb;
        gb->vga.vga.vram.opaque = &gb->vgavramregionptr;
+       gb->vga.vga.vram.data = gb;
+       gb->vga.cirrus_vga_io.data = gb;
+       gb->vga.low_mem_container.data = gb;
+       gb->vga.low_mem.data = gb;
+       gb->vga.cirrus_bank[0].data = gb;
+       gb->vga.cirrus_bank[1].data = gb;
+       gb->vga.cirrus_linear_io.data = gb;
+       gb->vga.cirrus_linear_bitblt_io.data = gb;
+       gb->vga.cirrus_mmio_io.data = gb;
+       gb->gfxsurface.data = gb;
+       gb->fakesurface.data = gb;
        vga_common_init(&gb->vga.vga);
+       gb->vga.vga.con = (void*)gb;
        cirrus_init_common(&gb->vga, gb->board->chiptype, 0,  NULL, NULL, gb->board->manufacturer == 0);
-       picasso_allocatewritewatch (rbc->rtgmem_size);
+       picasso_allocatewritewatch(gb->rbc->rtg_index, gb->rbc->rtgmem_size);
+}
+
+bool gfxboard_allocate_slot(int board, int idx)
+{
+       struct rtggfxboard *gb = &rtggfxboards[idx];
+       gb->active = true;
+       gb->rtg_index = idx;
+       const struct gfxboard *gfxb = &boards[board - GFXBOARD_HARDWARE];
+       gb->board = gfxb;
+       return true;
+}
+void gfxboard_free_slot(int idx)
+{
+       struct rtggfxboard *gb = &rtggfxboards[idx];
+       gb->active = false;
+       if (rtg_visible == idx) {
+               rtg_visible = -1;
+               picasso_requested_on = false;
+       }
 }
 
 static void vga_update_size(struct rtggfxboard *gb)
@@ -357,34 +436,86 @@ static bool gfxboard_setmode(struct rtggfxboard *gb)
        return true;
 }
 
-bool gfxboard_toggle (int mode)
+static int rtg_initial;
+
+void gfxboard_rtg_disable(int index)
 {
-       struct rtggfxboard *gb = &rtggfxboards[0];
+       if (index == rtg_visible && rtg_visible >= 0) {
+               struct rtggfxboard *gb = &rtggfxboards[index];
+               if (rtg_visible >= 0) {
+                       if (currprefs.rtgboards[rtg_visible].rtgmem_type == GFXBOARD_A2410) {
+                               tms_toggle(0);
+                       }
+               }
+               rtg_visible = -1;
+       }
+}
+
+bool gfxboard_rtg_enable_initial(int index)
+{
+       // if some RTG already enabled, don't override
+       if (rtg_visible >= 0 || rtg_initial >= 0)
+               return false;
+       if (picasso_on)
+               return false;
+       rtg_initial = index;
+       picasso_requested_on = true;
+       // check_prefs_picasso() calls gfxboard_toggle when ready
+       return true;
+}
+
+
+int gfxboard_toggle (int index, int log)
+{
+       bool initial = false;
+
+       if (rtg_visible < 0 && rtg_initial >= 0 && rtg_initial < MAX_RTG_BOARDS) {
+               index = rtg_initial;
+               initial = true;
+       }
 
-       if (currprefs.rtgboards[gb->rtg_index].rtgmem_type == GFXBOARD_A2410) {
-               return tms_toggle(mode);
+       gfxboard_rtg_disable(rtg_visible);
+
+       rtg_visible = -1;
+
+       struct rtggfxboard *gb = &rtggfxboards[index];
+       if (!gb->active) 
+               goto end;
+
+       if (index < 0)
+               goto end;
+
+       if (currprefs.rtgboards[index].rtgmem_type == GFXBOARD_A2410) {
+               bool r = tms_toggle(1);
+               if (r) {
+                       rtg_initial = MAX_RTG_BOARDS;
+                       rtg_visible = gb->rtg_index;
+                       return index;
+               }
+               goto end;
        }
 
        if (gb->vram == NULL)
-               return false;
-       if (gb->monswitch_current) {
-               gb->vga_width = 0;
-               gb->monswitch_new = false;
+               return -1;
+       vga_update_size(gb);
+       if (gb->vga_width > 16 && gb->vga_height > 16) {
+               if (!gfxboard_setmode(gb))
+                       goto end;
+               rtg_initial = MAX_RTG_BOARDS;
+               rtg_visible = gb->rtg_index;
+               gb->monswitch_new = true;
                gb->monswitch_delay = 1;
-               picasso_requested_on = 0;
-               return true;
-       } else {
-               vga_update_size(gb);
-               if (gb->vga_width > 16 && gb->vga_height > 16) {
-                       if (!gfxboard_setmode(gb))
-                               return false;
-                       gb->monswitch_new = true;
-                       gb->monswitch_delay = 1;
-                       picasso_requested_on = 1;
-                       return true;
-               }
+               picasso_requested_on = 1;
+               if (log && currprefs.rtgboards[1].rtgmem_size)
+                       statusline_add_message(_T("RTG %d: %s"), index + 1, gb->board->name);
+               return index;
        }
-       return false;
+end:
+       if (initial) {
+               rtg_initial = -1;
+               return -2;
+       }
+       return -1;
 }
 
 static bool gfxboard_checkchanged (struct rtggfxboard *gb)
@@ -401,19 +532,15 @@ static bool gfxboard_checkchanged (struct rtggfxboard *gb)
        return false;
 }
 
-static DisplaySurface gfxsurface, fakesurface;
 DisplaySurface *qemu_console_surface(QemuConsole *con)
 {
-       struct rtggfxboard *gb = &rtggfxboards[0];
-       if (picasso_on)
-               return &gfxsurface;
-       gb->modechanged = true;
-       return &fakesurface;
+       struct rtggfxboard *gb = (struct rtggfxboard*)con;
+       return &gb->gfxsurface;
 }
 
 void qemu_console_resize(QemuConsole *con, int width, int height)
 {
-       struct rtggfxboard *gb = &rtggfxboards[0];
+       struct rtggfxboard *gb = (struct rtggfxboard*)con;
        if (width != gb->vga_width || gb->vga_height != height)
                gb->vga_changed = true;
        gb->vga_width = width;
@@ -426,7 +553,7 @@ void linear_memory_region_set_dirty(MemoryRegion *mr, hwaddr addr, hwaddr size)
 
 void vga_memory_region_set_dirty(MemoryRegion *mr, hwaddr addr, hwaddr size)
 {
-       struct rtggfxboard *gb = &rtggfxboards[0];
+       struct rtggfxboard *gb = (struct rtggfxboard*)mr->data;
        if (gb->vga.vga.graphic_mode != 1)
                return;
        if (!gb->fullrefresh)
@@ -445,28 +572,42 @@ DisplaySurface* qemu_create_displaysurface_from(int width, int height, int bpp,
                                                 int linesize, uint8_t *data,
                                                 bool byteswap)
 {
-       struct rtggfxboard *gb = &rtggfxboards[0];
-       gb->modechanged = true;
-       return &fakesurface;
+       struct rtggfxboard *gb;
+       for (int i = 0; i < MAX_RTG_BOARDS; i++) {
+               gb = &rtggfxboards[i];
+               if (data >= gb->vram && data < gb->vramend) {
+                       gb->modechanged = true;
+                       return &gb->fakesurface;
+               }
+       }
+       return NULL;
 }
 
 int surface_bits_per_pixel(DisplaySurface *s)
 {
-       if (s == &fakesurface)
+       if (rtg_visible < 0)
+               return 32;
+       struct rtggfxboard *gb = (struct rtggfxboard*)s->data;
+       if (s == &gb->fakesurface)
                return 32;
        return picasso_vidinfo.pixbytes * 8;
 }
 int surface_bytes_per_pixel(DisplaySurface *s)
 {
-       if (s == &fakesurface)
+       if (rtg_visible < 0)
+               return 4;
+       struct rtggfxboard *gb = (struct rtggfxboard*)s->data;
+       if (s == &gb->fakesurface)
                return 4;
        return picasso_vidinfo.pixbytes;
 }
 
 int surface_stride(DisplaySurface *s)
 {
-       struct rtggfxboard *gb = &rtggfxboards[0];
-       if (s == &fakesurface || !gb->vga_refresh_active)
+       if (rtg_visible < 0)
+               return 0;
+       struct rtggfxboard *gb = (struct rtggfxboard*)s->data;
+       if (s == &gb->fakesurface || !gb->vga_refresh_active)
                return 0;
        if (gb->gfxboard_surface == NULL)
                gb->gfxboard_surface = gfx_lock_picasso (false, false);
@@ -474,10 +615,14 @@ int surface_stride(DisplaySurface *s)
 }
 uint8_t *surface_data(DisplaySurface *s)
 {
-       struct rtggfxboard *gb = &rtggfxboards[0];
+       if (rtg_visible < 0)
+               return NULL;
+       struct rtggfxboard *gb = (struct rtggfxboard*)s->data;
+       if (!gb)
+               return NULL;
        if (gb->vga_changed)
                return NULL;
-       if (s == &fakesurface || !gb->vga_refresh_active)
+       if (s == &gb->fakesurface || !gb->vga_refresh_active)
                return gb->fakesurface_surface;
        if (gb->gfxboard_surface == NULL)
                gb->gfxboard_surface = gfx_lock_picasso (false, false);
@@ -486,57 +631,83 @@ uint8_t *surface_data(DisplaySurface *s)
 
 void gfxboard_refresh (void)
 {
-       struct rtggfxboard *gb = &rtggfxboards[0];
-       gb->fullrefresh = 2;
+       if (rtg_visible >= 0) {
+               rtggfxboards[rtg_visible].fullrefresh = 2;
+       }
 }
 
 void gfxboard_hsync_handler(void)
 {
-       struct rtggfxboard *gb = &rtggfxboards[0];
-       if (gb->rbc->rtgmem_type == GFXBOARD_A2410) {
-               tms_hsync_handler();
+       for (int i = 0; i < MAX_RTG_BOARDS; i++) {
+               if (currprefs.rtgboards[i].rtgmem_type == GFXBOARD_A2410) {
+                       tms_hsync_handler();
+                       break;
+               }
        }
 }
 
 bool gfxboard_vsync_handler (void)
 {
-       struct rtggfxboard *gb = &rtggfxboards[0];
        bool flushed = false;
 
-       if (gb->rbc->rtgmem_type == GFXBOARD_A2410) {
-               return tms_vsync_handler();
+       for (int i = 0; i < MAX_RTG_BOARDS; i++) {
+               struct rtggfxboard *gb = &rtggfxboards[i];
+
+               if (currprefs.rtgboards[i].rtgmem_type == GFXBOARD_A2410) {
+
+                       flushed = tms_vsync_handler();
+
+               } else  if (gb->configured_mem > 0 && gb->configured_regs > 0) {
+
+                       if (gb->monswitch_new != gb->monswitch_current) {
+                               if (gb->monswitch_delay > 0)
+                                       gb->monswitch_delay--;
+                               if (gb->monswitch_delay == 0) {
+                                       if (!gb->monswitch_new && rtg_visible == i) {
+                                               gfxboard_rtg_disable(i);
+                                       }
+                                       gb->monswitch_current = gb->monswitch_new;
+                                       vga_update_size(gb);
+                                       write_log(_T("GFXBOARD %d ACTIVE=%d\n"), i, gb->monswitch_current);
+                                       gfxboard_rtg_enable_initial(i);
+                               }
+                       } else {
+                               gb->monswitch_delay = 0;
+                       }
+                       // Vertical Sync End Register, 0x20 = Disable Vertical Interrupt, 0x10 = Clear Vertical Interrupt.
+                       if (gb->board->irq) {
+                               if ((!(gb->vga.vga.cr[0x11] & 0x20) && (gb->vga.vga.cr[0x11] & 0x10) && !(gb->vga.vga.gr[0x17] & 4))) {
+                                       if (gb->gfxboard_intena) {
+                                               gb->gfxboard_vblank = true;
+                                               if (gb->board->irq == 2)
+                                                       INTREQ(0x8000 | 0x0008);
+                                               else
+                                                       INTREQ(0x8000 | 0x2000);
+                                       }
+                               }
+                       }
+               }
        }
 
-       if (!gb->configured_mem || !gb->configured_regs)
-               return false;
+       if (rtg_visible < 0)
+               return flushed;
+
+       struct rtggfxboard *gb = &rtggfxboards[rtg_visible];
+
+       if (gb->configured_mem <= 0 || gb->configured_regs <= 0)
+               return flushed;
 
        if (gb->monswitch_current && (gb->modechanged || gfxboard_checkchanged(gb))) {
                gb->modechanged = false;
                if (!gfxboard_setmode (gb)) {
-                       picasso_requested_on = 0;
+                       gfxboard_rtg_disable(rtg_visible);
                        return false;
                }
-               init_hz_p96 ();
-               picasso_requested_on = 1;
-               return false;
-       }
-
-       if (gb->monswitch_new != gb->monswitch_current) {
-               if (gb->monswitch_delay > 0)
-                       gb->monswitch_delay--;
-               if (gb->monswitch_delay == 0) {
-                       if (!gb->monswitch_new)
-                               picasso_requested_on = 0;
-                       gb->monswitch_current = gb->monswitch_new;
-                       vga_update_size(gb);
-                       write_log (_T("GFXBOARD ACTIVE=%d\n"), gb->monswitch_current);
-               }
-       } else {
-               gb->monswitch_delay = 0;
+               return flushed;
        }
 
        if (!gb->monswitch_delay && gb->monswitch_current && picasso_on && picasso_requested_on && !gb->vga_changed) {
-               picasso_getwritewatch (gb->vram_start_offset);
+               picasso_getwritewatch (rtg_visible, gb->vram_start_offset);
                if (gb->fullrefresh)
                        gb->vga.vga.graphic_mode = -1;
                gb->vga_refresh_active = true;
@@ -564,18 +735,6 @@ bool gfxboard_vsync_handler (void)
        }
        gb->gfxboard_surface = NULL;
 
-       // Vertical Sync End Register, 0x20 = Disable Vertical Interrupt, 0x10 = Clear Vertical Interrupt.
-       if (gb->board->irq) {
-               if ((!(gb->vga.vga.cr[0x11] & 0x20) && (gb->vga.vga.cr[0x11] & 0x10) && !(gb->vga.vga.gr[0x17] & 4))) {
-                       if (gb->gfxboard_intena) {
-                               gb->gfxboard_vblank = true;
-                               if (gb->board->irq == 2)
-                                       INTREQ (0x8000 | 0x0008);
-                               else
-                                       INTREQ (0x8000 | 0x2000);
-                       }
-               }
-       }
        return flushed;
 }
 
@@ -595,7 +754,7 @@ void memory_region_init_alias(MemoryRegion *mr,
                               hwaddr offset,
                               uint64_t size)
 {
-       struct rtggfxboard *gb = &rtggfxboards[0];
+       struct rtggfxboard *gb = (struct rtggfxboard*)mr->data;
        if (!stricmp(name, "vga.bank0")) {
                mr->opaque = &gb->vgabank0regionptr;
        } else if (!stricmp(name, "vga.bank1")) {
@@ -636,7 +795,7 @@ static void remap_vram (struct rtggfxboard *gb, hwaddr offset0, hwaddr offset1,
 
 void memory_region_set_alias_offset(MemoryRegion *mr, hwaddr offset)
 {
-       struct rtggfxboard *gb = &rtggfxboards[0];
+       struct rtggfxboard *gb = (struct rtggfxboard*)mr->data;
        if (mr->opaque == &gb->vgabank0regionptr) {
                if (offset != gb->vram_offset[0]) {
                        //write_log (_T("vgavramregion0 %08x\n"), offset);
@@ -656,7 +815,7 @@ void memory_region_set_alias_offset(MemoryRegion *mr, hwaddr offset)
 }
 void memory_region_set_enabled(MemoryRegion *mr, bool enabled)
 {
-       struct rtggfxboard *gb = &rtggfxboards[0];
+       struct rtggfxboard *gb = (struct rtggfxboard*)mr->data;
        if (mr->opaque == &gb->vgabank0regionptr || mr->opaque == &gb->vgabank1regionptr) {
                if (enabled != gb->vram_enabled)  {
                        //write_log (_T("enable vgavramregion %d\n"), enabled);
@@ -676,13 +835,13 @@ void memory_region_reset_dirty(MemoryRegion *mr, hwaddr addr,
 bool memory_region_get_dirty(MemoryRegion *mr, hwaddr addr,
                              hwaddr size, unsigned client)
 {
-       struct rtggfxboard *gb = &rtggfxboards[0];
+       struct rtggfxboard *gb = (struct rtggfxboard*)mr->data;
        if (mr->opaque != &gb->vgavramregionptr)
                return false;
        //write_log (_T("memory_region_get_dirty %08x %08x\n"), addr, size);
        if (gb->fullrefresh)
                return true;
-       return picasso_is_vram_dirty (addr + gfxmem_bank.start, size);
+       return picasso_is_vram_dirty (gb->rtg_index, addr + gb->gfxmem_bank->start, size);
 }
 
 static QEMUResetHandler *reset_func;
@@ -789,18 +948,18 @@ static uae_u8 bget_regtest (struct rtggfxboard *gb, uaecptr addr, uae_u8 v)
        return v;
 }
 
-void vga_io_put(int portnum, uae_u8 v)
+void vga_io_put(int board, int portnum, uae_u8 v)
 {
-       struct rtggfxboard *gb = &rtggfxboards[0];
+       struct rtggfxboard *gb = &rtggfxboards[board];
        if (!gb->vgaio)
                return;
        portnum -= 0x3b0;
        bput_regtest(gb, portnum, v);
        gb->vgaio->write(&gb->vga, portnum, v, 1);
 }
-uae_u8 vga_io_get(int portnum)
+uae_u8 vga_io_get(int board, int portnum)
 {
-       struct rtggfxboard *gb = &rtggfxboards[0];
+       struct rtggfxboard *gb = &rtggfxboards[board];
        uae_u8 v = 0xff;
        if (!gb->vgaio)
                return v;
@@ -809,17 +968,17 @@ uae_u8 vga_io_get(int portnum)
        v = bget_regtest(gb, portnum, v);
        return v;
 }
-void vga_ram_put(int offset, uae_u8 v)
+void vga_ram_put(int board, int offset, uae_u8 v)
 {
-       struct rtggfxboard *gb = &rtggfxboards[0];
+       struct rtggfxboard *gb = &rtggfxboards[board];
        if (!gb->vgalowram)
                return;
        offset -= 0xa0000;
        gb->vgalowram->write(&gb->vga, offset, v, 1);
 }
-uae_u8 vga_ram_get(int offset)
+uae_u8 vga_ram_get(int board, int offset)
 {
-       struct rtggfxboard *gb = &rtggfxboards[0];
+       struct rtggfxboard *gb = &rtggfxboards[board];
        if (!gb->vgalowram)
                return 0xff;
        offset -= 0xa0000;
@@ -828,7 +987,7 @@ uae_u8 vga_ram_get(int offset)
 
 void *memory_region_get_ram_ptr(MemoryRegion *mr)
 {
-       struct rtggfxboard *gb = &rtggfxboards[0];
+       struct rtggfxboard *gb = (struct rtggfxboard*)mr->data;
        if (mr->opaque == &gb->vgavramregionptr)
                return gb->vram;
        return NULL;
@@ -838,7 +997,7 @@ void memory_region_init_ram(MemoryRegion *mr,
                             const char *name,
                             uint64_t size)
 {
-       struct rtggfxboard *gb = &rtggfxboards[0];
+       struct rtggfxboard *gb = (struct rtggfxboard*)mr->data;
        if (!stricmp (name, "vga.vram")) {
                gb->vgavramregion.opaque = mr->opaque;
        }
@@ -850,7 +1009,7 @@ void memory_region_init_io(MemoryRegion *mr,
                            const char *name,
                            uint64_t size)
 {
-       struct rtggfxboard *gb = &rtggfxboards[0];
+       struct rtggfxboard *gb = (struct rtggfxboard*)mr->data;
        if (!stricmp (name, "cirrus-io")) {
                gb->vgaio = ops;
                mr->opaque = gb->vgaioregion.opaque;
@@ -865,14 +1024,16 @@ void memory_region_init_io(MemoryRegion *mr,
 
 int is_surface_bgr(DisplaySurface *surface)
 {
-       struct rtggfxboard *gb = &rtggfxboards[0];
+       if (!surface || !surface->data)
+               return 0;
+       struct rtggfxboard *gb = (struct rtggfxboard*)surface->data;
        return gb->board->swap;
 }
 
 static uaecptr fixaddr_bs (struct rtggfxboard *gb, uaecptr addr, int mask, int *bs)
 {
        bool swapped = false;
-       addr &= gfxmem_bank.mask;
+       addr &= gb->gfxmem_bank->mask;
        if (gb->p4z2) {
                if (addr < 0x200000) {
                        addr |= gb->p4_vram_bank[0];
@@ -905,7 +1066,7 @@ static uaecptr fixaddr_bs (struct rtggfxboard *gb, uaecptr addr, int mask, int *
                        addr += gb->vram_offset[0];
                }
        }
-       addr &= gfxmem_bank.mask;
+       addr &= gb->gfxmem_bank->mask;
        return addr;
 }
 
@@ -922,7 +1083,7 @@ STATIC_INLINE uaecptr fixaddr (struct rtggfxboard *gb, uaecptr addr, int mask)
                        addr += gb->vram_offset[0];
                }
        }
-       addr &= gfxmem_bank.mask;
+       addr &= gb->gfxmem_bank->mask;
        return addr;
 }
 
@@ -935,14 +1096,14 @@ STATIC_INLINE uaecptr fixaddr (struct rtggfxboard *gb, uaecptr addr)
                        addr += gb->vram_offset[0];
                }
        }
-       addr &= gfxmem_bank.mask;
+       addr &= gb->gfxmem_bank->mask;
        return addr;
 }
 
 STATIC_INLINE const MemoryRegionOps *getvgabank (struct rtggfxboard *gb, uaecptr *paddr)
 {
        uaecptr addr = *paddr;
-       addr &= gfxmem_bank.mask;
+       addr &= gb->gfxmem_bank->mask;
        *paddr = addr;
        return gb->vgaram;
 }
@@ -952,7 +1113,7 @@ static uae_u32 gfxboard_lget_vram (struct rtggfxboard *gb, uaecptr addr, int bs)
        uae_u32 v;
        if (!gb->vram_enabled) {
                const MemoryRegionOps *bank = getvgabank (gb, &addr);
-               addr &= gfxmem_bank.mask;
+               addr &= gb->gfxmem_bank->mask;
                if (bs < 0) { // WORD
                        v  = bank->read (&gb->vga, addr + 1, 1) << 24;
                        v |= bank->read (&gb->vga, addr + 0, 1) << 16;
@@ -985,7 +1146,7 @@ static uae_u32 gfxboard_lget_vram (struct rtggfxboard *gb, uaecptr addr, int bs)
        if (!vram_enabled || vram_offset_enabled)
 #endif
        if (memlogr)
-       write_log (_T("R %08X L %08X BS=%d EN=%d\n"), addr, v, bs, vram_enabled);
+       write_log (_T("R %08X L %08X BS=%d EN=%d\n"), addr, v, bs, gb->vram_enabled);
 #endif
        return v;
 }
@@ -1013,7 +1174,7 @@ static uae_u16 gfxboard_wget_vram (struct rtggfxboard *gb, uaecptr addr, int bs)
        if (!vram_enabled || vram_offset_enabled)
 #endif
        if (memlogr)
-       write_log (_T("R %08X W %08X BS=%d EN=%d\n"), addr, v, bs, vram_enabled);
+       write_log (_T("R %08X W %08X BS=%d EN=%d\n"), addr, v, bs, gb->vram_enabled);
 #endif
        return v;
 }
@@ -1037,7 +1198,7 @@ static uae_u8 gfxboard_bget_vram (struct rtggfxboard *gb, uaecptr addr, int bs)
        if (!vram_enabled || vram_offset_enabled)
 #endif
        if (memlogr)
-       write_log (_T("R %08X B %08X BS=0 EN=%d\n"), addr, v, vram_enabled);
+       write_log (_T("R %08X B %08X BS=0 EN=%d\n"), addr, v, gb->vram_enabled);
 #endif
        return v;
 }
@@ -1145,16 +1306,50 @@ static void gfxboard_bput_vram (struct rtggfxboard *gb, uaecptr addr, uae_u8 b,
        }
 }
 
-STATIC_INLINE rtggfxboard *getgfxboard(uaecptr addr)
-{
-       return &rtggfxboards[0];
+static struct rtggfxboard *lastgetgfxboard;
+static rtggfxboard *getgfxboard(uaecptr addr)
+{
+       if (total_active_gfx_boards == 1)
+               return &rtggfxboards[0];
+       if (lastgetgfxboard) {
+               if (addr >= lastgetgfxboard->io_start && addr < lastgetgfxboard->io_end)
+                       return lastgetgfxboard;
+               if (addr >= lastgetgfxboard->mem_start[0] && addr < lastgetgfxboard->mem_end[0])
+                       return lastgetgfxboard;
+               if (addr >= lastgetgfxboard->mem_start[1] && addr < lastgetgfxboard->mem_end[1])
+                       return lastgetgfxboard;
+               lastgetgfxboard = NULL;
+       }
+       for (int i = 0; i < MAX_RTG_BOARDS; i++) {
+               struct rtggfxboard *gb = &rtggfxboards[i];
+               if (!gb->active)
+                       continue;
+               if (gb->configured_mem < 0 || gb->configured_regs < 0) {
+                       lastgetgfxboard = gb;
+                       return gb;
+               } else {
+                       if (addr >= gb->io_start && addr < gb->io_end) {
+                               lastgetgfxboard = gb;
+                               return gb;
+                       }
+                       if (addr >= gb->mem_start[0] && addr < gb->mem_end[0]) {
+                               lastgetgfxboard = gb;
+                               return gb;
+                       }
+                       if (addr >= gb->mem_start[1] && addr < gb->mem_end[1]) {
+                               lastgetgfxboard = gb;
+                               return gb;
+                       }
+               }
+       }
+       return NULL;
 }
 
 // LONG byteswapped VRAM
 static uae_u32 REGPARAM2 gfxboard_lget_lbsmem (uaecptr addr)
 {
        struct rtggfxboard *gb = getgfxboard(addr);
-       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
        addr = fixaddr(gb, addr, 0);
        if (addr == -1)
                return 0;
@@ -1163,7 +1358,7 @@ static uae_u32 REGPARAM2 gfxboard_lget_lbsmem (uaecptr addr)
 static uae_u32 REGPARAM2 gfxboard_wget_lbsmem (uaecptr addr)
 {
        struct rtggfxboard *gb = getgfxboard(addr);
-       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
        addr = fixaddr(gb, addr, 0);
        if (addr == -1)
                return 0;
@@ -1172,7 +1367,7 @@ static uae_u32 REGPARAM2 gfxboard_wget_lbsmem (uaecptr addr)
 static uae_u32 REGPARAM2 gfxboard_bget_lbsmem (uaecptr addr)
 {
        struct rtggfxboard *gb = getgfxboard(addr);
-       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
        addr = fixaddr(gb, addr, 0);
        if (addr == -1)
                return 0;
@@ -1182,7 +1377,7 @@ static uae_u32 REGPARAM2 gfxboard_bget_lbsmem (uaecptr addr)
 static void REGPARAM2 gfxboard_lput_lbsmem (uaecptr addr, uae_u32 l)
 {
        struct rtggfxboard *gb = getgfxboard(addr);
-       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
        addr = fixaddr(gb, addr, 0);
        if (addr == -1)
                return;
@@ -1191,7 +1386,7 @@ static void REGPARAM2 gfxboard_lput_lbsmem (uaecptr addr, uae_u32 l)
 static void REGPARAM2 gfxboard_wput_lbsmem (uaecptr addr, uae_u32 w)
 {
        struct rtggfxboard *gb = getgfxboard(addr);
-       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
        addr = fixaddr(gb, addr, 0);
        if (addr == -1)
                return;
@@ -1200,7 +1395,7 @@ static void REGPARAM2 gfxboard_wput_lbsmem (uaecptr addr, uae_u32 w)
 static void REGPARAM2 gfxboard_bput_lbsmem (uaecptr addr, uae_u32 w)
 {
        struct rtggfxboard *gb = getgfxboard(addr);
-       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
        addr = fixaddr(gb, addr, 0);
        if (addr == -1)
                return;
@@ -1211,7 +1406,7 @@ static void REGPARAM2 gfxboard_bput_lbsmem (uaecptr addr, uae_u32 w)
 static uae_u32 REGPARAM2 gfxboard_lget_wbsmem (uaecptr addr)
 {
        struct rtggfxboard *gb = getgfxboard(addr);
-       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
        addr = fixaddr(gb, addr, 0);
        if (addr == -1)
                return 0;
@@ -1220,7 +1415,7 @@ static uae_u32 REGPARAM2 gfxboard_lget_wbsmem (uaecptr addr)
 static uae_u32 REGPARAM2 gfxboard_wget_wbsmem (uaecptr addr)
 {
        struct rtggfxboard *gb = getgfxboard(addr);
-       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
        addr = fixaddr(gb, addr, 0);
        if (addr == -1)
                return 0;
@@ -1229,7 +1424,7 @@ static uae_u32 REGPARAM2 gfxboard_wget_wbsmem (uaecptr addr)
 static uae_u32 REGPARAM2 gfxboard_bget_wbsmem (uaecptr addr)
 {
        struct rtggfxboard *gb = getgfxboard(addr);
-       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
        addr = fixaddr(gb, addr, 0);
        if (addr == -1)
                return 0;
@@ -1239,7 +1434,7 @@ static uae_u32 REGPARAM2 gfxboard_bget_wbsmem (uaecptr addr)
 static void REGPARAM2 gfxboard_lput_wbsmem (uaecptr addr, uae_u32 l)
 {
        struct rtggfxboard *gb = getgfxboard(addr);
-       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
        addr = fixaddr(gb, addr, 0);
        if (addr == -1)
                return;
@@ -1248,7 +1443,7 @@ static void REGPARAM2 gfxboard_lput_wbsmem (uaecptr addr, uae_u32 l)
 static void REGPARAM2 gfxboard_wput_wbsmem (uaecptr addr, uae_u32 w)
 {
        struct rtggfxboard *gb = getgfxboard(addr);
-       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
        addr = fixaddr(gb, addr, 0);
        if (addr == -1)
                return;
@@ -1257,7 +1452,7 @@ static void REGPARAM2 gfxboard_wput_wbsmem (uaecptr addr, uae_u32 w)
 static void REGPARAM2 gfxboard_bput_wbsmem (uaecptr addr, uae_u32 w)
 {
        struct rtggfxboard *gb = getgfxboard(addr);
-       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
        addr = fixaddr(gb, addr, 0);
        if (addr == -1)
                return;
@@ -1269,7 +1464,7 @@ static uae_u32 REGPARAM2 gfxboard_lget_nbsmem (uaecptr addr)
 {
        struct rtggfxboard *gb = getgfxboard(addr);
        int bs = 0;
-       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
        addr = fixaddr_bs (gb, addr, 0, &bs);
        if (addr == -1)
                return 0;
@@ -1280,7 +1475,7 @@ static uae_u32 REGPARAM2 gfxboard_wget_nbsmem (uaecptr addr)
 {
        struct rtggfxboard *gb = getgfxboard(addr);
        int bs = 0;
-       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
        addr = fixaddr_bs (gb, addr, 0, &bs);
        if (addr == -1)
                return 0;
@@ -1291,7 +1486,7 @@ static void REGPARAM2 gfxboard_lput_nbsmem (uaecptr addr, uae_u32 l)
 {
        struct rtggfxboard *gb = getgfxboard(addr);
        int bs = 0;
-       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
        addr = fixaddr_bs (gb, addr, 0, &bs);
        if (addr == -1)
                return;
@@ -1301,7 +1496,7 @@ static void REGPARAM2 gfxboard_wput_nbsmem (uaecptr addr, uae_u32 w)
 {
        struct rtggfxboard *gb = getgfxboard(addr);
        int bs = 0;
-       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
        addr = fixaddr_bs (gb, addr, 0, &bs);
        if (addr == -1)
                return;
@@ -1312,7 +1507,7 @@ static uae_u32 REGPARAM2 gfxboard_bget_bsmem (uaecptr addr)
 {
        struct rtggfxboard *gb = getgfxboard(addr);
        int bs = 0;
-       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
        addr = fixaddr(gb, addr, 0);
        if (addr == -1)
                return 0;
@@ -1322,7 +1517,7 @@ static void REGPARAM2 gfxboard_bput_bsmem (uaecptr addr, uae_u32 b)
 {
        struct rtggfxboard *gb = getgfxboard(addr);
        int bs = 0;
-       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
        addr = fixaddr_bs (gb, addr, 0, &bs);
        if (addr == -1)
                return;
@@ -1333,7 +1528,7 @@ static void REGPARAM2 gfxboard_bput_bsmem (uaecptr addr, uae_u32 b)
 static uae_u32 REGPARAM2 gfxboard_lget_mem (uaecptr addr)
 {
        struct rtggfxboard *gb = getgfxboard(addr);
-       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
        addr = fixaddr(gb, addr, S_READ);
        if (addr == -1)
                return 0;
@@ -1342,7 +1537,7 @@ static uae_u32 REGPARAM2 gfxboard_lget_mem (uaecptr addr)
 static uae_u32 REGPARAM2 gfxboard_wget_mem (uaecptr addr)
 {
        struct rtggfxboard *gb = getgfxboard(addr);
-       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
        addr = fixaddr(gb, addr, S_READ);
        if (addr == -1)
                return 0;
@@ -1351,7 +1546,7 @@ static uae_u32 REGPARAM2 gfxboard_wget_mem (uaecptr addr)
 static uae_u32 REGPARAM2 gfxboard_bget_mem (uaecptr addr)
 {
        struct rtggfxboard *gb = getgfxboard(addr);
-       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
        addr = fixaddr(gb, addr, S_READ);
        if (addr == -1)
                return 0;
@@ -1360,7 +1555,7 @@ static uae_u32 REGPARAM2 gfxboard_bget_mem (uaecptr addr)
 static void REGPARAM2 gfxboard_lput_mem (uaecptr addr, uae_u32 l)
 {
        struct rtggfxboard *gb = getgfxboard(addr);
-       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
        addr = fixaddr(gb, addr, S_WRITE);
        if (addr == -1)
                return;
@@ -1369,7 +1564,7 @@ static void REGPARAM2 gfxboard_lput_mem (uaecptr addr, uae_u32 l)
 static void REGPARAM2 gfxboard_wput_mem (uaecptr addr, uae_u32 w)
 {
        struct rtggfxboard *gb = getgfxboard(addr);
-       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
        addr = fixaddr(gb, addr, S_WRITE);
        if (addr == -1)
                return;
@@ -1378,7 +1573,7 @@ static void REGPARAM2 gfxboard_wput_mem (uaecptr addr, uae_u32 w)
 static void REGPARAM2 gfxboard_bput_mem (uaecptr addr, uae_u32 b)
 {
        struct rtggfxboard *gb = getgfxboard(addr);
-       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
        addr = fixaddr(gb, addr, S_WRITE);
        if (addr == -1)
                return;
@@ -1389,7 +1584,7 @@ static void REGPARAM2 gfxboard_bput_mem (uaecptr addr, uae_u32 b)
 static uae_u32 REGPARAM2 gfxboard_lget_mem_nojit (uaecptr addr)
 {
        struct rtggfxboard *gb = getgfxboard(addr);
-       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
        addr = fixaddr (gb, addr);
        if (addr == -1)
                return 0;
@@ -1398,7 +1593,7 @@ static uae_u32 REGPARAM2 gfxboard_lget_mem_nojit (uaecptr addr)
 static uae_u32 REGPARAM2 gfxboard_wget_mem_nojit (uaecptr addr)
 {
        struct rtggfxboard *gb = getgfxboard(addr);
-       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
        addr = fixaddr (gb, addr);
        if (addr == -1)
                return 0;
@@ -1407,7 +1602,7 @@ static uae_u32 REGPARAM2 gfxboard_wget_mem_nojit (uaecptr addr)
 static uae_u32 REGPARAM2 gfxboard_bget_mem_nojit (uaecptr addr)
 {
        struct rtggfxboard *gb = getgfxboard(addr);
-       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
        addr = fixaddr (gb, addr);
        if (addr == -1)
                return 0;
@@ -1416,7 +1611,7 @@ static uae_u32 REGPARAM2 gfxboard_bget_mem_nojit (uaecptr addr)
 static void REGPARAM2 gfxboard_lput_mem_nojit (uaecptr addr, uae_u32 l)
 {
        struct rtggfxboard *gb = getgfxboard(addr);
-       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
        addr = fixaddr (gb, addr);
        if (addr == -1)
                return;
@@ -1425,7 +1620,7 @@ static void REGPARAM2 gfxboard_lput_mem_nojit (uaecptr addr, uae_u32 l)
 static void REGPARAM2 gfxboard_wput_mem_nojit (uaecptr addr, uae_u32 w)
 {
        struct rtggfxboard *gb = getgfxboard(addr);
-       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
        addr = fixaddr (gb, addr);
        if (addr == -1)
                return;
@@ -1434,7 +1629,7 @@ static void REGPARAM2 gfxboard_wput_mem_nojit (uaecptr addr, uae_u32 w)
 static void REGPARAM2 gfxboard_bput_mem_nojit (uaecptr addr, uae_u32 b)
 {
        struct rtggfxboard *gb = getgfxboard(addr);
-       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
        addr = fixaddr (gb, addr);
        if (addr == -1)
                return;
@@ -1444,15 +1639,15 @@ static void REGPARAM2 gfxboard_bput_mem_nojit (uaecptr addr, uae_u32 b)
 static int REGPARAM2 gfxboard_check (uaecptr addr, uae_u32 size)
 {
        struct rtggfxboard *gb = getgfxboard(addr);
-       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
-       addr &= gfxmem_bank.mask;
+       addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
+       addr &= gb->gfxmem_bank->mask;
        return (addr + size) <= gb->rbc->rtgmem_size;
 }
 static uae_u8 *REGPARAM2 gfxboard_xlate (uaecptr addr)
 {
        struct rtggfxboard *gb = getgfxboard(addr);
-       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
-       addr &= gfxmem_bank.mask;
+       addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
+       addr &= gb->gfxmem_bank->mask;
        return gb->vram + addr;
 }
 
@@ -1474,41 +1669,42 @@ static void REGPARAM2 gfxboard_wput_mem_autoconfig (uaecptr addr, uae_u32 b)
        b &= 0xffff;
        addr &= 65535;
        if (addr == 0x44) {
-               uae_u32 start;
+               uae_u32 start = expamem_board_pointer;
                if (!expamem_z3hack(&currprefs)) {
-                       start = (b & 0xff00) | gb->expamem_lo;
-                       gfxmem_bank.start = start << 16;
+                       start = ((b & 0xff00) | gb->expamem_lo) << 16;
                }
-               gfxboard_bank_memory.bget = gfxboard_bget_mem;
-               gfxboard_bank_memory.bput = gfxboard_bput_mem;
-               gfxboard_bank_memory.wput = gfxboard_wput_mem;
+               gb->gfxboardmem_start = start;
+               gb->gfxboard_bank_memory.bget = gfxboard_bget_mem;
+               gb->gfxboard_bank_memory.bput = gfxboard_bput_mem;
+               gb->gfxboard_bank_memory.wput = gfxboard_wput_mem;
                init_board (gb);
                if (ISP4()) {
-                       if (validate_banks_z3(&gfxboard_bank_memory, gfxmem_bank.start >> 16, expamem_z3_size >> 16)) {
+                       if (validate_banks_z3(&gb->gfxboard_bank_memory, gb->gfxmem_bank->start >> 16, expamem_board_size >> 16)) {
                                // main vram
-                               map_banks_z3(&gfxboard_bank_memory, (gfxmem_bank.start + PICASSOIV_VRAM1) >> 16, 0x400000 >> 16);
-                               map_banks_z3(&gfxboard_bank_wbsmemory, (gfxmem_bank.start + PICASSOIV_VRAM1 + 0x400000) >> 16, 0x400000 >> 16);
+                               map_banks_z3(&gb->gfxboard_bank_memory, (gb->gfxmem_bank->start + PICASSOIV_VRAM1) >> 16, 0x400000 >> 16);
+                               map_banks_z3(&gb->gfxboard_bank_wbsmemory, (gb->gfxmem_bank->start + PICASSOIV_VRAM1 + 0x400000) >> 16, 0x400000 >> 16);
                                // secondary
-                               map_banks_z3(&gfxboard_bank_memory_nojit, (gfxmem_bank.start + PICASSOIV_VRAM2) >> 16, 0x400000 >> 16);
-                               map_banks_z3(&gfxboard_bank_wbsmemory, (gfxmem_bank.start + PICASSOIV_VRAM2 + 0x400000) >> 16, 0x400000 >> 16);
+                               map_banks_z3(&gb->gfxboard_bank_memory_nojit, (gb->gfxmem_bank->start + PICASSOIV_VRAM2) >> 16, 0x400000 >> 16);
+                               map_banks_z3(&gb->gfxboard_bank_wbsmemory, (gb->gfxmem_bank->start + PICASSOIV_VRAM2 + 0x400000) >> 16, 0x400000 >> 16);
                                // regs
-                               map_banks_z3(&gfxboard_bank_registers, (gfxmem_bank.start + PICASSOIV_REG) >> 16, 0x200000 >> 16);
-                               map_banks_z3(&gfxboard_bank_special, gfxmem_bank.start >> 16, PICASSOIV_REG >> 16);
+                               map_banks_z3(&gb->gfxboard_bank_registers, (gb->gfxmem_bank->start + PICASSOIV_REG) >> 16, 0x200000 >> 16);
+                               map_banks_z3(&gb->gfxboard_bank_special, gb->gfxmem_bank->start >> 16, PICASSOIV_REG >> 16);
                        }
                        gb->picassoiv_bank = 0;
                        gb->picassoiv_flifi = 1;
-                       gb->configured_regs = gfxmem_bank.start >> 16;
+                       gb->configured_regs = gb->gfxmem_bank->start >> 16;
                } else {
-                       map_banks_z3(&gfxboard_bank_memory, gfxmem_bank.start >> 16, gb->board->banksize >> 16);
+                       map_banks_z3(&gb->gfxboard_bank_memory, gb->gfxmem_bank->start >> 16, gb->board->banksize >> 16);
                }
-               gb->configured_mem = gfxmem_bank.start >> 16;
-               gb->gfxboardmem_start = gfxmem_bank.start;
-               expamem_next (&gfxboard_bank_memory, NULL);
+               gb->mem_start[0] = start;
+               gb->mem_end[0] = gb->mem_start[0] + gb->board->banksize;
+               gb->configured_mem = gb->gfxmem_bank->start >> 16;
+               expamem_next (&gb->gfxboard_bank_memory, NULL);
                return;
        }
        if (addr == 0x4c) {
                gb->configured_mem = 0xff;
-               expamem_shutup(&gfxboard_bank_memory);
+               expamem_shutup(&gb->gfxboard_bank_memory);
                return;
        }
 }
@@ -1522,25 +1718,30 @@ static void REGPARAM2 gfxboard_bput_mem_autoconfig (uaecptr addr, uae_u32 b)
                if (gb->board->configtype == 2) {
                        addrbank *ab;
                        if (ISP4()) {
-                               ab = &gfxboard_bank_nbsmemory;
-                               if (gb->configured_mem == 0)
-                                       init_board (gb);
+                               ab = &gb->gfxboard_bank_nbsmemory;
                                map_banks_z2 (ab, b, 0x00200000 >> 16);
-                               if (gb->configured_mem == 0) {
+                               if (gb->configured_mem <= 0) {
                                        gb->configured_mem = b;
                                        gb->gfxboardmem_start = b << 16;
+                                       init_board(gb);
+                                       gb->mem_start[0] = b << 16;
+                                       gb->mem_end[0] = gb->mem_start[0] + 0x00200000;
                                } else {
-                                       gfxboard_bank_memory.bget = gfxboard_bget_mem;
-                                       gfxboard_bank_memory.bput = gfxboard_bput_mem;
+                                       gb->gfxboard_bank_memory.bget = gfxboard_bget_mem;
+                                       gb->gfxboard_bank_memory.bput = gfxboard_bput_mem;
+                                       gb->mem_start[1] = b << 16;
+                                       gb->mem_end[1] = gb->mem_start[1] + 0x00200000;
                                }
                        } else {
-                               ab = &gfxboard_bank_memory;
-                               gfxboard_bank_memory.bget = gfxboard_bget_mem;
-                               gfxboard_bank_memory.bput = gfxboard_bput_mem;
+                               ab = &gb->gfxboard_bank_memory;
+                               gb->gfxboard_bank_memory.bget = gfxboard_bget_mem;
+                               gb->gfxboard_bank_memory.bput = gfxboard_bput_mem;
+                               gb->gfxboardmem_start = b << 16;
                                init_board (gb);
                                map_banks_z2 (ab, b, gb->board->banksize >> 16);
                                gb->configured_mem = b;
-                               gb->gfxboardmem_start = b << 16;
+                               gb->mem_start[0] = b << 16;
+                               gb->mem_end[0] = gb->mem_start[0] + gb->board->banksize;
                        }
                        expamem_next (ab, NULL);
                } else {
@@ -1550,7 +1751,7 @@ static void REGPARAM2 gfxboard_bput_mem_autoconfig (uaecptr addr, uae_u32 b)
        }
        if (addr == 0x4c) {
                gb->configured_mem = 0xff;
-               expamem_shutup(&gfxboard_bank_memory);
+               expamem_shutup(&gb->gfxboard_bank_memory);
                return;
        }
 }
@@ -1640,7 +1841,9 @@ static uae_u32 REGPARAM2 gfxboard_bget_regs (uaecptr addr)
 static void REGPARAM2 gfxboard_lput_regs (uaecptr addr, uae_u32 l)
 {
        struct rtggfxboard *gb = getgfxboard(addr);
-       //write_log (_T("GFX LONG PUT IO %04X = %04X\n"), addr & 65535, l);
+#if REGDEBUG
+       write_log (_T("GFX LONG PUT IO %04X = %04X\n"), addr & 65535, l);
+#endif
        addr = mungeaddr (gb, addr, true);
        if (addr) {
                gb->vgaio->write (&gb->vga, addr + 0, l >> 24, 1);
@@ -1656,7 +1859,9 @@ static void REGPARAM2 gfxboard_lput_regs (uaecptr addr, uae_u32 l)
 static void REGPARAM2 gfxboard_wput_regs (uaecptr addr, uae_u32 w)
 {
        struct rtggfxboard *gb = getgfxboard(addr);
-       //write_log (_T("GFX WORD PUT IO %04X = %04X\n"), addr & 65535, w & 0xffff);
+#if REGDEBUG
+       write_log (_T("GFX WORD PUT IO %04X = %04X\n"), addr & 65535, w & 0xffff);
+#endif
        addr = mungeaddr (gb, addr, true);
        if (addr) {
                gb->vgaio->write (&gb->vga, addr + 0, (w >> 8) & 0xff, 1);
@@ -1668,7 +1873,9 @@ static void REGPARAM2 gfxboard_wput_regs (uaecptr addr, uae_u32 w)
 static void REGPARAM2 gfxboard_bput_regs (uaecptr addr, uae_u32 b)
 {
        struct rtggfxboard *gb = getgfxboard(addr);
-       //write_log (_T("GFX BYTE PUT IO %04X = %02X\n"), addr & 65535, b & 0xff);
+#if REGDEBUG
+       write_log (_T("GFX BYTE PUT IO %04X = %02X\n"), addr & 65535, b & 0xff);
+#endif
        addr &= 65535;
        if (addr >= 0x8000) {
                write_log (_T("GFX SPECIAL BPUT IO %08X = %02X\n"), addr, b & 0xff);
@@ -1718,14 +1925,18 @@ static void REGPARAM2 gfxboard_bput_regs_autoconfig (uaecptr addr, uae_u32 b)
        b &= 0xff;
        addr &= 65535;
        if (addr == 0x48) {
-               gfxboard_bank_registers.bget = gfxboard_bget_regs;
-               gfxboard_bank_registers.bput = gfxboard_bput_regs;
+               gb->gfxboard_bank_registers.bget = gfxboard_bget_regs;
+               gb->gfxboard_bank_registers.bput = gfxboard_bput_regs;
                if (gb->p4z2) {
-                       ab = &gfxboard_bank_special;
-                       map_banks_z2(ab, b, gfxboard_bank_special.allocated >> 16);
+                       ab = &gb->gfxboard_bank_special;
+                       map_banks_z2(ab, b, gb->gfxboard_bank_special.allocated >> 16);
+                       gb->io_start = b << 16;
+                       gb->io_end = gb->io_start + gb->gfxboard_bank_special.allocated;
                } else {
-                       ab = &gfxboard_bank_registers;
-                       map_banks_z2(ab, b, gfxboard_bank_registers.allocated >> 16);
+                       ab = &gb->gfxboard_bank_registers;
+                       map_banks_z2(ab, b, gb->gfxboard_bank_registers.allocated >> 16);
+                       gb->io_start = b << 16;
+                       gb->io_end = gb->io_start + gb->gfxboard_bank_registers.allocated;
                }
                gb->configured_regs = b;
                expamem_next (ab, NULL);
@@ -1738,9 +1949,8 @@ static void REGPARAM2 gfxboard_bput_regs_autoconfig (uaecptr addr, uae_u32 b)
        }
 }
 
-void gfxboard_free(void)
+static void gfxboard_free_board(struct rtggfxboard *gb)
 {
-       struct rtggfxboard *gb = &rtggfxboards[0];
        if (gb->rbc) {
                if (gb->rbc->rtgmem_type == GFXBOARD_A2410) {
                        tms_free();
@@ -1749,12 +1959,13 @@ void gfxboard_free(void)
                }
        }
        if (gb->vram) {
-               gfxmem_bank.baseaddr = gb->vramrealstart;
-               mapped_free (&gfxmem_bank);
+               gb->gfxmem_bank->baseaddr = gb->vramrealstart;
+               gfxboard_free_vram(gb->rbc->rtg_index);
+               gb->gfxmem_bank = NULL;
        }
        gb->vram = NULL;
        gb->vramrealstart = NULL;
-       xfree (gb->fakesurface_surface);
+       xfree(gb->fakesurface_surface);
        gb->fakesurface_surface = NULL;
        gb->configured_mem = 0;
        gb->configured_regs = 0;
@@ -1766,26 +1977,37 @@ void gfxboard_free(void)
        gb->gfxboard_vblank = false;
        gb->gfxboard_intena = false;
        gb->picassoiv_bank = 0;
+       gb->active = false;
 }
 
-void gfxboard_reset (void)
+void gfxboard_free(void)
 {
-       struct rtggfxboard *gb = &rtggfxboards[0];
-       gb->rbc = &currprefs.rtgboards[gb->rtg_index];
-       if (gb->rbc->rtgmem_type == GFXBOARD_A2410) {
-               tms_reset();
-               return;
-       }
-       if (gb->rbc->rtgmem_type >= GFXBOARD_HARDWARE) {
-               gb->board = &boards[gb->rbc->rtgmem_type - GFXBOARD_HARDWARE];
-               gfxmem_bank.mask = gb->rbc->rtgmem_size - 1;
+       for (int i = 0; i < MAX_RTG_BOARDS; i++) {
+               struct rtggfxboard *gb = &rtggfxboards[i];
+               gfxboard_free_board(gb);
        }
-       gfxboard_free();
-       if (gb->board) {
-               if (gb->board->configtype == 3)
-                       gfxboard_bank_memory.wput = gfxboard_wput_mem_autoconfig;
-               if (reset_func) 
-                       reset_func (reset_parm);
+}
+
+void gfxboard_reset (void)
+{
+       rtg_initial = -1;
+       for (int i = 0; i < MAX_RTG_BOARDS; i++) {
+               struct rtggfxboard *gb = &rtggfxboards[i];
+               gb->rbc = &currprefs.rtgboards[gb->rtg_index];
+               if (gb->rbc->rtgmem_type == GFXBOARD_A2410) {
+                       tms_reset();
+               } else {
+                       if (gb->rbc->rtgmem_type >= GFXBOARD_HARDWARE) {
+                               gb->board = &boards[gb->rbc->rtgmem_type - GFXBOARD_HARDWARE];
+                       }
+                       gfxboard_free_board(gb);
+                       if (gb->board) {
+                               if (gb->board->configtype == 3)
+                                       gb->gfxboard_bank_memory.wput = gfxboard_wput_mem_autoconfig;
+                               if (reset_func) 
+                                       reset_func (reset_parm);
+                       }
+               }
        }
 }
 
@@ -2157,7 +2379,7 @@ int gfxboard_get_configtype(struct rtgboardconfig *rbc)
                return 2;
        if (type == GFXBOARD_UAE_Z3)
                return 3;
-       struct rtggfxboard *gb = &rtggfxboards[0];
+       struct rtggfxboard *gb = &rtggfxboards[rbc->rtg_index];
        gb->board = &boards[type - GFXBOARD_HARDWARE];
        return gb->board->configtype;
 }
@@ -2167,7 +2389,7 @@ bool gfxboard_need_byteswap (struct rtgboardconfig *rbc)
        int type = rbc->rtgmem_type;
        if (type < GFXBOARD_HARDWARE)
                return false;
-       struct rtggfxboard *gb = &rtggfxboards[0];
+       struct rtggfxboard *gb = &rtggfxboards[rbc->rtg_index];
        gb->board = &boards[type - GFXBOARD_HARDWARE];
        return gb->board->swap;
 }
@@ -2185,7 +2407,7 @@ int gfxboard_get_vram_min (struct rtgboardconfig *rbc)
        int type = rbc->rtgmem_type;
        if (type < GFXBOARD_HARDWARE)
                return -1;
-       struct rtggfxboard *gb = &rtggfxboards[0];
+       struct rtggfxboard *gb = &rtggfxboards[rbc->rtg_index];
        gb->board = &boards[type - GFXBOARD_HARDWARE];
        return gb->board->vrammin;
 }
@@ -2195,7 +2417,7 @@ int gfxboard_get_vram_max (struct rtgboardconfig *rbc)
        int type = rbc->rtgmem_type;
        if (type < GFXBOARD_HARDWARE)
                return -1;
-       struct rtggfxboard *gb = &rtggfxboards[0];
+       struct rtggfxboard *gb = &rtggfxboards[rbc->rtg_index];
        gb->board = &boards[type - GFXBOARD_HARDWARE];
        return gb->board->vrammax;
 }
@@ -2205,7 +2427,7 @@ bool gfxboard_is_registers (struct rtgboardconfig *rbc)
        int type = rbc->rtgmem_type;
        if (type < 2)
                return false;
-       struct rtggfxboard *gb = &rtggfxboards[0];
+       struct rtggfxboard *gb = &rtggfxboards[rbc->rtg_index];
        gb->board = &boards[type - 2];
        return gb->board->model_registers != 0;
 }
@@ -2215,7 +2437,7 @@ int gfxboard_num_boards (struct rtgboardconfig *rbc)
        int type = rbc->rtgmem_type;
        if (type < 2)
                return 1;
-       struct rtggfxboard *gb = &rtggfxboards[0];
+       struct rtggfxboard *gb = &rtggfxboards[rbc->rtg_index];
        gb->board = &boards[type - 2];
        if (type == GFXBOARD_PICASSO4_Z2)
                return 3;
@@ -2229,15 +2451,19 @@ uae_u32 gfxboard_get_romtype(struct rtgboardconfig *rbc)
        int type = rbc->rtgmem_type;
        if (type < 2)
                return 0;
-       struct rtggfxboard *gb = &rtggfxboards[0];
+       struct rtggfxboard *gb = &rtggfxboards[rbc->rtg_index];
        gb->board = &boards[type - 2];
        return gb->board->romtype;
 }
 
-static void gfxboard_init (struct rtggfxboard *gb)
+static void gfxboard_init (struct uae_prefs *p, struct rtggfxboard *gb)
 {
        if (!gb->automemory)
                gb->automemory = xmalloc (uae_u8, GFXBOARD_AUTOCONFIG_SIZE);
+       struct rtgboardconfig *rbc = &p->rtgboards[gb->rtg_index];
+       gb->rbc = rbc;
+       gb->gfxmem_bank = gfxmem_banks[gb->rtg_index];
+       gb->gfxmem_bank->mask = gb->rbc->rtgmem_size - 1;
        memset (gb->automemory, 0xff, GFXBOARD_AUTOCONFIG_SIZE);
        gb->p4z2 = false;
        zfile_fclose (gb->p4rom);
@@ -2295,13 +2521,21 @@ static void ew (struct rtggfxboard *gb, int addr, uae_u32 value)
        }
 }
 
-addrbank *gfxboard_init_memory (int devnum)
+bool gfxboard_init_memory (struct autoconfig_info *aci)
 {
-       struct rtggfxboard *gb = &rtggfxboards[0];
+       struct rtggfxboard *gb = &rtggfxboards[aci->devnum];
        int bank;
        uae_u8 z2_flags, z3_flags, type;
+       struct uae_prefs *p = aci->prefs;
+
+       gb->rtg_index = aci->devnum;
+       gfxboard_init (aci->prefs, gb);
 
-       gfxboard_init (gb);
+       total_active_gfx_boards = 0;
+       for (int i = 0; i < MAX_RTG_BOARDS; i++) {
+               if (p->rtgboards[i].rtgmem_size && p->rtgboards[i].rtgmem_type >= GFXBOARD_HARDWARE)
+                       total_active_gfx_boards++;
+       }
 
        memset (gb->automemory, 0xff, GFXBOARD_AUTOCONFIG_SIZE);
        
@@ -2338,10 +2572,10 @@ addrbank *gfxboard_init_memory (int devnum)
                TCHAR path[MAX_DPATH];
                fetch_rompath (path, sizeof path / sizeof (TCHAR));
 
-               gb->p4rom = read_device_rom(&currprefs, ROMTYPE_PICASSOIV, 0, roms);
+               gb->p4rom = read_device_rom(p, ROMTYPE_PICASSOIV, 0, roms);
 
-               if (!gb->p4rom && currprefs.picassoivromfile[0] && zfile_exists(currprefs.picassoivromfile))
-                       gb->p4rom = read_rom_name(currprefs.picassoivromfile);
+               if (!gb->p4rom && p->picassoivromfile[0] && zfile_exists(p->picassoivromfile))
+                       gb->p4rom = read_rom_name(p->picassoivromfile);
 
                if (!gb->p4rom && rl)
                        gb->p4rom = read_rom(rl->rd);
@@ -2376,40 +2610,79 @@ addrbank *gfxboard_init_memory (int devnum)
        _stprintf (gb->lbsmemorybankname, _T("%s VRAM LONGSWAP"), gb->board->name);
        _stprintf (gb->regbankname, _T("%s REG"), gb->board->name);
 
-       gfxboard_bank_memory.name = gb->memorybankname;
-       gfxboard_bank_memory_nojit.name = gb->memorybankname;
-       gfxboard_bank_wbsmemory.name = gb->wbsmemorybankname;
-       gfxboard_bank_lbsmemory.name = gb->lbsmemorybankname;
-       gfxboard_bank_registers.name = gb->regbankname;
+       memcpy(&gb->gfxboard_bank_memory, &tmpl_gfxboard_bank_memory, sizeof addrbank);
+       memcpy(&gb->gfxboard_bank_wbsmemory, &tmpl_gfxboard_bank_wbsmemory, sizeof addrbank);
+       memcpy(&gb->gfxboard_bank_lbsmemory, &tmpl_gfxboard_bank_lbsmemory, sizeof addrbank);
+       memcpy(&gb->gfxboard_bank_nbsmemory, &tmpl_gfxboard_bank_nbsmemory, sizeof addrbank);
+       memcpy(&gb->gfxboard_bank_registers, &tmpl_gfxboard_bank_registers, sizeof addrbank);
+       memcpy(&gb->gfxboard_bank_special, &tmpl_gfxboard_bank_special, sizeof addrbank);
+       memcpy(&gb->gfxboard_bank_memory_nojit, &tmpl_gfxboard_bank_memory_nojit, sizeof addrbank);
+       
+       gb->gfxboard_bank_memory.name = gb->memorybankname;
+       gb->gfxboard_bank_memory_nojit.name = gb->memorybankname;
+       gb->gfxboard_bank_wbsmemory.name = gb->wbsmemorybankname;
+       gb->gfxboard_bank_lbsmemory.name = gb->lbsmemorybankname;
+       gb->gfxboard_bank_registers.name = gb->regbankname;
+
+       gb->gfxboard_bank_memory.bget = gfxboard_bget_mem_autoconfig;
+       gb->gfxboard_bank_memory.bput = gfxboard_bput_mem_autoconfig;
+       gb->gfxboard_bank_memory.wput = gfxboard_wput_mem_autoconfig;
+
+       aci->label = gb->board->name;
+       if (gb->rbc->rtgmem_type == GFXBOARD_VGA) {
+               aci->addrbank = &expamem_nonautoconfig;
+       } else {
+               aci->addrbank = &gb->gfxboard_bank_memory;
+       }
+       aci->parent = aci;
+       gb->configured_mem = -1;
+       if (!aci->doinit) {
+               if (gb->rbc->rtgmem_type == GFXBOARD_VGA) {
+                       static const int parent[] = { ROMTYPE_A1060, ROMTYPE_A2088, ROMTYPE_A2088T, ROMTYPE_A2286, ROMTYPE_A2386, 0 };
+                       aci->parent_romtype = parent;
+               } else {
+                       memcpy(aci->autoconfig_raw, gb->automemory, sizeof aci->autoconfig_raw);
+               }
+               return true;
+       }
 
-       gfxboard_bank_memory.bget = gfxboard_bget_mem_autoconfig;
-       gfxboard_bank_memory.bput = gfxboard_bput_mem_autoconfig;
+       gb->active = true;
 
        if (gb->rbc->rtgmem_type == GFXBOARD_VGA) {
                init_board(gb);
                gb->configured_mem = 1;
                gb->configured_regs = 1;
-               return &expamem_null;
+               return true;
        }
 
-       return &gfxboard_bank_memory;
+       return true;
 }
 
-addrbank *gfxboard_init_memory_p4_z2 (int devnum)
+bool gfxboard_init_memory_p4_z2 (struct autoconfig_info *aci)
 {
-       struct rtggfxboard *gb = &rtggfxboards[0];
-       if (gb->board->configtype == 3)
-               return &expamem_null;
-
+       struct rtggfxboard *gb = &rtggfxboards[aci->devnum];
+       if (gb->board->configtype == 3) {
+               aci->addrbank = &expamem_null;
+               return true;
+       }
        copyp4autoconfig (gb, 64);
-       return &gfxboard_bank_memory;
+       memcpy(&gb->gfxboard_bank_memory, &tmpl_gfxboard_bank_memory, sizeof addrbank);
+       gb->gfxboard_bank_memory.bget = gfxboard_bget_mem_autoconfig;
+       gb->gfxboard_bank_memory.bput = gfxboard_bput_mem_autoconfig;
+       memcpy(aci->autoconfig_raw, gb->automemory, sizeof aci->autoconfig_raw);
+       aci->addrbank = &gb->gfxboard_bank_memory;
+       aci->label = gb->board->name;
+       aci->parent_of_previous = true;
+       return true;
 }
 
-addrbank *gfxboard_init_registers (int devnum)
+bool gfxboard_init_registers (struct autoconfig_info *aci)
 {
-       struct rtggfxboard *gb = &rtggfxboards[0];
-       if (!gb->board->model_registers)
-               return &expamem_null;
+       struct rtggfxboard *gb = &rtggfxboards[aci->devnum];
+       if (!gb->board->model_registers) {
+               aci->addrbank = &expamem_null;
+               return true;
+       }
 
        memset (gb->automemory, 0xff, GFXBOARD_AUTOCONFIG_SIZE);
        ew (gb, 0x00, 0xc0 | 0x01); // 64k Z2
@@ -2423,18 +2696,24 @@ addrbank *gfxboard_init_registers (int devnum)
        ew (gb, 0x20, ser >>  8); /* ser.no. Byte 2 */
        ew (gb, 0x24, ser >>  0); /* ser.no. Byte 3 */
 
-       gfxboard_bank_registers.allocated = BOARD_REGISTERS_SIZE;
+       gb->gfxboard_bank_registers.allocated = BOARD_REGISTERS_SIZE;
+       gb->configured_regs = -1;
 
        if (ISP4()) {
                uae_u8 v;
                copyp4autoconfig (gb, 128);
                loadp4rom (gb);
                v = (((gb->automemory[0] & 0xf0) | (gb->automemory[2] >> 4)) & 3) - 1;
-               gfxboard_bank_special.allocated = 0x10000 << v;
+               gb->gfxboard_bank_special.allocated = 0x10000 << v;
        }
 
-       gfxboard_bank_registers.bget = gfxboard_bget_regs_autoconfig;
-       gfxboard_bank_registers.bput = gfxboard_bput_regs_autoconfig;
+       gb->gfxboard_bank_registers.bget = gfxboard_bget_regs_autoconfig;
+       gb->gfxboard_bank_registers.bput = gfxboard_bput_regs_autoconfig;
 
-       return &gfxboard_bank_registers;
+       memcpy(aci->autoconfig_raw, gb->automemory, sizeof aci->autoconfig_raw);
+       aci->label = gb->board->name;
+
+       aci->addrbank = &gb->gfxboard_bank_registers;
+       aci->parent_of_previous = true;
+       return true;
 }
index bb19121bd06308a5564642463e80aa52383352d5..fc943814063082d75a8612efe6d356b501395f57 100644 (file)
@@ -1957,11 +1957,12 @@ void hardfile_do_disk_change (struct uaedev_config_data *uci, bool insert)
        int fsid = uci->configoffset;
        struct hardfiledata *hfd;
 
-       if (uci->ci.controller_type == HD_CONTROLLER_TYPE_PCMCIA_SRAM) {
-               gayle_modify_pcmcia_sram_unit (&uci->ci, insert);
-               return;
-       } else if (uci->ci.controller_type == HD_CONTROLLER_TYPE_PCMCIA_IDE) {
-               gayle_modify_pcmcia_ide_unit (&uci->ci, insert);
+       if (uci->ci.controller_type == HD_CONTROLLER_TYPE_PCMCIA) {
+               if (uci->ci.controller_type_unit == 0) {
+                       gayle_modify_pcmcia_sram_unit (&uci->ci, insert);
+               } else {
+                       gayle_modify_pcmcia_ide_unit (&uci->ci, insert);
+               }
                return;
        }
        hfd = get_hardfile_data (fsid);
index 575fe735285ac2878d5659e2932158680466631f..dc6c2545e01329671e4ff95ba534201c9b83cf45 100644 (file)
@@ -1233,14 +1233,22 @@ static const uae_u8 gvp_ide2_rom_autoconfig[16] = { 0xd1, 0x0d, 0x00, 0x00, 0x07
 static const uae_u8 gvp_ide2_controller_autoconfig[16] = { 0xc1, 0x0b, 0x00, 0x00, 0x07, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
 static const uae_u8 gvp_ide1_controller_autoconfig[16] = { 0xd1, 0x08, 0x00, 0x00, 0x07, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00 };
 
-addrbank *gvp_ide_rom_autoconfig_init(struct romconfig *rc)
+bool gvp_ide_rom_autoconfig_init(struct autoconfig_info *aci)
 {
-       struct ide_board *ide = getide(rc);
        const uae_u8 *autoconfig;
+       if (ISCPUBOARD(BOARD_GVP, BOARD_GVP_SUB_A3001SI)) {
+               autoconfig = gvp_ide1_controller_autoconfig;
+       } else {
+               autoconfig = gvp_ide2_rom_autoconfig;
+       }
+       aci->autoconfigp = autoconfig;
+       if (!aci->doinit)
+               return true;
+
+       struct ide_board *ide = getide(aci->rc);
 
        if (ISCPUBOARD(BOARD_GVP, BOARD_GVP_SUB_A3001SI)) {
                ide->bank = &gvp_ide_rom_bank;
-               autoconfig = gvp_ide1_controller_autoconfig;
                init_ide(ide, GVP_IDE, 2, true, false);
                ide->rom_size = 8192;
                gvp_ide_controller_board->intena = true;
@@ -1248,7 +1256,6 @@ addrbank *gvp_ide_rom_autoconfig_init(struct romconfig *rc)
                gvp_ide_controller_board->configured = -1;
        } else {
                ide->bank = &gvp_ide_rom_bank;
-               autoconfig = gvp_ide2_rom_autoconfig;
                ide->rom_size = 16384;
        }
        ide->configured = 0;
@@ -1261,17 +1268,22 @@ addrbank *gvp_ide_rom_autoconfig_init(struct romconfig *rc)
        memset(ide->rom, 0xff, ide->rom_size);
        ide->rom_mask = ide->rom_size - 1;
 
-       load_rom_rc(rc, ROMTYPE_CB_A3001S1, ide->rom_size, 0, ide->rom, ide->rom_size, LOADROM_FILL);
+       load_rom_rc(aci->rc, ROMTYPE_CB_A3001S1, ide->rom_size, 0, ide->rom, ide->rom_size, LOADROM_FILL);
        for (int i = 0; i < 16; i++) {
                uae_u8 b = autoconfig[i];
                ew(ide, i * 4, b);
        }
-       return ide->bank;
+       aci->addrbank = ide->bank;
+       return true;
 }
 
-addrbank *gvp_ide_controller_autoconfig_init(struct romconfig *rc)
+bool gvp_ide_controller_autoconfig_init(struct autoconfig_info *aci)
 {
-       struct ide_board *ide = getide(rc);
+       if (!aci->doinit) {
+               aci->autoconfigp = gvp_ide2_controller_autoconfig;
+               return true;
+       }
+       struct ide_board *ide = getide(aci->rc);
 
        init_ide(ide, GVP_IDE, 2, true, false);
        ide->configured = 0;
@@ -1281,7 +1293,8 @@ addrbank *gvp_ide_controller_autoconfig_init(struct romconfig *rc)
                uae_u8 b = gvp_ide2_controller_autoconfig[i];
                ew(ide, i * 4, b);
        }
-       return ide->bank;
+       aci->addrbank = ide->bank;
+       return true;
 }
 
 void gvp_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
@@ -1298,13 +1311,17 @@ void gvp_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *r
 static const uae_u8 alf_autoconfig[16] = { 0xd1, 6, 0x00, 0x00, 0x08, 0x2c, 0x00, 0x00, 0x00, 0x00, ALF_ROM_OFFSET >> 8, ALF_ROM_OFFSET & 0xff };
 static const uae_u8 alfplus_autoconfig[16] = { 0xd1, 38, 0x00, 0x00, 0x08, 0x2c, 0x00, 0x00, 0x00, 0x00, ALF_ROM_OFFSET >> 8, ALF_ROM_OFFSET & 0xff };
 
-addrbank *alf_init(struct romconfig *rc)
+bool alf_init(struct autoconfig_info *aci)
 {
-       struct ide_board *ide = getide(rc);
        bool alfplus = cfgfile_board_enabled(&currprefs, ROMTYPE_ALFAPLUS, 0);
+       if (!aci->doinit) {
+               aci->autoconfigp = alfplus ? alfplus_autoconfig : alf_autoconfig;
+               return true;
+       }
 
+       struct ide_board *ide = getide(aci->rc);
        if (!ide)
-               return &expamem_null;
+               return false;
 
        ide->configured = 0;
 
@@ -1327,8 +1344,8 @@ addrbank *alf_init(struct romconfig *rc)
                ew(ide, i * 4, b);
        }
 
-       if (!rc->autoboot_disabled) {
-               struct zfile *z = read_device_from_romconfig(rc, alfplus ? ROMTYPE_ALFAPLUS : ROMTYPE_ALFA);
+       if (!aci->rc->autoboot_disabled) {
+               struct zfile *z = read_device_from_romconfig(aci->rc, alfplus ? ROMTYPE_ALFAPLUS : ROMTYPE_ALFA);
                if (z) {
                        for (int i = 0; i < 0x1000 / 2; i++) {
                                uae_u8 b;
@@ -1347,7 +1364,8 @@ addrbank *alf_init(struct romconfig *rc)
                        zfile_fclose(z);
                }
        }
-       return ide->bank;
+       aci->addrbank = ide->bank;
+       return true;
 }
 
 void alf_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
@@ -1363,13 +1381,25 @@ const uae_u8 apollo_autoconfig[16] = { 0xd1, 0x22, 0x00, 0x00, 0x22, 0x22, 0x00,
 const uae_u8 apollo_autoconfig_cpuboard[16] = { 0xd2, 0x23, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, APOLLO_ROM_OFFSET >> 8, APOLLO_ROM_OFFSET & 0xff };
 const uae_u8 apollo_autoconfig_cpuboard_060[16] = { 0xd2, 0x23, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x02, APOLLO_ROM_OFFSET >> 8, APOLLO_ROM_OFFSET & 0xff };
 
-static addrbank *apollo_init(struct romconfig *rc, bool cpuboard)
+static bool apollo_init(struct autoconfig_info *aci, bool cpuboard)
 {
-       struct ide_board *ide = getide(rc);
-       const uae_u8 *autoconfig;
+       const uae_u8 *autoconfig = apollo_autoconfig;
+       if (cpuboard) {
+               if (currprefs.cpu_model == 68060)
+                       autoconfig = apollo_autoconfig_cpuboard_060;
+               else
+                       autoconfig = apollo_autoconfig_cpuboard;
+       }
+
+       if (!aci->doinit) {
+               aci->autoconfigp = autoconfig;
+               return true;
+       }
+
+       struct ide_board *ide = getide(aci->rc);
 
        if (!ide)
-               return &expamem_null;
+               return false;
 
        ide->configured = 0;
        ide->bank = &ide_bank_generic;
@@ -1382,20 +1412,13 @@ static addrbank *apollo_init(struct romconfig *rc, bool cpuboard)
        memset(ide->rom, 0xff, ide->rom_size);
        ide->rom_mask = ide->rom_size - 1;
        ide->keepautoconfig = false;
-       autoconfig = apollo_autoconfig;
-       if (cpuboard) {
-               if (currprefs.cpu_model == 68060)
-                       autoconfig = apollo_autoconfig_cpuboard_060;
-               else
-                       autoconfig = apollo_autoconfig_cpuboard;
-       }
        for (int i = 0; i < 16; i++) {
                uae_u8 b = autoconfig[i];
                ew(ide, i * 4, b);
        }
        if (cpuboard) {
                ide->mask = 131072 - 1;
-               struct zfile *z = read_device_from_romconfig(rc, ROMTYPE_APOLLO);
+               struct zfile *z = read_device_from_romconfig(aci->rc, ROMTYPE_APOLLO);
                if (z) {
                        int len = zfile_size(z);
                        // skip 68060 $f0 ROM block
@@ -1410,18 +1433,19 @@ static addrbank *apollo_init(struct romconfig *rc, bool cpuboard)
                }
        } else {
                ide->mask = 65536 - 1;
-               load_rom_rc(rc, ROMTYPE_APOLLO, 16384, 0, ide->rom, 32768, LOADROM_EVENONLY_ODDONE | LOADROM_FILL);
+               load_rom_rc(aci->rc, ROMTYPE_APOLLO, 16384, 0, ide->rom, 32768, LOADROM_EVENONLY_ODDONE | LOADROM_FILL);
        }
-       return ide->bank;
+       aci->addrbank = ide->bank;
+       return true;
 }
 
-addrbank *apollo_init_hd(struct romconfig *rc)
+bool apollo_init_hd(struct autoconfig_info *aci)
 {
-       return apollo_init(rc, false);
+       return apollo_init(aci, false);
 }
-addrbank *apollo_init_cpu(struct romconfig *rc)
+bool apollo_init_cpu(struct autoconfig_info *aci)
 {
-       return apollo_init(rc, true);
+       return apollo_init(aci, true);
 }
 
 void apollo_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
@@ -1429,35 +1453,46 @@ void apollo_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig
        add_ide_standard_unit(ch, ci, rc, apollo_board, APOLLO_IDE, true, false, 2);
 }
 
-addrbank *masoboshi_init(struct romconfig *rc)
+bool masoboshi_init(struct autoconfig_info *aci)
 {
-       struct ide_board *ide = getide(rc);
+       int rom_size = 65536;
+       uae_u8 *rom = xcalloc(uae_u8, rom_size);
+       memset(rom, 0xff, rom_size);
+
+       load_rom_rc(aci->rc, ROMTYPE_MASOBOSHI, 32768, 0, rom, 65536, LOADROM_EVENONLY_ODDONE | LOADROM_FILL);
+       if (!aci->doinit) {
+               if (aci->rc && aci->rc->autoboot_disabled)
+                       memcpy(aci->autoconfig_raw, rom + 0x100, sizeof aci->autoconfig_raw);
+               else
+                       memcpy(aci->autoconfig_raw, rom + 0x000, sizeof aci->autoconfig_raw);
+               xfree(rom);
+               return true;
+       }
+
+       struct ide_board *ide = getide(aci->rc);
 
        if (!ide)
-               return &expamem_null;
+               return false;
 
        ide->configured = 0;
 
        ide->configured = 0;
        ide->bank = &ide_bank_generic;
        ide->type = MASOBOSHI_IDE;
-       ide->rom_size = 65536;
-       ide->mask = 65536 - 1;
+       ide->rom_size = rom_size;
+       ide->mask = rom_size - 1;
        ide->subtype = 0;
 
-       ide->rom = xcalloc(uae_u8, ide->rom_size);
-       memset(ide->rom, 0xff, ide->rom_size);
-       memset(ide->acmemory, 0xff, sizeof ide->acmemory);
-       ide->rom_mask = ide->rom_size - 1;
-
-       load_rom_rc(rc, ROMTYPE_MASOBOSHI, 32768, 0, ide->rom, 65536, LOADROM_EVENONLY_ODDONE | LOADROM_FILL);
-       ide->subtype = rc->subtype;
-       if (rc && rc->autoboot_disabled)
+       ide->subtype = aci->rc->subtype;
+       if (aci->rc && aci->rc->autoboot_disabled)
                memcpy(ide->acmemory, ide->rom + 0x100, sizeof ide->acmemory);
        else
                memcpy(ide->acmemory, ide->rom + 0x000, sizeof ide->acmemory);
 
-       return ide->bank;
+       memset(ide->acmemory, 0xff, sizeof ide->acmemory);
+
+       aci->addrbank =ide->bank;
+       return true;
 }
 
 static void masoboshi_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
@@ -1480,9 +1515,13 @@ void masoboshi_add_idescsi_unit (int ch, struct uaedev_config_info *ci, struct r
 
 static const uae_u8 adide_autoconfig[16] = { 0xd1, 0x02, 0x00, 0x00, 0x08, 0x17, 0x00, 0x00, 0x00, 0x00, ADIDE_ROM_OFFSET >> 8, ADIDE_ROM_OFFSET & 0xff };
 
-addrbank *adide_init(struct romconfig *rc)
+bool adide_init(struct autoconfig_info *aci)
 {
-       struct ide_board *ide = getide(rc);
+       if (!aci->doinit) {
+               aci->autoconfigp = adide_autoconfig;
+               return true;
+       }
+       struct ide_board *ide = getide(aci->rc);
 
        ide->configured = 0;
        ide->keepautoconfig = false;
@@ -1495,14 +1534,15 @@ addrbank *adide_init(struct romconfig *rc)
        ide->rom = xcalloc(uae_u8, ide->rom_size);
        memset(ide->rom, 0xff, ide->rom_size);
        ide->rom_mask = ide->rom_size - 1;
-       if (!rc->autoboot_disabled) {
-               load_rom_rc(rc, ROMTYPE_ADIDE, 16384, 0, ide->rom, 32768, LOADROM_EVENONLY_ODDONE | LOADROM_FILL);
+       if (!aci->rc->autoboot_disabled) {
+               load_rom_rc(aci->rc, ROMTYPE_ADIDE, 16384, 0, ide->rom, 32768, LOADROM_EVENONLY_ODDONE | LOADROM_FILL);
        }
        for (int i = 0; i < 16; i++) {
                uae_u8 b = adide_autoconfig[i];
                ew(ide, i * 4, b);
        }
-       return ide->bank;
+       aci->addrbank = ide->bank;
+       return true;
 }
 
 void adide_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
@@ -1510,21 +1550,33 @@ void adide_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig
        add_ide_standard_unit(ch, ci, rc, adide_board, ADIDE_IDE, false, true, 2);
 }
 
-addrbank *mtec_init(struct romconfig *rc)
+bool mtec_init(struct autoconfig_info *aci)
 {
-       struct ide_board *ide = getide(rc);
+       uae_u8 *rom;
+       int rom_size = 32768;
+
+       rom = xcalloc(uae_u8, rom_size);
+       memset(rom, 0xff, rom_size);
+       load_rom_rc(aci->rc, ROMTYPE_MTEC, 16384, !aci->rc->autoboot_disabled ? 16384 : 0, rom, 32768, LOADROM_EVENONLY_ODDONE | LOADROM_FILL);
+
+       if (!aci->doinit) {
+               memcpy(aci->autoconfig_raw, rom, sizeof aci->autoconfig_raw);
+               xfree(rom);
+               return true;
+       }
+
+       struct ide_board *ide = getide(aci->rc);
 
        ide->configured = 0;
        ide->bank = &ide_bank_generic;
-       ide->rom_size = 32768;
        ide->mask = 65536 - 1;
 
-       ide->rom = xcalloc(uae_u8, ide->rom_size);
-       memset(ide->rom, 0xff, ide->rom_size);
-       ide->rom_mask = ide->rom_size - 1;
-       load_rom_rc(rc, ROMTYPE_MTEC, 16384, !rc->autoboot_disabled ? 16384 : 0, ide->rom, 32768, LOADROM_EVENONLY_ODDONE | LOADROM_FILL);
+       ide->rom = rom;
+       ide->rom_size = rom_size;
        memcpy(ide->acmemory, ide->rom, sizeof ide->acmemory);
-       return ide->bank;
+
+       aci->addrbank = ide->bank;
+       return true;
 }
 
 void mtec_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
@@ -1532,22 +1584,27 @@ void mtec_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *
        add_ide_standard_unit(ch, ci, rc, mtec_board, MTEC_IDE, false, false, 2);
 }
 
-addrbank *rochard_init(struct romconfig *rc)
+bool rochard_init(struct autoconfig_info *aci)
 {
-       struct ide_board *ide = getide(rc);
+       if (!aci->doinit) {
+               load_rom_rc(aci->rc, ROMTYPE_ROCHARD, 8192, !aci->rc->autoboot_disabled ? 8192 : 0, aci->autoconfig_raw, sizeof aci->autoconfig_raw, 0);
+               return true;
+       }
+       struct ide_board *ide = getide(aci->rc);
 
        ide->configured = 0;
        ide->bank = &ide_bank_generic;
        ide->rom_size = 32768;
        ide->mask = 65536 - 1;
-       ide->subtype = rc->subtype;
+       ide->subtype = aci->rc->subtype;
 
        ide->rom = xcalloc(uae_u8, ide->rom_size);
        memset(ide->rom, 0xff, ide->rom_size);
        ide->rom_mask = ide->rom_size - 1;
-       load_rom_rc(rc, ROMTYPE_ROCHARD, 8192, !rc->autoboot_disabled ? 8192 : 0, ide->rom, 16384, 0);
+       load_rom_rc(aci->rc, ROMTYPE_ROCHARD, 8192, !aci->rc->autoboot_disabled ? 8192 : 0, ide->rom, 16384, 0);
        memcpy(ide->acmemory, ide->rom, sizeof ide->acmemory);
-       return ide->bank;
+       aci->addrbank = ide->bank;
+       return true;
 }
 
 static void rochard_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
@@ -1568,21 +1625,33 @@ void rochard_add_idescsi_unit(int ch, struct uaedev_config_info *ci, struct romc
        }
 }
 
-addrbank *golemfast_init(struct romconfig *rc)
+bool golemfast_init(struct autoconfig_info *aci)
 {
-       struct ide_board *ide = getide(rc);
+       int rom_size = 32768;
+       uae_u8 *rom;
+       
+       rom = xcalloc(uae_u8, rom_size);
+       memset(rom, 0xff, rom_size);
+       load_rom_rc(aci->rc, ROMTYPE_GOLEMFAST, 16384, 0, rom, 32768, 0);
+
+       if (!aci->doinit) {
+               memcpy(aci->autoconfig_raw, rom, sizeof aci->autoconfig_raw);
+               xfree(rom);
+               return true;
+       }
 
+       struct ide_board *ide = getide(aci->rc);
+
+       ide->rom = rom;
        ide->configured = 0;
        ide->bank = &ide_bank_generic;
-       ide->rom_size = 32768;
+       ide->rom_size = rom_size;
        ide->mask = 65536 - 1;
 
-       ide->rom = xcalloc(uae_u8, ide->rom_size);
-       memset(ide->rom, 0xff, ide->rom_size);
        ide->rom_mask = ide->rom_size - 1;
-       load_rom_rc(rc, ROMTYPE_GOLEMFAST, 16384, 0, ide->rom, 32768, 0);
        memcpy(ide->acmemory, ide->rom, sizeof ide->acmemory);
-       return ide->bank;
+       aci->addrbank = ide->bank;
+       return true;
 }
 
 static void golemfast_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
@@ -1605,36 +1674,39 @@ void golemfast_add_idescsi_unit(int ch, struct uaedev_config_info *ci, struct ro
 
 
 extern void x86_xt_ide_bios(struct zfile*, struct romconfig*);
-static addrbank *x86_at_hd_init(struct romconfig *rc, int type)
+static bool x86_at_hd_init(struct autoconfig_info *aci, int type)
 {
-       struct ide_board *ide = getide(rc);
+       static const int parent[] = { ROMTYPE_A1060, ROMTYPE_A2088, ROMTYPE_A2088T, ROMTYPE_A2286, ROMTYPE_A2386, 0 };
+       aci->parent_romtype = parent;
+       if (!aci->doinit)
+               return true;
 
+       struct ide_board *ide = getide(aci->rc);
        if (!ide)
-               return NULL;
+               return false;
 
        ide->intena = type == 0;
        ide->configured = 1;
        ide->bank = &ide_bank_generic;
 
-       struct zfile *f = read_device_from_romconfig(rc, 0);
+       struct zfile *f = read_device_from_romconfig(aci->rc, 0);
        if (f) {
-               x86_xt_ide_bios(f, rc);
+               x86_xt_ide_bios(f, aci->rc);
                zfile_fclose(f);
        }
-
-       return NULL;
+       return true;
 }
-addrbank *x86_at_hd_init_1(struct romconfig *rc)
+bool x86_at_hd_init_1(struct autoconfig_info *aci)
 {
-       return x86_at_hd_init(rc, 0);
+       return x86_at_hd_init(aci, 0);
 }
-addrbank *x86_at_hd_init_2(struct romconfig *rc)
+bool x86_at_hd_init_2(struct autoconfig_info *aci)
 {
-       return x86_at_hd_init(rc, 0);
+       return x86_at_hd_init(aci, 0);
 }
-addrbank *x86_at_hd_init_xt(struct romconfig *rc)
+bool x86_at_hd_init_xt(struct autoconfig_info *aci)
 {
-       return x86_at_hd_init(rc, 1);
+       return x86_at_hd_init(aci, 1);
 }
 
 void x86_add_at_hd_unit_1(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
index 12886d2b586650b59ee09d22ac0084bc3411ef51..543f3558dd58297da51cfc9fec74babeb9dfa9a5 100644 (file)
@@ -10,6 +10,7 @@
 
 #ifdef DEBUGGER
 
+#include "options.h"
 #include "memory.h"
 #include "identify.h"
 
index bced619ade8e0008c643e8f89e6cd34fc8ecc86a..aac3f65e84e2d8c9059661525f0cea31d479a4de 100644 (file)
@@ -3,7 +3,7 @@
 
 #ifdef A2065
 
-extern addrbank *a2065_init (int);
+extern bool a2065_init (struct autoconfig_info *aci);
 extern void a2065_free (void);
 extern void a2065_reset (void);
 extern void a2065_hsync_handler (void);
index f59b488a7d0a90c2f3db973c40c97b484e12bdc2..d26bf498c05f8625f883a4dd699c63fcaf1ee4a4 100644 (file)
@@ -73,13 +73,12 @@ struct wd_state {
        bool enabled;
        int configured;
        bool autoconfig;
-       uae_u8 dmacmemory[100];
+       uae_u8 dmacmemory[128];
        uae_u8 *rom;
        int board_mask;
        uaecptr baseaddress;
        int rombankswitcher, rombank;
        int rom_size, rom_mask;
-       addrbank *bank;
        struct romconfig *rc;
        struct wd_state **self_ptr;
 
@@ -96,6 +95,7 @@ struct wd_state {
        struct wd_chip_state wc;
        struct commodore_dmac cdmac;
        struct gvp_dmac gdmac;
+       addrbank bank;
 };
 extern wd_state *wd_cdtv;
 
@@ -103,21 +103,20 @@ extern void init_wd_scsi (struct wd_state*);
 extern void scsi_dmac_a2091_start_dma (struct wd_state*);
 extern void scsi_dmac_a2091_stop_dma (struct wd_state*);
 
-extern addrbank *a2090_init (struct romconfig*);
+extern bool a2090_init (struct autoconfig_info *aci);
 
-extern addrbank *a2091_init (struct romconfig*);
+extern bool a2091_init (struct autoconfig_info *aci);
 extern void a2091_free(void);
 extern void a2091_reset (void);
 
-extern addrbank *gvp_init_s1(struct romconfig*);
-extern addrbank *gvp_init_s2(struct romconfig*);
-extern addrbank *gvp_init_accelerator(struct romconfig*);
+extern bool gvp_init_s1(struct autoconfig_info *aci);
+extern bool gvp_init_s2(struct autoconfig_info *aci);
+extern bool gvp_init_accelerator(struct autoconfig_info *aci);
 extern void gvp_free(void);
 extern void gvp_reset (void);
 
-extern void a3000scsi_init (void);
+extern bool a3000scsi_init(struct autoconfig_info *aci);
 extern void a3000scsi_free (void);
-extern void a3000scsi_reset (void);
 extern void rethink_a2091 (void);
 
 extern void wdscsi_put (struct wd_chip_state*, wd_state*, uae_u8);
index dd9ea983bcaa58a50370e52e3dfc8ff7aeceed0b..77b38704b57ffb409d49e65fc3d1bf9513d5673e 100644 (file)
 #define PERIOD_MAX ULONG_MAX
 #define MAX_EV ~0u
 
-void aud0_handler (void);
-void aud1_handler (void);
-void aud2_handler (void);
-void aud3_handler (void);
-
 void AUDxDAT (int nr, uae_u16 value);
 void AUDxDAT (int nr, uae_u16 value, uaecptr addr);
 void AUDxVOL (int nr, uae_u16 value);
@@ -31,7 +26,6 @@ uae_u16 audio_dmal (void);
 void audio_state_machine (void);
 uaecptr audio_getpt (int nr, bool reset);
 int init_audio (void);
-void ahi_install (void);
 void audio_reset (void);
 void update_audio (void);
 void audio_evhandler (void);
@@ -47,12 +41,17 @@ void audio_vsync (void);
 void audio_sampleripper(int);
 void write_wavheader (struct zfile *wavfile, uae_u32 size, uae_u32 freq);
 
+bool audio_is_pull(void);
+int audio_pull_buffer(void);
+bool audio_finish_pull(void);
+bool audio_is_pull_event(void);
+bool audio_is_event_frame_possible(int);
+
 extern int sampleripper_enabled;
 
-extern void audio_update_sndboard(unsigned int);
-extern void audio_enable_sndboard(bool);
-extern void audio_state_sndboard(int);
-extern void audio_state_sndboard_state(int, int, unsigned int);
+extern int audio_enable_stream(bool, int, int);
+extern void audio_state_stream(int);
+extern void audio_state_stream_state(int, int*, int, unsigned int);
 
 typedef void (*CDA_CALLBACK)(int);
 extern void audio_cda_new_buffer(uae_s16 *buffer, int length, int userdata, CDA_CALLBACK next_cd_audio_buffer_callback);
@@ -61,12 +60,10 @@ extern void audio_cda_volume(int left, int right);
 extern int sound_cd_volume[2];
 extern int sound_paula_volume[2];
 
+#define AUDIO_CHANNEL_MAX_STREAM_CH 8
+#define AUDIO_CHANNEL_STREAMS 9
+
 #define AUDIO_CHANNELS_PAULA 4
-#define AUDIO_CHANNELS_MAX 8
-#define AUDIO_CHANNEL_SNDBOARD_LEFT 4
-#define AUDIO_CHANNEL_SNDBOARD_RIGHT 5
-#define AUDIO_CHANNEL_CDA_LEFT 6
-#define AUDIO_CHANNEL_CDA_RIGHT 7
 
 enum {
        SND_MONO,
index ccd32fa08cbb99fc013b7d779bee5b16067f3f04..e790af4aecc6590999cbc01279dd8aef28d69756 100644 (file)
@@ -93,10 +93,10 @@ extern uaecptr ROM_hardfile_resname, ROM_hardfile_resid;
 extern uaecptr ROM_hardfile_init;
 extern uaecptr filesys_initcode, filesys_initcode_ptr;
 
-extern int is_hardfile (int unit_no);
-extern int nr_units (void);
-extern int nr_directory_units (struct uae_prefs*);
-extern uaecptr need_uae_boot_rom (void);
+extern int is_hardfile(int unit_no);
+extern int nr_units(void);
+extern int nr_directory_units(struct uae_prefs*);
+extern uaecptr need_uae_boot_rom(struct uae_prefs*);
 
 struct mountedinfo
 {
@@ -108,7 +108,6 @@ struct mountedinfo
        TCHAR rootdir[MAX_DPATH];
 };
 
-extern int add_filesys_unitconfig (struct uae_prefs *p, int index, TCHAR *error);
 extern int get_filesys_unitconfig (struct uae_prefs *p, int index, struct mountedinfo*);
 extern int kill_filesys_unitconfig (struct uae_prefs *p, int nr);
 extern int move_filesys_unitconfig (struct uae_prefs *p, int nr, int to);
@@ -143,17 +142,25 @@ extern uae_u32 uaeboard_demux (uae_u32*);
 extern void expansion_init (void);
 extern void expansion_cleanup (void);
 extern void expansion_clear (void);
-extern void expansion_autoconfig_put(int, uae_u8);
-extern uaecptr expansion_startaddress(uaecptr addr, uae_u32 size);
+extern uaecptr expansion_startaddress(struct uae_prefs*, uaecptr addr, uae_u32 size);
 extern bool expansion_is_next_board_fastram(void);
 extern uaecptr uaeboard_alloc_ram(uae_u32);
 extern uae_u8 *uaeboard_map_ram(uaecptr);
+extern void expansion_scan_autoconfig(struct uae_prefs*, bool);
+extern void expansion_generate_autoconfig_info(struct uae_prefs *p);
+extern struct autoconfig_info *expansion_get_autoconfig_info(struct uae_prefs*, int romtype, int devnum);
+extern struct autoconfig_info *expansion_get_autoconfig_data(struct uae_prefs *p, int index);
+extern struct autoconfig_info *expansion_get_autoconfig_by_address(struct uae_prefs *p, uaecptr addr);
+extern void expansion_set_autoconfig_sort(struct uae_prefs *p);
+extern int expansion_autoconfig_move(struct uae_prefs *p, int index, int direction);
+extern bool alloc_expansion_bank(addrbank *bank, struct autoconfig_info *aci);
+extern void free_expansion_bank(addrbank *bank);
 
 extern void uaegfx_install_code (uaecptr);
 
 extern uae_u32 emulib_target_getcpurate (uae_u32, uae_u32*);
 
-typedef addrbank*(*DEVICE_INIT)(struct romconfig*);
+typedef bool (*DEVICE_INIT)(struct autoconfig_info*);
 typedef void(*DEVICE_ADD)(int, struct uaedev_config_info*, struct romconfig*);
 typedef bool(*E8ACCESS)(int, uae_u32*, int, bool);
 typedef void(*DEVICE_MEMORY_CALLBACK)(struct romconfig*, uae_u8*, int);
@@ -168,6 +175,10 @@ typedef void(*DEVICE_MEMORY_CALLBACK)(struct romconfig*, uae_u8*, int);
 #define EXPANSIONTYPE_X86_BRIDGE 256
 #define EXPANSIONTYPE_CUSTOM_SECONDARY 512
 #define EXPANSIONTYPE_RTG 1024
+#define EXPANSIONTYPE_SOUND 2048
+#define EXPANSIONTYPE_FLOPPY 4096
+#define EXPANSIONTYPE_NET 8192
+#define EXPANSIONTYPE_INTERNAL 16384
 struct expansionboardsettings
 {
        const TCHAR *name;
index a3769848a93f31e9b749e2cd0876a2f4b4d81f19..6292024da9bae3e92361be2007651e60b4876a33 100644 (file)
@@ -70,6 +70,7 @@ struct device_info {
        bool open;
     int type;
     int media_inserted;
+       int audio_playing;
     int removable;
     int write_protected;
     int cylinders;
@@ -115,7 +116,7 @@ typedef uae_u8* (*execscsicmd_in_func)(int, uae_u8*, int, int*);
 typedef int (*execscsicmd_direct_func)(int, struct amigascsi*);
 
 typedef void (*play_subchannel_callback)(uae_u8*, int);
-typedef int (*play_status_callback)(int);
+typedef int (*play_status_callback)(int, int);
 
 typedef int (*pause_func)(int, int);
 typedef int (*stop_func)(int);
index 96adc99efd35bd87e25cf82f9371a78854bfcf7d..cb1c5bd8e70d46b349d14bb47a24b1112f8edd34 100644 (file)
@@ -3,7 +3,7 @@
 
 #include "uae/types.h"
 
-extern addrbank *cd32_fmv_init (uaecptr);
+extern addrbank *cd32_fmv_init (struct autoconfig_info *aci);
 extern void cd32_fmv_reset(void);
 extern void cd32_fmv_free(void);
 extern void rethink_cd32fmv(void);
index 9b90d6f925346b80f886caef3b7b5c74420cac3a..dff4a3055b88bef823e4ab844153dec306bb0a6b 100644 (file)
@@ -7,10 +7,9 @@
 
 extern addrbank dmac_bank;
 
-extern addrbank *cdtv_init (struct romconfig *rc);
+extern bool cdtv_init (struct autoconfig_info *aci);
 extern void cdtv_free (void);
 extern void CDTV_hsync_handler(void);
-extern void cdtv_check_banks (void);
 
 void cdtv_battram_write (int addr, int v);
 uae_u8 cdtv_battram_read (int addr);
@@ -19,7 +18,7 @@ extern void cdtv_loadcardmem (uae_u8*, int);
 extern void cdtv_savecardmem (uae_u8*, int);
 
 extern void cdtv_add_scsi_unit (int ch, struct uaedev_config_info *ci, struct romconfig *rc);
-
+extern bool cdtvscsi_init(struct autoconfig_info *aci);
 
 extern void cdtv_getdmadata (uae_u32*);
 
index 473ae98fdba62a1b3c201ed45c70eb293fb65a43..0fc13dfed804a1f353f61c3e38a9d44f62483fa1 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef UAE_CDTVCR_H
 #define UAE_CDTVCR_H
 
+bool cdtvcr_init(struct autoconfig_info*);
 void cdtvcr_reset(void);
 void cdtvcr_free(void);
 void rethink_cdtvcr(void);
index 1b4ee43a0655f8d3520652efb5dfa2d8272f26c5..1b7e17694a61244711d4cd2613381567b1d84f9a 100644 (file)
@@ -14,7 +14,7 @@
 extern void CIA_reset (void);
 extern void CIA_vsync_prehandler (void);
 extern void CIA_hsync_prehandler (void);
-extern void CIA_hsync_posthandler (bool);
+extern void CIA_hsync_posthandler (bool, bool);
 extern void CIA_handler (void);
 extern void CIAA_tod_inc (int);
 extern void CIAB_tod_handler (int);
index 2b49b2784575720a2d9346f254ced4d0bbc2d02a..fbeee2e58cf4152dd9aebb0352dfdfce9d19f8e7 100644 (file)
@@ -3,7 +3,7 @@
 
 #include "uae/types.h"
 
-extern addrbank *cpuboard_autoconfig_init(struct romconfig*);
+extern bool cpuboard_autoconfig_init(struct autoconfig_info*);
 extern bool cpuboard_maprom(void);
 extern void cpuboard_map(void);
 extern void cpuboard_reset(void);
@@ -44,6 +44,7 @@ void blizzardppc_irq(int level);
 #define BOARD_MEMORY_25BITMEM 6
 #define BOARD_MEMORY_EMATRIX 7
 
+#define ISCPUBOARDP(p, type,subtype) (cpuboards[p->cpuboard_type].id == type && (type < 0 || p->cpuboard_subtype == subtype))
 #define ISCPUBOARD(type,subtype) (cpuboards[currprefs.cpuboard_type].id == type && (type < 0 || currprefs.cpuboard_subtype == subtype))
 
 #define BOARD_ACT 1
index fbf19a7f09a45d8f4553748920bfaafd413eb8bd..154ab287b7e3c6bcad408032887fea5a9ec5a5a2 100644 (file)
@@ -194,6 +194,7 @@ STATIC_INLINE void color_reg_cpy (struct color_entry *dst, struct color_entry *s
 
 #define COLOR_CHANGE_BRDBLANK 0x80000000
 #define COLOR_CHANGE_SHRES_DELAY 0x40000000
+#define COLOR_CHANGE_HSYNC_HACK 0x20000000
 struct color_change {
        int linepos;
        int regno;
@@ -318,6 +319,7 @@ void get_custom_mouse_limits (int *pw, int *ph, int *pdx, int *pdy, int dbl);
 extern void putpixel (uae_u8 *buf, int bpp, int x, xcolnr c8, int opaq);
 extern void allocvidbuffer (struct vidbuffer *buf, int width, int height, int depth);
 extern void freevidbuffer (struct vidbuffer *buf);
+extern void check_prefs_picasso(void);
 
 /* Finally, stuff that shouldn't really be shared.  */
 
index 37c15155edf92449f614c165a4e061ae76416e75..70612b238a8c6b4062ca3212b8e5edea8fc61325 100644 (file)
@@ -91,26 +91,21 @@ struct hd_hardfiledata {
     int ansi_version;
 };
 
-#define HD_CONTROLLER_EXPANSION_MAX 50
-#define HD_CONTROLLER_NEXT_UNIT 200
+#define HD_CONTROLLER_EXPANSION_MAX 120
+#define HD_CONTROLLER_NEXT_UNIT 300
 
 #define HD_CONTROLLER_TYPE_UAE 0
 #define HD_CONTROLLER_TYPE_IDE_AUTO (HD_CONTROLLER_TYPE_UAE + 1)
 #define HD_CONTROLLER_TYPE_IDE_FIRST (HD_CONTROLLER_TYPE_IDE_AUTO)
-#define HD_CONTROLLER_TYPE_IDE_MB (HD_CONTROLLER_TYPE_IDE_FIRST + 1)
-#define HD_CONTROLLER_TYPE_IDE_EXPANSION_FIRST (HD_CONTROLLER_TYPE_IDE_MB + 1)
+#define HD_CONTROLLER_TYPE_IDE_EXPANSION_FIRST (HD_CONTROLLER_TYPE_IDE_FIRST + 1)
 #define HD_CONTROLLER_TYPE_IDE_LAST (HD_CONTROLLER_TYPE_IDE_EXPANSION_FIRST + HD_CONTROLLER_EXPANSION_MAX - 1)
 
 #define HD_CONTROLLER_TYPE_SCSI_AUTO (HD_CONTROLLER_TYPE_IDE_LAST + 1)
 #define HD_CONTROLLER_TYPE_SCSI_FIRST (HD_CONTROLLER_TYPE_SCSI_AUTO)
-#define HD_CONTROLLER_TYPE_SCSI_A3000 (HD_CONTROLLER_TYPE_SCSI_FIRST + 1)
-#define HD_CONTROLLER_TYPE_SCSI_A4000T (HD_CONTROLLER_TYPE_SCSI_A3000 + 1)
-#define HD_CONTROLLER_TYPE_SCSI_CDTV (HD_CONTROLLER_TYPE_SCSI_A4000T + 1)
-#define HD_CONTROLLER_TYPE_SCSI_EXPANSION_FIRST (HD_CONTROLLER_TYPE_SCSI_CDTV + 1)
+#define HD_CONTROLLER_TYPE_SCSI_EXPANSION_FIRST (HD_CONTROLLER_TYPE_SCSI_FIRST + 1)
 #define HD_CONTROLLER_TYPE_SCSI_LAST (HD_CONTROLLER_TYPE_SCSI_EXPANSION_FIRST + HD_CONTROLLER_EXPANSION_MAX - 1)
 
-#define HD_CONTROLLER_TYPE_PCMCIA_SRAM (HD_CONTROLLER_TYPE_SCSI_LAST + 1)
-#define HD_CONTROLLER_TYPE_PCMCIA_IDE (HD_CONTROLLER_TYPE_PCMCIA_SRAM + 1)
+#define HD_CONTROLLER_TYPE_PCMCIA (HD_CONTROLLER_TYPE_SCSI_LAST + 1)
 
 #define FILESYS_VIRTUAL 0
 #define FILESYS_HARDFILE 1
index 7fa086bb132d7ffde355eaa826d49dfd550648e1..c835a5156569adc0c229254fbd04adcf43f37ab9 100644 (file)
@@ -184,8 +184,6 @@ extern bool my_issamepath(const TCHAR *path1, const TCHAR *path2);
 extern bool my_createsoftlink(const TCHAR *path, const TCHAR *target);
 extern bool my_createshortcut(const TCHAR *source, const TCHAR *target, const TCHAR *description);
 
-
-extern char *custom_fsdb_search_dir (const char *dirname, TCHAR *rel);
 extern a_inode *custom_fsdb_lookup_aino_aname (a_inode *base, const TCHAR *aname);
 extern a_inode *custom_fsdb_lookup_aino_nname (a_inode *base, const TCHAR *nname);
 extern int custom_fsdb_used_as_nname (a_inode *base, const TCHAR *nname);
index 7a2819ab50aa316b5d459ae5402c5206c7c8eb33..96a14333e75263df91800eded1ee88d46e763820 100644 (file)
@@ -6,16 +6,20 @@
 extern void gayle_reset (int);
 extern void gayle_hsync (void);
 extern void gayle_free (void);
-extern int gayle_add_ide_unit (int ch, struct uaedev_config_info *ci);
+extern void gayle_add_ide_unit (int ch, struct uaedev_config_info *ci, struct romconfig *rc);
+extern bool gayle_ide_init(struct autoconfig_info*);
 extern int gayle_modify_pcmcia_sram_unit (struct uaedev_config_info*, int insert);
 extern int gayle_modify_pcmcia_ide_unit (struct uaedev_config_info*, int insert);
 extern int gayle_add_pcmcia_sram_unit (struct uaedev_config_info*);
 extern int gayle_add_pcmcia_ide_unit(struct uaedev_config_info*);
-extern int gayle_ne2000_unit(void);
 extern void gayle_free_units (void);
 extern void rethink_gayle (void);
 extern void gayle_map_pcmcia (void);
 extern void check_prefs_changed_gayle(void);
+extern void gayle_add_pcmcia_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
+extern bool gayle_pcmcia_init(struct autoconfig_info*);
+extern bool gayle_init_ne2000_pcmcia(struct autoconfig_info *aci);
+
 
 extern int gary_toenb; // non-existing memory access = bus error.
 extern int gary_timeout; // non-existing memory access = delay
index a22ac2fbb47a0640c4ecc6c06df4a0d963e8f143..20ef6f750a683405a0932ea41a70c55b263289cb 100644 (file)
@@ -1,9 +1,9 @@
 #ifndef UAE_GFXBOARD_H
 #define UAE_GFXBOARD_H
 
-extern addrbank *gfxboard_init_memory (int devnum);
-extern addrbank *gfxboard_init_memory_p4_z2(int devnum);
-extern addrbank *gfxboard_init_registers(int devnum);
+extern bool gfxboard_init_memory (struct autoconfig_info*);
+extern bool gfxboard_init_memory_p4_z2(struct autoconfig_info*);
+extern bool gfxboard_init_registers(struct autoconfig_info*);
 extern void gfxboard_free (void);
 extern void gfxboard_reset (void);
 extern bool gfxboard_vsync_handler (void);
@@ -16,24 +16,31 @@ extern bool gfxboard_need_byteswap (struct rtgboardconfig*);
 extern int gfxboard_get_autoconfig_size(struct rtgboardconfig*);
 extern double gfxboard_get_vsync (void);
 extern void gfxboard_refresh (void);
-extern bool gfxboard_toggle (int mode);
+extern int gfxboard_toggle (int mode, int msg);
 extern int gfxboard_num_boards (struct rtgboardconfig*);
 extern uae_u32 gfxboard_get_romtype(struct rtgboardconfig*);
 extern const TCHAR *gfxboard_get_name(int);
 extern const TCHAR *gfxboard_get_manufacturername(int);
 extern const TCHAR *gfxboard_get_configname(int);
+extern bool gfxboard_allocate_slot(int, int);
+extern void gfxboard_free_slot(int);
+extern bool gfxboard_rtg_enable_initial(int);
+extern void gfxboard_rtg_disable(int);
 
-extern addrbank *tms_init(int devnum);
+extern bool tms_init(struct autoconfig_info *aci);
 extern void tms_free(void);
 extern void tms_reset(void);
 extern void tms_hsync_handler(void);
 extern bool tms_vsync_handler(void);
 extern bool tms_toggle(int);
 
-extern void vga_io_put(int portnum, uae_u8 v);
-extern uae_u8 vga_io_get(int portnum);
-extern void vga_ram_put(int offset, uae_u8 v);
-extern uae_u8 vga_ram_get(int offset);
+extern void vga_io_put(int board, int portnum, uae_u8 v);
+extern uae_u8 vga_io_get(int board, int portnum);
+extern void vga_ram_put(int board, int offset, uae_u8 v);
+extern uae_u8 vga_ram_get(int board, int offset);
+
+void gfxboard_get_a8_vram(int index);
+void gfxboard_free_vram(int index);
 
 #define GFXBOARD_UAE_Z2 0
 #define GFXBOARD_UAE_Z3 1
index 1a087a6b9f0c8175f3c71ab063c8dc87fcce9ead..a2f2e533bb11fc931630f2ebcc92a629610dcb5e 100644 (file)
@@ -66,6 +66,7 @@ struct gui_info
        int fps, idle;
        int fps_color;
     int sndbuf, sndbuf_status;
+       bool sndbuf_avail;
     TCHAR df[4][256];                  /* inserted image */
     uae_u32 crc32[4];                  /* crc32 of image */
 };
index a6dc28c0624cdfdb65443e5b0e71024e73a131d8..c83784558746e26ee568c2717c7200b8df5189b8 100644 (file)
@@ -11,29 +11,29 @@ void idecontroller_rethink(void);
 void idecontroller_hsync(void);
 
 void gvp_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
-addrbank *gvp_ide_rom_autoconfig_init(struct romconfig*);
-addrbank *gvp_ide_controller_autoconfig_init(struct romconfig*);
+bool gvp_ide_rom_autoconfig_init(struct autoconfig_info *aci);
+bool gvp_ide_controller_autoconfig_init(struct autoconfig_info *aci);
 
 void alf_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
-addrbank *alf_init(struct romconfig*);
+bool alf_init(struct autoconfig_info *aci);
 
 void apollo_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
-addrbank *apollo_init_hd(struct romconfig*);
-addrbank *apollo_init_cpu(struct romconfig*);
+bool apollo_init_hd(struct autoconfig_info *aci);
+bool apollo_init_cpu(struct autoconfig_info *aci);
 
 void masoboshi_add_idescsi_unit (int ch, struct uaedev_config_info *ci, struct romconfig *rc);
-addrbank *masoboshi_init(struct romconfig*);
+bool masoboshi_init(struct autoconfig_info *aci);
 
 void adide_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
-addrbank *adide_init(struct romconfig *rc);
+bool adide_init(struct autoconfig_info *aci);
 
 void mtec_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
-addrbank *mtec_init(struct romconfig *rc);
+bool mtec_init(struct autoconfig_info *aci);
 
-addrbank *rochard_init(struct romconfig *rc);
+bool rochard_init(struct autoconfig_info *aci);
 void rochard_add_idescsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 
-addrbank *golemfast_init(struct romconfig *rc);
+bool golemfast_init(struct autoconfig_info *aci);
 void golemfast_add_idescsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 
 uae_u32 REGPARAM3 apollo_ide_lget (uaecptr addr) REGPARAM;
@@ -47,11 +47,11 @@ extern const uae_u8 apollo_autoconfig_060[16];
 
 void x86_ide_hd_put(int portnum, uae_u16 v, int);
 uae_u16 x86_ide_hd_get(int portnum, int);
-addrbank *x86_at_hd_init_1(struct romconfig *rc);
+bool x86_at_hd_init_1(struct autoconfig_info *aci);
 void x86_add_at_hd_unit_1(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
-addrbank *x86_at_hd_init_2(struct romconfig *rc);
+bool x86_at_hd_init_2(struct autoconfig_info *aci);
 void x86_add_at_hd_unit_2(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
-addrbank *x86_at_hd_init_xt(struct romconfig *rc);
+bool x86_at_hd_init_xt(struct autoconfig_info *aci);
 void x86_add_at_hd_unit_xt(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 
 #endif /* UAE_IDECONTROLLERS_H */
index 38ba7c57b8b0a0ecf09224ee1ab48edecbcbf138..7b43af144dcb515228d5d53b4a0a61555437f9da 100644 (file)
@@ -90,7 +90,8 @@ struct inputevent {
 #define ID_FLAG_INVERT 32
 #define ID_FLAG_RESERVEDGAMEPORTSCUSTOM 64
 #define ID_FLAG_SET_ONOFF 128
-#define ID_FLAG_SET_ONOFF_VAL 256
+#define ID_FLAG_SET_ONOFF_VAL1 256
+#define ID_FLAG_SET_ONOFF_VAL2 512
 
 #define ID_FLAG_GAMEPORTSCUSTOM_MASK (ID_FLAG_GAMEPORTSCUSTOM1 | ID_FLAG_GAMEPORTSCUSTOM2)
 #define ID_FLAG_AUTOFIRE_MASK (ID_FLAG_TOGGLE | ID_FLAG_INVERTTOGGLE | ID_FLAG_AUTOFIRE)
@@ -113,7 +114,7 @@ struct inputevent {
 #define ID_FLAG_QUALIFIER_MASK      0xfffffff00000000ULL
 #define ID_FLAG_QUALIFIER_MASK_R    0xaaaaaaa00000000ULL
 
-#define ID_FLAG_SAVE_MASK_CONFIG 0x000001ff
+#define ID_FLAG_SAVE_MASK_CONFIG 0x000003ff
 #define ID_FLAG_SAVE_MASK_QUALIFIERS ID_FLAG_QUALIFIER_MASK
 #define ID_FLAG_SAVE_MASK_FULL (ID_FLAG_SAVE_MASK_CONFIG | ID_FLAG_SAVE_MASK_QUALIFIERS)
 
@@ -131,7 +132,8 @@ struct inputevent {
 #define IDEV_MAPPED_GAMEPORTSCUSTOM2 32
 #define IDEV_MAPPED_INVERT 64
 #define IDEV_MAPPED_SET_ONOFF 128
-#define IDEV_MAPPED_SET_ONOFF_VAL 256
+#define IDEV_MAPPED_SET_ONOFF_VAL1 256
+#define IDEV_MAPPED_SET_ONOFF_VAL2 512
 
 #define IDEV_MAPPED_QUALIFIER1          0x000000100000000ULL
 #define IDEV_MAPPED_QUALIFIER2          0x000000400000000ULL
@@ -148,8 +150,11 @@ struct inputevent {
 #define IDEV_MAPPED_QUALIFIER_WIN       0x100000000000000ULL
 #define IDEV_MAPPED_QUALIFIER_MASK      0xfffffff00000000ULL
 
-#define SET_ONOFF_ON_VALUE  0x7fffff01
+#define SET_ONOFF_PRESSREL_VALUE 0x7fffff30
+#define SET_ONOFF_PRESS_VALUE 0x7fffff20
+#define SET_ONOFF_ON_VALUE  0x7fffff10
 #define SET_ONOFF_OFF_VALUE 0x7fffff00
+#define SET_ONOFF_MASK_PRESS 15
 
 #define ID_BUTTON_OFFSET 0
 #define ID_BUTTON_TOTAL 32
index 997caf384bdcd3acfca53c27fc717ad00c750085..59f39ddf9f95913011b0924336187dab54b6cb71 100644 (file)
@@ -144,7 +144,8 @@ enum aks { AKS_ENTERGUI = 0x200,
        AKS_TOGGLEDEFAULTSCREEN,
     AKS_TOGGLEWINDOWEDFULLSCREEN, AKS_TOGGLEFULLWINDOWFULLSCREEN, AKS_TOGGLEWINDOWFULLWINDOW,
        AKS_ENTERDEBUGGER, AKS_IRQ7,
-    AKS_PAUSE, AKS_WARP, AKS_INHIBITSCREEN,
+    AKS_PAUSE, AKS_SINGLESTEP,
+       AKS_WARP, AKS_INHIBITSCREEN,
        AKS_STATEREWIND, AKS_STATECURRENT, AKS_STATECAPTURE, 
        AKS_VIDEORECORD,
     AKS_VOLDOWN, AKS_VOLUP, AKS_VOLMUTE,
index ed3bc56d76f82be357012f073da7bd8f5524debc..7c2dead53413c59940952a48706cd68b1013bb6a 100644 (file)
@@ -119,6 +119,34 @@ struct addrbank_sub
        uae_u32 maskval;
 };
 
+struct autoconfig_info
+{
+       struct uae_prefs *prefs;
+       bool doinit;
+       int devnum;
+       uae_u8 autoconfig_raw[128];
+       uae_u8 autoconfig_bytes[16];
+       TCHAR name[128];
+       const uae_u8 *autoconfigp;
+       uae_u32 start;
+       uae_u32 size;
+       int zorro;
+       const TCHAR *label;
+       addrbank *addrbank;
+       struct romconfig *rc;
+       uae_u32 last_high_ram;
+       const struct cpuboardsubtype *cst;
+       const struct expansionromtype *ert;
+       struct autoconfig_info *parent;
+       const int *parent_romtype;
+       bool parent_of_previous;
+       bool parent_address_space;
+       const TCHAR *parent_name;
+       bool can_sort;
+       bool (*get_params)(struct uae_prefs*, struct expansion_params*);
+       bool (*set_params)(struct uae_prefs*, struct expansion_params*);
+};
+
 #define CE_MEMBANK_FAST32 0
 #define CE_MEMBANK_CHIP16 1
 #define CE_MEMBANK_CHIP32 2
@@ -233,6 +261,90 @@ MEMORY_BPUT(name); \
 MEMORY_CHECK(name); \
 MEMORY_XLATE(name);
 
+
+#define MEMORY_ARRAY_LGET(name, index) \
+static uae_u32 REGPARAM3 name ## index ## _lget (uaecptr) REGPARAM; \
+static uae_u32 REGPARAM2 name ## index ## _lget (uaecptr addr) \
+{ \
+       uae_u8 *m; \
+       addr -= name ## _bank[index].start & name ## _bank[index].mask; \
+       addr &= name ## _bank[index].mask; \
+       m = name ## _bank[index].baseaddr + addr; \
+       return do_get_mem_long ((uae_u32 *)m); \
+}
+#define MEMORY_ARRAY_WGET(name, index) \
+static uae_u32 REGPARAM3 name ## index ## _wget (uaecptr) REGPARAM; \
+static uae_u32 REGPARAM2 name ## index ## _wget (uaecptr addr) \
+{ \
+       uae_u8 *m; \
+       addr -= name ## _bank[index].start & name ## _bank[index].mask; \
+       addr &= name ## _bank[index].mask; \
+       m = name ## _bank[index].baseaddr + addr; \
+       return do_get_mem_word ((uae_u16 *)m); \
+}
+#define MEMORY_ARRAY_BGET(name, index) \
+static uae_u32 REGPARAM3 name ## index ## _bget (uaecptr) REGPARAM; \
+static uae_u32 REGPARAM2 name ## index ## _bget (uaecptr addr) \
+{ \
+       addr -= name ## _bank[index].start & name ## _bank[index].mask; \
+       addr &= name ## _bank[index].mask; \
+       return name ## _bank[index].baseaddr[addr]; \
+}
+#define MEMORY_ARRAY_LPUT(name, index) \
+static void REGPARAM3 name ## index ## _lput (uaecptr, uae_u32) REGPARAM; \
+static void REGPARAM2 name ## index ## _lput (uaecptr addr, uae_u32 l) \
+{ \
+       uae_u8 *m;  \
+       addr -= name ## _bank[index].start & name ## _bank[index].mask; \
+       addr &= name ## _bank[index].mask; \
+       m = name ## _bank[index].baseaddr + addr; \
+       do_put_mem_long ((uae_u32 *)m, l); \
+}
+#define MEMORY_ARRAY_WPUT(name, index) \
+static void REGPARAM3 name ## index ## _wput (uaecptr, uae_u32) REGPARAM; \
+static void REGPARAM2 name ## index ## _wput (uaecptr addr, uae_u32 w) \
+{ \
+       uae_u8 *m;  \
+       addr -= name ## _bank[index].start & name ## _bank[index].mask; \
+       addr &= name ## _bank[index].mask; \
+       m = name ## _bank[index].baseaddr + addr; \
+       do_put_mem_word ((uae_u16 *)m, w); \
+}
+#define MEMORY_ARRAY_BPUT(name, index) \
+static void REGPARAM3 name ## index ## _bput (uaecptr, uae_u32) REGPARAM; \
+static void REGPARAM2 name ## index ## _bput (uaecptr addr, uae_u32 b) \
+{ \
+       addr -= name ## _bank[index].start & name ## _bank[index].mask; \
+       addr &= name ## _bank[index].mask; \
+       name ## _bank[index].baseaddr[addr] = b; \
+}
+#define MEMORY_ARRAY_CHECK(name, index) \
+static int REGPARAM3 name ## index ## _check (uaecptr addr, uae_u32 size) REGPARAM; \
+static int REGPARAM2 name ## index ## _check (uaecptr addr, uae_u32 size) \
+{ \
+       addr -= name ## _bank[index].start & name ## _bank[index].mask; \
+       addr &= name ## _bank[index].mask; \
+       return (addr + size) <= name ## _bank[index].allocated; \
+}
+#define MEMORY_ARRAY_XLATE(name, index) \
+static uae_u8 *REGPARAM3 name ## index ## _xlate (uaecptr addr) REGPARAM; \
+static uae_u8 *REGPARAM2 name ## index ## _xlate (uaecptr addr) \
+{ \
+       addr -= name ## _bank[index].start & name ## _bank[index].mask; \
+       addr &= name ## _bank[index].mask; \
+       return name ## _bank[index].baseaddr + addr; \
+}
+
+#define MEMORY_ARRAY_FUNCTIONS(name, index) \
+MEMORY_ARRAY_LGET(name, index); \
+MEMORY_ARRAY_WGET(name, index); \
+MEMORY_ARRAY_BGET(name, index); \
+MEMORY_ARRAY_LPUT(name, index); \
+MEMORY_ARRAY_WPUT(name, index); \
+MEMORY_ARRAY_BPUT(name, index); \
+MEMORY_ARRAY_CHECK(name, index); \
+MEMORY_ARRAY_XLATE(name, index);
+
 extern addrbank chipmem_bank;
 extern addrbank chipmem_agnus_bank;
 extern addrbank chipmem_bank_ce2;
@@ -244,21 +356,17 @@ extern addrbank rtarea_bank;
 extern addrbank filesys_bank;
 extern addrbank uaeboard_bank;
 extern addrbank expamem_bank;
-extern addrbank expamem_null, expamem_none;
-extern addrbank fastmem_bank;
-extern addrbank fastmem_nojit_bank;
-extern addrbank fastmem2_bank;
-extern addrbank fastmem2_nojit_bank;
-extern addrbank gfxmem_bank;
+extern addrbank expamem_null, expamem_none, expamem_nonautoconfig;
+extern addrbank fastmem_bank[MAX_RAM_BOARDS];
+extern addrbank fastmem_nojit_bank[MAX_RAM_BOARDS];
+extern addrbank *gfxmem_banks[MAX_RTG_BOARDS];
 extern addrbank gayle_bank;
 extern addrbank gayle2_bank;
 extern addrbank mbres_bank;
 extern addrbank akiko_bank;
-extern addrbank cdtvcr_bank;
 extern addrbank cardmem_bank;
 extern addrbank bogomem_bank;
-extern addrbank z3fastmem_bank;
-extern addrbank z3fastmem2_bank;
+extern addrbank z3fastmem_bank[MAX_RAM_BOARDS];
 extern addrbank z3chipmem_bank;
 extern addrbank mem25bit_bank;
 extern addrbank a3000lmem_bank;
@@ -277,9 +385,10 @@ extern void expamem_reset (void);
 extern void expamem_next (addrbank *mapped, addrbank *next);
 extern void expamem_shutup (addrbank *mapped);
 extern bool expamem_z3hack(struct uae_prefs*);
-extern void set_expamem_z3_hack_override(bool);
-extern uaecptr expamem_z3_pointer, expamem_z2_pointer;
-extern uae_u32 expamem_z3_size, expamem_z2_size;
+extern void set_expamem_z3_hack_mode(int);
+extern uaecptr expamem_board_pointer, expamem_highmem_pointer;
+extern uaecptr expamem_z3_pointer_real, expamem_z3_pointer_uae;
+extern uae_u32 expamem_board_size;
 
 extern uae_u32 last_custom_value1;
 
@@ -627,9 +736,6 @@ extern void memcpyha (uaecptr dst, const uae_u8 *src, int size);
 extern void memcpyah_safe (uae_u8 *dst, uaecptr src, int size);
 extern void memcpyah (uae_u8 *dst, uaecptr src, int size);
 
-extern uae_s32 getz2size (struct uae_prefs *p);
-uae_u32 getz2endaddr (void);
-
 #define UAE_MEMORY_REGIONS_MAX 64
 #define UAE_MEMORY_REGION_NAME_LENGTH 64
 
index fc4eeb7b8fc91ae956246cb5f9f1ed0a188e2b0c..dce014823cbae001c5bd272c24784a631c981976 100644 (file)
@@ -17,11 +17,11 @@ extern void ematrix_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct
 extern void multievolution_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 extern void golemfast_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 
-extern addrbank *ncr_fastlane_autoconfig_init(struct romconfig*);
-extern addrbank *ncr_oktagon_autoconfig_init(struct romconfig*);
-extern addrbank *ncr_dkb_autoconfig_init(struct romconfig*);
-extern addrbank *ncr_ematrix_autoconfig_init(struct romconfig *rc);
-extern addrbank *ncr_multievolution_init(struct romconfig*);
+extern bool ncr_fastlane_autoconfig_init(struct autoconfig_info *aci);
+extern bool ncr_oktagon_autoconfig_init(struct autoconfig_info *aci);
+extern bool ncr_dkb_autoconfig_init(struct autoconfig_info *aci);
+extern bool ncr_ematrix_autoconfig_init(struct autoconfig_info *aci);
+extern bool ncr_multievolution_init(struct autoconfig_info *aci);
 
 extern void cpuboard_ncr9x_scsi_put(uaecptr, uae_u32);
 extern uae_u32 cpuboard_ncr9x_scsi_get(uaecptr);
index 33f7a05106c5a977b661714e1625ff7cb5026710..258f7a3d9be9739428018575a4e006511f3b38ed 100644 (file)
@@ -18,13 +18,16 @@ extern void ncr_free(void);
 extern void ncr_reset(void);
 extern void ncr_rethink(void);
 
-extern addrbank *ncr710_a4091_autoconfig_init(struct romconfig*);
-extern addrbank *ncr710_warpengine_autoconfig_init(struct romconfig*);
+extern bool ncr710_a4091_autoconfig_init(struct autoconfig_info *aci);
+extern bool ncr710_warpengine_autoconfig_init(struct autoconfig_info *aci);
 
 void cpuboard_ncr710_io_bput(uaecptr addr, uae_u32 v);
 uae_u32 cpuboard_ncr710_io_bget(uaecptr addr);
 
 extern void a4000t_add_scsi_unit (int ch, struct uaedev_config_info *ci, struct romconfig *rc);
+extern bool is_a4000t_scsi(void);
+extern bool a4000t_scsi_init(struct autoconfig_info *aci);
+
 extern void warpengine_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 extern void tekmagic_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 extern void cyberstorm_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
index 2413c62e45f15cb4670e4ec928ff873cd01cd14b..dd0f2bc4fa02389b9dfb0cf5068ad99b6f847b2e 100644 (file)
@@ -600,11 +600,10 @@ extern void exception3_notinstruction(uae_u32 opcode, uaecptr addr);
 extern void exception3i (uae_u32 opcode, uaecptr addr);
 extern void exception3b (uae_u32 opcode, uaecptr addr, bool w, bool i, uaecptr pc);
 extern void exception2 (uaecptr addr, bool read, int size, uae_u32 fc);
-extern void exception2_fake (uaecptr addr);
 extern void m68k_reset (void);
 extern void cpureset (void);
 extern void cpu_halt (int id);
-extern void cpu_sleep_millis(int ms);
+extern int cpu_sleep_millis(int ms);
 
 extern void fill_prefetch (void);
 extern void fill_prefetch_020 (void);
index baca962272c29c204ced28b9049b7fc001861dd8..15ec33c5ac22514c9b24175799f0ae89fa97873d 100644 (file)
@@ -328,7 +328,8 @@ struct gfx_filterdata
 };
 
 #define MAX_DUPLICATE_EXPANSION_BOARDS 4
-#define MAX_EXPANSION_BOARDS 4
+#define MAX_EXPANSION_BOARDS 20
+struct boardromconfig;
 struct romconfig
 {
        TCHAR romfile[MAX_DPATH];
@@ -339,19 +340,37 @@ struct romconfig
        int device_settings;
        int subtype;
        void *unitdata;
+       struct boardromconfig *back;
 };
 #define MAX_BOARD_ROMS 2
 struct boardromconfig
 {
        int device_type;
        int device_num;
+       int device_order;
        struct romconfig roms[MAX_BOARD_ROMS];
 };
 #define MAX_RTG_BOARDS 4
 struct rtgboardconfig
 {
+       int rtg_index;
        int rtgmem_type;
        uae_u32 rtgmem_size;
+       int device_order;
+};
+#define MAX_RAM_BOARDS 4
+struct ramboard
+{
+       uae_u32 size;
+       uae_u16 manufacturer;
+       uae_u8 product;
+       uae_u8 autoconfig[16];
+       bool autoconfig_inuse;
+       int device_order;
+};
+struct expansion_params
+{
+       int device_order;
 };
 
 #define Z3MAPPING_AUTO 0
@@ -604,11 +623,10 @@ struct uae_prefs {
        int picasso96_modeflags;
 
        uae_u32 z3autoconfig_start;
-       uae_u32 z3fastmem_size, z3fastmem2_size;
+       struct ramboard z3fastmem[MAX_RAM_BOARDS];
+       struct ramboard fastmem[MAX_RAM_BOARDS];
        uae_u32 z3chipmem_size;
        uae_u32 z3chipmem_start;
-       uae_u32 fastmem_size, fastmem2_size;
-       bool fastmem_autoconfig;
        uae_u32 chipmem_size;
        uae_u32 bogomem_size;
        uae_u32 mbresmem_low_size;
@@ -628,6 +646,7 @@ struct uae_prefs {
        uae_u32 custom_memory_sizes[MAX_CUSTOM_MEMORY_ADDRS];
        uae_u32 custom_memory_mask[MAX_CUSTOM_MEMORY_ADDRS];
        int uaeboard;
+       int uaeboard_order;
 
        bool kickshifter;
        bool filesys_no_uaefsdb;
@@ -638,10 +657,11 @@ struct uae_prefs {
        bool native_code;
        bool uae_hide_autoconfig;
        int z3_mapping_mode;
-       bool sound_toccata;
-       bool sound_toccata_mixer;
-       bool sound_es1370;
-       bool sound_fm801;
+       bool autoconfig_custom_sort;
+       bool obs_sound_toccata;
+       bool obs_sound_toccata_mixer;
+       bool obs_sound_es1370;
+       bool obs_sound_fm801;
 
        int mountitems;
        struct uaedev_config_data mountconfig[MOUNT_CONFIG_SIZE];
@@ -663,7 +683,8 @@ struct uae_prefs {
        bool win32_logfile;
        bool win32_notaskbarbutton;
        bool win32_nonotificationicon;
-       bool win32_alwaysontop;
+       bool win32_gui_alwaysontop;
+       bool win32_main_alwaysontop;
        bool win32_powersavedisabled;
        bool win32_minimize_inactive;
        int win32_statusbar;
@@ -748,6 +769,7 @@ struct uae_prefs {
        TCHAR input_config_name[GAMEPORT_INPUT_SETTINGS][256];
        int dongle;
        int input_contact_bounce;
+       int input_device_match_mask;
 };
 
 extern int config_changed;
@@ -793,7 +815,7 @@ extern int cfgfile_strval (const TCHAR *option, const TCHAR *value, const TCHAR
 extern int cfgfile_string (const TCHAR *option, const TCHAR *value, const TCHAR *name, TCHAR *location, int maxsz);
 extern TCHAR *cfgfile_subst_path (const TCHAR *path, const TCHAR *subst, const TCHAR *file);
 
-extern TCHAR *target_expand_environment (const TCHAR *path);
+extern TCHAR *target_expand_environment (const TCHAR *path, TCHAR *out, int maxlen);
 extern int target_parse_option (struct uae_prefs *, const TCHAR *option, const TCHAR *value);
 extern void target_save_options (struct zfile*, struct uae_prefs *);
 extern void target_default_options (struct uae_prefs *, int type);
@@ -823,7 +845,9 @@ extern int cfgfile_configuration_change (int);
 extern void fixup_prefs_dimensions (struct uae_prefs *prefs);
 extern void fixup_prefs (struct uae_prefs *prefs, bool userconfig);
 extern void fixup_cpu (struct uae_prefs *prefs);
-bool cfgfile_board_enabled(struct uae_prefs *p, int romtype, int devnum);
+extern bool cfgfile_board_enabled(struct uae_prefs *p, int romtype, int devnum);
+extern void cfgfile_compatibility_romtype(struct uae_prefs *p);
+extern void cfgfile_compatibility_rtg(struct uae_prefs *p);
 
 extern void check_prefs_changed_custom (void);
 extern void check_prefs_changed_cpu (void);
index 6b8d86faf5568f3c7815656d1ced277c5a3bf796..87822d55d86b77d84000516b8e23ba1a84c0ddee 100644 (file)
@@ -7,11 +7,12 @@ extern void pci_hsync(void);
 extern void pci_rethink(void);
 extern void pci_dump(int);
 
-extern addrbank *dkb_wildfire_pci_init(struct romconfig *rc);
-extern addrbank *prometheus_init(struct romconfig *rc);
-extern addrbank *cbvision_init(struct romconfig *rc);;
-extern addrbank *grex_init(struct romconfig *rc);
-extern addrbank *mediator_init(struct romconfig *rc);
-extern addrbank *mediator_init2(struct romconfig *rc);
+extern bool dkb_wildfire_pci_init(struct autoconfig_info *aci);
+extern bool prometheus_init(struct autoconfig_info *aci);
+extern bool cbvision_init(struct autoconfig_info *aci);
+extern bool grex_init(struct autoconfig_info *aci);
+extern bool mediator_init(struct autoconfig_info *aci);
+extern bool mediator_init2(struct autoconfig_info *aci);
+extern bool pci_expansion_init(struct autoconfig_info *aci);
 
 #endif /* UAE_PCI_H */
index d67428daf0514a9b51430b2cc3ce978dff0f54a5..d9eac0b763967a901b219a7070954f4a9a525341 100644 (file)
@@ -108,6 +108,25 @@ extern int decode_cloanto_rom_do (uae_u8 *mem, int size, int real_size);
 #define ROMTYPE_GOLEMFAST      0x00100038
 #define ROMTYPE_PHOENIXB       0x00100039
 #define ROMTYPE_IVSTPRO                0x0010003A
+#define ROMTYPE_TOCCATA                0x0010003B
+#define ROMTYPE_ES1370         0x0010003C
+#define ROMTYPE_FM801          0x0010003D
+#define ROMTYPE_UAESNDZ2       0x0010003E
+#define ROMTYPE_UAESNDZ3       0x0010003F
+#define ROMTYPE_RAMZ2          0x00100040
+#define ROMTYPE_RAMZ3          0x00100041
+#define ROMTYPE_CATWEASEL      0x00100042
+#define ROMTYPE_CDTVSCSI       0x00100043
+#define ROMTYPE_MB_IDE         0x00100044
+#define ROMTYPE_SCSI_A3000     0x00100045
+#define ROMTYPE_SCSI_A4000T    0x00100046
+#define ROMTYPE_MB_PCMCIA      0x00100047
+#define ROMTYPE_MEGACHIP       0x00100048
+#define ROMTYPE_A2065          0x00100049
+#define ROMTYPE_NE2KPCI                0x0010004a
+#define ROMTYPE_NE2KPCMCIA     0x0010004b
+#define ROMTYPE_CDTVDMAC       0x0010004c
+#define ROMTYPE_CDTVCR         0x0010004d
 
 #define ROMTYPE_NOT                    0x00800000
 #define ROMTYPE_QUAD           0x01000000
@@ -212,4 +231,6 @@ struct boardromconfig *get_boardromconfig(struct uae_prefs *p, int romtype, int
 #define LOADROM_ODDFILL(x) ((x << 16) | LOADROM_EVENONLY)
 bool load_rom_rc(struct romconfig *rc, uae_u32 romtype, int maxfilesize, int fileoffset, uae_u8 *rom, int maxromsize, int flags);
 
+#define EXPANSION_ORDER_MAX 10000
+
 #endif /* UAE_ROMMGR_H */
index 83e37562fda3574d295500bb65ac731b8f537f84..af1597cad795c4acdf725e89717699724d2ccc7a 100644 (file)
@@ -209,6 +209,9 @@ extern uae_u8 *save_a3000hram (int *);
 extern uae_u8 *restore_rom (uae_u8 *);
 extern uae_u8 *save_rom (int, int *, uae_u8 *);
 
+extern uae_u8 *save_expansion_info(int*, uae_u8*);
+extern uae_u8 *restore_expansion_info(uae_u8*);
+
 extern uae_u8 *restore_action_replay (uae_u8 *);
 extern uae_u8 *save_action_replay (int *, uae_u8 *);
 extern uae_u8 *restore_hrtmon (uae_u8 *);
index ea71b80d269c218fae689a874a049538b394befc..18aa8ab66cfd70c39800a53a72f51627448b5d5c 100644 (file)
@@ -172,31 +172,31 @@ uae_u8 parallel_port_scsi_read(int reg, uae_u8 data, uae_u8 dir);
 void parallel_port_scsi_write(int reg, uae_u8 v, uae_u8 dir);
 extern bool parallel_port_scsi;
 
-addrbank *supra_init(struct romconfig*);
+bool supra_init(struct autoconfig_info*);
 void supra_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 
-addrbank *golem_init(struct romconfig*);
+bool golem_init(struct autoconfig_info*);
 void golem_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 
-addrbank *stardrive_init(struct romconfig*);
+bool stardrive_init(struct autoconfig_info*);
 void stardrive_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 
-addrbank *kommos_init(struct romconfig*);
+bool kommos_init(struct autoconfig_info*);
 void kommos_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 
-addrbank *vector_init(struct romconfig*);
+bool vector_init(struct autoconfig_info*);
 void vector_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 
-addrbank *protar_init(struct romconfig *rc);
+bool protar_init(struct autoconfig_info *aci);
 void protar_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 
-addrbank *add500_init(struct romconfig *rc);
+bool add500_init(struct autoconfig_info *aci);
 void add500_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 
-addrbank *kronos_init(struct romconfig *rc);
+bool kronos_init(struct autoconfig_info *aci);
 void kronos_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 
-addrbank *adscsi_init(struct romconfig *rc);
+bool adscsi_init(struct autoconfig_info *aci);
 void adscsi_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 
 void rochard_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
@@ -204,51 +204,51 @@ bool rochard_scsi_init(struct romconfig *rc, uaecptr baseaddress);
 uae_u8 rochard_scsi_get(uaecptr addr);
 void rochard_scsi_put(uaecptr addr, uae_u8 v);
 
-addrbank *cltda1000scsi_init(struct romconfig *rc);
+bool cltda1000scsi_init(struct autoconfig_info *aci);
 void cltda1000scsi_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 
-addrbank *ptnexus_init(struct romconfig *rc);
+bool ptnexus_init(struct autoconfig_info *aci);
 void ptnexus_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 
-addrbank *dataflyer_init(struct romconfig *rc);
+bool dataflyer_init(struct autoconfig_info *aci);
 void dataflyer_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 
-addrbank *tecmar_init(struct romconfig *rc);
+bool tecmar_init(struct autoconfig_info *aci);
 void tecmar_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 
-addrbank *xebec_init(struct romconfig *rc);
+bool xebec_init(struct autoconfig_info *aci);
 void xebec_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 
-addrbank *microforge_init(struct romconfig *rc);
+bool microforge_init(struct autoconfig_info *aci);
 void microforge_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 
-addrbank *paradox_init(struct romconfig *rc);
+bool paradox_init(struct autoconfig_info *aci);
 void paradox_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 
-addrbank *hda506_init(struct romconfig *rc);
+bool hda506_init(struct autoconfig_info *aci);
 void hda506_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 
-addrbank *alf1_init(struct romconfig *rc);
+bool alf1_init(struct autoconfig_info *aci);
 void alf1_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 
-addrbank *promigos_init(struct romconfig *rc);
+bool promigos_init(struct autoconfig_info *aci);
 void promigos_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 
-addrbank *system2000_init(struct romconfig *rc);
+bool system2000_init(struct autoconfig_info *aci);
 void system2000_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 
-addrbank *omtiadapter_init(struct romconfig *rc);
+bool omtiadapter_init(struct autoconfig_info *aci);
 void omtiadapter_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 
-addrbank *phoenixboard_init(struct romconfig *rc);
+bool phoenixboard_init(struct autoconfig_info *aci);
 void phoenixboard_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 
-addrbank *trumpcardpro_init(struct romconfig*);
+bool trumpcardpro_init(struct autoconfig_info*);
 void trumpcardpro_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 
 void x86_xt_hd_bput(int, uae_u8);
 uae_u8 x86_xt_hd_bget(int);
-addrbank *x86_xt_hd_init(struct romconfig *rc);
+bool x86_xt_hd_init(struct autoconfig_info *aci);
 void x86_add_xt_hd_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 
 #endif /* UAE_SCSI_H */
index 3cd708dad69b7ab5b7083bf102a659f65b95d8f9..11e3bbdb0ad253c7342e6cd02317481c542b5fba 100644 (file)
@@ -3,7 +3,7 @@
 
 #include "uae/types.h"
 
-addrbank *sndboard_init(int devnum);
+bool sndboard_init(struct autoconfig_info *aci);
 void sndboard_free(void);
 void sndboard_hsync(void);
 void sndboard_vsync(void);
@@ -12,4 +12,10 @@ void update_sndboard_sound(double);
 void sndboard_reset(void);
 void sndboard_ext_volume(void);
 
+bool uaesndboard_init_z2(struct autoconfig_info *aci);
+bool uaesndboard_init_z3(struct autoconfig_info *aci);
+void uaesndboard_free(void);
+void uaesndboard_reset(void);
+
+
 #endif /* UAE_SNDBOARD_H */
index 609560cb29cfbd0e12d4e3b740876211f4c88b0d..96ba90a6a34e92d6214ed58fb193b6978e88a604 100644 (file)
@@ -7,7 +7,7 @@ bool emulate_specialmonitors(struct vidbuffer *src, struct vidbuffer *dst);
 void specialmonitor_store_fmode(int vpos, int hpos, uae_u16 fmode);
 void specialmonitor_reset(void);
 bool specialmonitor_need_genlock(void);
-addrbank *specialmonitor_autoconfig_init(int devnum);
+bool specialmonitor_autoconfig_init(struct autoconfig_info*);
 bool emulate_genlock(struct vidbuffer*, struct vidbuffer*);
 bool emulate_grayscale(struct vidbuffer*, struct vidbuffer*);
 
index c1780ede93d65cbbe93b61b360434c6466ec23ff..9b45cca6d8d5507d8c901a5f19fa829835812355 100644 (file)
@@ -16,9 +16,9 @@ extern void start_program (void);
 extern void leave_program (void);
 extern void real_main (int, TCHAR **);
 extern void usage (void);
-extern void sleep_millis (int ms);
-extern void sleep_millis_main(int ms);
-extern void sleep_millis_amiga(int ms);
+extern int sleep_millis (int ms);
+extern int sleep_millis_main(int ms);
+extern int sleep_millis_amiga(int ms);
 extern void sleep_cpu_wakeup(void);
 extern int sleep_resolution;
 
index 6ab2d6c85d8089edcf764075afc3ec33749741e3..0fce62cf228a0cabf0cb1ac60368170fd0fc9cec 100644 (file)
@@ -1,11 +1,11 @@
 #ifndef UAE_X86_H
 #define UAE_X86_H
 
-extern addrbank *a1060_init(struct romconfig *rc);
-extern addrbank *a2088xt_init(struct romconfig *rc);
-extern addrbank *a2088t_init(struct romconfig *rc);
-extern addrbank *a2286_init(struct romconfig *rc);
-extern addrbank *a2386_init(struct romconfig *rc);
+extern bool a1060_init(struct autoconfig_info *aci);
+extern bool a2088xt_init(struct autoconfig_info *aci);
+extern bool a2088t_init(struct autoconfig_info *aci);
+extern bool a2286_init(struct autoconfig_info *aci);
+extern bool a2386_init(struct autoconfig_info *aci);
 void x86_bridge_hsync(void);
 void x86_bridge_vsync(void);
 void x86_bridge_reset(void);
index 4149d248ad4886e7469f2fddbdb90b1219e3bf55..4df579121a55bf3c8ffd9aaa8bbdd562bd9d69df 100644 (file)
@@ -112,6 +112,10 @@ struct uae_input_device2 {
        int states[MAX_INPUT_DEVICE_EVENTS / 2][MAX_INPUT_SUB_EVENT + 1];
 };
 
+#define INPUT_MATCH_CONFIG_NAME_ONLY 1
+#define INPUT_MATCH_FRIENDLY_NAME_ONLY 2
+#define INPUT_MATCH_BOTH 4
+
 static struct uae_input_device2 joysticks2[MAX_INPUT_DEVICES];
 static struct uae_input_device2 mice2[MAX_INPUT_DEVICES];
 static uae_u8 scancodeused[MAX_INPUT_DEVICES][256];
@@ -142,6 +146,7 @@ static struct teststore testmode_wait[TESTMODE_MAX];
 
 static int bouncy;
 static signed long bouncy_cycles;
+static int autopause;
 
 static int handle_input_event (int nr, int state, int max, int autofire, bool canstoprecord, bool playbackevent);
 
@@ -880,6 +885,7 @@ void write_inputdevice_config (struct uae_prefs *p, struct zfile *f)
        cfgfile_write (f, _T("input.autoswitch"), _T("%d"), p->input_autoswitch);
        cfgfile_dwrite_str (f, _T("input.keyboard_type"), kbtypes[p->input_keyboard_type]);
        cfgfile_dwrite (f, _T("input.contact_bounce"), _T("%d"), p->input_contact_bounce);
+       cfgfile_dwrite (f, _T("input.devicematchflags"), _T("%d"), p->input_device_match_mask);
        for (id = 0; id < MAX_INPUT_SETTINGS; id++) {
                TCHAR tmp[MAX_DPATH];
                if (id < GAMEPORT_INPUT_SETTINGS) {
@@ -1155,7 +1161,7 @@ static void setautofireevent(struct uae_input_device *uid, int num, int sub, int
        }
 }
 
-static void setcompakbevent(struct uae_prefs *p, struct uae_input_device *uid, int l, int evt, int port, int af)
+static void setcompakbevent(struct uae_prefs *p, struct uae_input_device *uid, int l, int evt, int port, int af, uae_u64 flags)
 {
        inputdevice_sparecopy(uid, l, 0);
        if (p->jports[port].nokeyboardoverride && uid->port[l][0] == 0) {
@@ -1166,6 +1172,7 @@ static void setcompakbevent(struct uae_prefs *p, struct uae_input_device *uid, i
        }
        uid->eventid[l][0] = evt;
        uid->flags[l][0] &= COMPA_RESERVED_FLAGS;
+       uid->flags[l][0] |= flags;
        uid->port[l][0] = port + 1;
        xfree(uid->custom[l][0]);
        uid->custom[l][0] = NULL;
@@ -1180,8 +1187,15 @@ static int matchdevice(struct inputdevice_functions *inf, const TCHAR *confignam
                for (int i = 0; i < inf->get_num(); i++) {
                        TCHAR *aname1 = inf->get_friendlyname(i);
                        TCHAR *aname2 = inf->get_uniquename(i);
-                       if (fullmatch && (!aname1 || !name))
-                               continue;
+                       if (fullmatch) {
+                               if (!aname1 || !name)
+                                       continue;
+                               if (!(currprefs.input_device_match_mask & INPUT_MATCH_BOTH))
+                                       continue;
+                       } else {
+                               if (!(currprefs.input_device_match_mask & INPUT_MATCH_CONFIG_NAME_ONLY))
+                                       continue;
+                       }
                        if (aname2 && configname) {
                                bool matched = false;
                                TCHAR bname[MAX_DPATH];
@@ -1231,8 +1245,15 @@ static int matchdevice(struct inputdevice_functions *inf, const TCHAR *confignam
                                if (aname2 && configname) {
                                        const TCHAR *bname2 = configname;
                                        bool matched = false;
-                                       if (fullmatch && (!aname1 || !name))
-                                               continue;
+                                       if (fullmatch) {
+                                               if (!aname1 || !name)
+                                                       continue;
+                                               if (!(currprefs.input_device_match_mask & INPUT_MATCH_BOTH))
+                                                       continue;
+                                       } else {
+                                               if (!(currprefs.input_device_match_mask & INPUT_MATCH_CONFIG_NAME_ONLY))
+                                                       continue;
+                                       }
                                        if (aname2 && bname2 && !_tcscmp(aname2, bname2))
                                                matched = true;
                                        if (matched && fullmatch && _tcscmp(aname1, name) != 0)
@@ -1255,6 +1276,8 @@ static int matchdevice(struct inputdevice_functions *inf, const TCHAR *confignam
                // no match, try friendly names
                for (int i = 0; i < inf->get_num(); i++) {
                        TCHAR *aname1 = inf->get_friendlyname(i);
+                       if (!(currprefs.input_device_match_mask & INPUT_MATCH_FRIENDLY_NAME_ONLY))
+                               continue;
                        if (aname1 && name) {
                                const TCHAR *bname1 = name;
                                if (aname1 && bname1 && !_tcscmp(aname1, bname1)) {
@@ -1337,11 +1360,15 @@ static const struct inputevent *readevent (const TCHAR *name, TCHAR **customp)
                        return &events[i];
                i++;
        }
-       if (_tcslen (name) > 2 && name[0] == '\'' && name[_tcslen (name) - 1] == '\'') {
-               if (!customp)
+       if (_tcslen (name) > 2 && name[0] == '\'') {
+               name++;
+               const TCHAR *end = name;
+               while (*end && *end != '\'')
+                       end++;
+               if (!customp || *end == 0)
                        return NULL;
-               TCHAR *custom = my_strdup (name + 1);
-               custom[_tcslen (custom) - 1] = 0;
+               TCHAR *custom = my_strdup (name);
+               custom[end - name] = 0;
                *customp = custom;
        }
        return &events[0];
@@ -1389,7 +1416,10 @@ void read_inputdevice_config (struct uae_prefs *pr, const TCHAR *option, TCHAR *
                keyboard_default = keyboard_default_table[pr->input_keyboard_type];
                inputdevice_default_kb_all (pr);
        }
-
+       if (!strcasecmp(p, _T("devicematchflags"))) {
+               pr->input_device_match_mask = _tstol(value);
+               write_log(_T("input_device_match_mask = %d\n"), pr->input_device_match_mask);
+       }
        if (!strcasecmp (p, _T("contact_bounce")))
                pr->input_contact_bounce = _tstol (value);
 
@@ -1507,7 +1537,7 @@ void read_inputdevice_config (struct uae_prefs *pr, const TCHAR *option, TCHAR *
 
        bool newdev = false;
        if (temp_uid_index[devnum][tid->devtype] == -1) {
-               int newdevnum;
+               int newdevnum = -1;
                if (tid->devtype == IDTYPE_KEYBOARD) {
                        // keyboard devnum == 0: always select keyboard zero.
                        if (devnum == 0) {
@@ -1524,7 +1554,17 @@ void read_inputdevice_config (struct uae_prefs *pr, const TCHAR *option, TCHAR *
                                newdevnum = matchdevice(idf, tid->configname, tid->name);
                        }
                } else {
-                       newdevnum = matchdevice(idf, tid->configname, tid->name);
+                       // match devices with empty names to first free slot
+                       if (tid->configname && tid->configname[0] == 0 && tid->name && tid->name[0] == 0) {
+                               for (int i = 0; i < MAX_INPUT_DEVICES; i++) {
+                                       if (tid->matcheddevices[i] < 0) {
+                                               newdevnum = i;
+                                               break;
+                                       }
+                               }
+                       } else {
+                               newdevnum = matchdevice(idf, tid->configname, tid->name);
+                       }
                }
                newdev = true;
                if (newdevnum >= 0) {
@@ -1673,36 +1713,38 @@ static void generate_jport_custom_item(struct uae_input_device *uid, int num, in
                for (int j = 0; j < MAX_INPUT_SUB_EVENT; j++) {
                        int evt = uid2->eventid[i][j];
                        uae_u64 flags = uid2->flags[i][j];
-                       if (uid2->port[i][j] == port + 1 && (flags & ID_FLAG_GAMEPORTSCUSTOM_MASK) && evt > 0) {
-                               const struct inputevent *ie = &events[evt];
-                               TCHAR *p = out + _tcslen(out);
-                               if (out[0])
-                                       *p++= ' ';
-                               if (devtype == IDTYPE_KEYBOARD) {
-                                       _stprintf(p, _T("k.%d.b.%d"), num, uid2->extra[i]);
-                               } else if (devtype == IDTYPE_JOYSTICK || devtype == IDTYPE_MOUSE) {
-                                       TCHAR type = devtype == IDTYPE_JOYSTICK ? 'j' : 'm';
-                                       if (i >= ID_BUTTON_OFFSET && i < ID_BUTTON_OFFSET + ID_BUTTON_TOTAL) {
-                                               _stprintf(p, _T("%c.%d.b.%d"), type, num, i - ID_BUTTON_OFFSET);
-                                       } else if (i >= ID_AXIS_OFFSET && i < ID_AXIS_OFFSET + ID_AXIS_TOTAL) {
-                                               _stprintf(p, _T("%c.%d.a.%d"), type, num, i - ID_AXIS_OFFSET);
+                       if (flags & ID_FLAG_GAMEPORTSCUSTOM_MASK) {
+                               if (uid2->port[i][j] == port + 1 && evt > 0) {
+                                       const struct inputevent *ie = &events[evt];
+                                       TCHAR *p = out + _tcslen(out);
+                                       if (out[0])
+                                               *p++= ' ';
+                                       if (devtype == IDTYPE_KEYBOARD) {
+                                               _stprintf(p, _T("k.%d.b.%d"), num, uid2->extra[i]);
+                                       } else if (devtype == IDTYPE_JOYSTICK || devtype == IDTYPE_MOUSE) {
+                                               TCHAR type = devtype == IDTYPE_JOYSTICK ? 'j' : 'm';
+                                               if (i >= ID_BUTTON_OFFSET && i < ID_BUTTON_OFFSET + ID_BUTTON_TOTAL) {
+                                                       _stprintf(p, _T("%c.%d.b.%d"), type, num, i - ID_BUTTON_OFFSET);
+                                               } else if (i >= ID_AXIS_OFFSET && i < ID_AXIS_OFFSET + ID_AXIS_TOTAL) {
+                                                       _stprintf(p, _T("%c.%d.a.%d"), type, num, i - ID_AXIS_OFFSET);
+                                               }
                                        }
-                               }
-                               if (flags & ID_FLAG_SAVE_MASK_QUALIFIERS) {
-                                       TCHAR *p2 = p + _tcslen(p);
-                                       *p2++ = '.';
-                                       for (int i = 0; i < MAX_INPUT_QUALIFIERS * 2; i++) {
-                                               if ((ID_FLAG_QUALIFIER1 << i) & flags) {
-                                                       if (i & 1)
-                                                               _stprintf(p2, _T("%c"), 'a' + i / 2);
-                                                       else
-                                                               _stprintf(p2, _T("%c"), 'A' + i / 2);
-                                                       p2++;
+                                       if (flags & ID_FLAG_SAVE_MASK_QUALIFIERS) {
+                                               TCHAR *p2 = p + _tcslen(p);
+                                               *p2++ = '.';
+                                               for (int i = 0; i < MAX_INPUT_QUALIFIERS * 2; i++) {
+                                                       if ((ID_FLAG_QUALIFIER1 << i) & flags) {
+                                                               if (i & 1)
+                                                                       _stprintf(p2, _T("%c"), 'a' + i / 2);
+                                                               else
+                                                                       _stprintf(p2, _T("%c"), 'A' + i / 2);
+                                                               p2++;
+                                                       }
                                                }
                                        }
+                                       _tcscat(p, _T("="));
+                                       _tcscat(p, ie->confname);
                                }
-                               _tcscat(p, _T("="));
-                               _tcscat(p, ie->confname);
                        }
                }
        }
@@ -1727,7 +1769,7 @@ static int custom_autoswitch_mouse[MAX_JPORTS_CUSTOM];
 void inputdevice_parse_jport_custom(struct uae_prefs *pr, int index, int port, TCHAR *outname)
 {
        const TCHAR *eventstr = pr->jports_custom[index].custom;
-       TCHAR data[MAX_DPATH];
+       TCHAR data[CONFIG_BLEN];
        TCHAR *bufp;
        int cnt = 0;
 
@@ -1859,13 +1901,13 @@ void inputdevice_parse_jport_custom(struct uae_prefs *pr, int index, int port, T
                                                for (int i = 0; i < MAX_INPUT_DEVICES; i++) {
                                                        id = &pr->keyboard_settings[pr->input_selected_setting][i];
                                                        if (i == 0 || id->enabled) {
-                                                               setcompakbevent(pr, id, num, evt, port, 0);
+                                                               setcompakbevent(pr, id, num, evt, port, 0, ID_FLAG_GAMEPORTSCUSTOM_MASK);
                                                        }
                                                }
                                        }
                                } else {
                                        if (port >= 0) {
-                                               inputdevice_set_gameports_mapping(pr, devnum, num, evt, 0, port, pr->input_selected_setting);
+                                               inputdevice_set_gameports_mapping(pr, devnum, num, evt, IDEV_MAPPED_GAMEPORTSCUSTOM1 | IDEV_MAPPED_GAMEPORTSCUSTOM2, port, pr->input_selected_setting);
                                        }
                                        if (evt == INPUTEVENT_JOY1_FIRE_BUTTON || evt == INPUTEVENT_JOY2_FIRE_BUTTON) {
                                                if (joystick > 0)
@@ -2907,10 +2949,41 @@ static void joymousecounter (int joy)
        }
 }
 
+static int inputread;
+
+static void inputdevice_read(bool peek)
+{
+//     if ((inputdevice_logging & (2 | 4)))
+//             write_log(_T("INPUTREAD\n"));
+       int got2 = 0;
+       for (;;) {
+               int got = handle_msgpump();
+               if (!got)
+                       break;
+               got2 = 1;
+       }
+       if (inputread < 0) {
+               idev[IDTYPE_MOUSE].read();
+               idev[IDTYPE_JOYSTICK].read();
+               idev[IDTYPE_KEYBOARD].read();
+       }
+}
+
+static void maybe_read_input(void)
+{
+       if (inputread >= 0 && inputread + 10 > vpos)
+               return;
+       bool peek = inputread >= 0 && inputread + 50 > vpos;
+       inputread = vpos;
+       inputdevice_read(peek);
+}
+
 static uae_u16 getjoystate (int joy)
 {
        uae_u16 v;
 
+       maybe_read_input();
+
        v = (uae_u8)mouse_x[joy] | (mouse_y[joy] << 8);
 #if DONGLE_DEBUG
        if (notinrom ())
@@ -2999,6 +3072,7 @@ static uae_u8 parconvert (uae_u8 v, int jd, int shift)
 uae_u8 handle_parport_joystick (int port, uae_u8 pra, uae_u8 dra)
 {
        uae_u8 v;
+       maybe_read_input();
        switch (port)
        {
        case 0:
@@ -3154,6 +3228,7 @@ uae_u8 handle_joystick_buttons (uae_u8 pra, uae_u8 dra)
        uae_u8 but = 0;
        int i;
 
+       maybe_read_input();
        cap_check ();
        for (i = 0; i < 2; i++) {
                int mask = 0x40 << i;
@@ -3179,10 +3254,10 @@ uae_u8 handle_joystick_buttons (uae_u8 pra, uae_u8 dra)
        }
 
        if (inputdevice_logging & 4) {
-               static uae_u8 old;
-               if (but != old)
+//             static uae_u8 old;
+//             if (but != old)
                        write_log (_T("BFE001 R: %02X:%02X %x\n"), dra, but, M68K_GETPC);
-               old = but;
+//             old = but;
        }
        return but;
 }
@@ -3193,6 +3268,7 @@ void handle_cd32_joystick_cia (uae_u8 pra, uae_u8 dra)
        static int oldstate[2];
        int i;
 
+       maybe_read_input();
        if (inputdevice_logging & 4) {
                write_log (_T("BFE001 W: %02X:%02X %x\n"), dra, pra, M68K_GETPC);
        }
@@ -3262,19 +3338,6 @@ static uae_u16 handle_joystick_potgor (uae_u16 potgor)
        return potgor;
 }
 
-
-static int inputdelay;
-
-static void inputdevice_read (void)
-{
-       do {
-               handle_msgpump ();
-               idev[IDTYPE_MOUSE].read ();
-               idev[IDTYPE_JOYSTICK].read ();
-               idev[IDTYPE_KEYBOARD].read ();
-       } while (handle_msgpump ());
-}
-
 static void inject_events (const TCHAR *str)
 {
        bool quot = false;
@@ -3453,7 +3516,6 @@ static int handle_custom_event (const TCHAR *custom)
 
 void inputdevice_hsync (void)
 {
-       static int cnt;
        cap_check ();
 
 #ifdef CATWEASEL
@@ -3483,8 +3545,7 @@ void inputdevice_hsync (void)
 
        if (input_record && input_record != INPREC_RECORD_PLAYING) {
                if (vpos == 0)
-                       inputdevice_read ();
-               inputdelay = 0;
+                       inputdevice_read(false);
        }
        if (input_play) {
                inprec_playdiskchange ();
@@ -3495,13 +3556,7 @@ void inputdevice_hsync (void)
                        handle_msgpump ();
        }
        if (!input_record && !input_play) {
-               if ((++cnt & 63) == 63 ) {
-                       inputdevice_read ();
-               } else if (inputdelay > 0) {
-                       inputdelay--;
-                       if (inputdelay == 0)
-                               inputdevice_read ();
-               }
+               maybe_read_input();
        }
 }
 
@@ -3758,10 +3813,16 @@ static bool inputdevice_handle_inputcode2 (int code, int state)
        if (vpos != 0)
                write_log (_T("inputcode=%d but vpos = %d"), code, vpos);
 
-       if (state == SET_ONOFF_ON_VALUE)
+       int onoffstate = state & ~SET_ONOFF_MASK_PRESS;
+
+       if (onoffstate == SET_ONOFF_ON_VALUE)
                newstate = 1;
-       else if (state == SET_ONOFF_OFF_VALUE)
+       else if (onoffstate == SET_ONOFF_OFF_VALUE)
                newstate = 0;
+       else if (onoffstate == SET_ONOFF_PRESS_VALUE)
+               newstate = -1;
+       else if (onoffstate == SET_ONOFF_PRESSREL_VALUE)
+               newstate = (state & SET_ONOFF_MASK_PRESS) ? 1 : -1;
        else if (state)
                newstate = -1;
        else
@@ -3861,7 +3922,12 @@ static bool inputdevice_handle_inputcode2 (int code, int state)
                NMI_delayed ();
                break;
        case AKS_PAUSE:
-               pausemode (newstate);
+               pausemode(newstate > 0 ? 1 : newstate);
+               break;
+       case AKS_SINGLESTEP:
+               if (pause_emulation)
+                       pausemode(0);
+               autopause = 1;
                break;
        case AKS_WARP:
                warpmode (newstate);
@@ -4493,8 +4559,16 @@ void inputdevice_vsync (void)
        if (inputdevice_logging & 32)
                write_log (_T("*\n"));
 
+       if (autopause > 0 && pause_emulation == 0) {
+               autopause--;
+               if (!autopause) {
+                       pausemode(1);
+               }
+       }
+
        input_frame++;
        mouseupdate (0, true);
+       inputread = -1;
 
        struct delayed_event *de = delayed_events;
        while (de) {
@@ -4512,12 +4586,6 @@ void inputdevice_vsync (void)
                de = de->next;
        }
 
-       if (!input_record) {
-               inputdevice_read ();
-               if (!input_play)
-                       inputdelay = uaerand () % (maxvpos <= 1 ? 1 : maxvpos - 1);
-       }
-
        inputdevice_handle_inputcode ();
        if (mouseedge_alive > 0)
                mouseedge_alive--;
@@ -4888,6 +4956,7 @@ static bool checkqualifiers (int evt, uae_u64 flags, uae_u64 *qualmask, uae_s16
                return isspecial == false;
        }
 
+       // do we have any subevents with qualifier set?
        for (i = 0; i < MAX_INPUT_SUB_EVENT; i++) {
                for (j = 0; j < MAX_INPUT_QUALIFIERS; j++) {
                        uae_u64 mask = (ID_FLAG_QUALIFIER1 | ID_FLAG_QUALIFIER1_R) << (j * 2);
@@ -4927,7 +4996,7 @@ static void setqualifiers (int evt, int state)
                qualifiers |= mask;
        else
                qualifiers &= ~mask;
-       //write_log (_T("%llx\n"), qualifiers);
+       //write_log (_T("%016llx\n"), qualifiers);
 }
 
 static uae_u64 getqualmask (uae_u64 *qualmask, struct uae_input_device *id, int num, bool *qualonly)
@@ -5103,7 +5172,9 @@ static void setbuttonstateall (struct uae_input_device *id, struct uae_input_dev
                        int inverttoggle = (flags & ID_FLAG_INVERTTOGGLE) ? 1 : 0;
                        int invert = (flags & ID_FLAG_INVERT) ? 1 : 0;
                        int setmode = (flags & ID_FLAG_SET_ONOFF) ? 1: 0;
-                       int setval = (flags & ID_FLAG_SET_ONOFF_VAL) ? SET_ONOFF_ON_VALUE : SET_ONOFF_OFF_VALUE;
+                       int setvalval = (flags & (ID_FLAG_SET_ONOFF_VAL1 | ID_FLAG_SET_ONOFF_VAL2));
+                       int setval = setvalval == (ID_FLAG_SET_ONOFF_VAL1 | ID_FLAG_SET_ONOFF_VAL2) ? SET_ONOFF_PRESSREL_VALUE :
+                               (setvalval == ID_FLAG_SET_ONOFF_VAL2 ? SET_ONOFF_PRESS_VALUE : (setvalval == ID_FLAG_SET_ONOFF_VAL1 ? SET_ONOFF_ON_VALUE : SET_ONOFF_OFF_VALUE));
                        int state;
 
                         if (buttonstate < 0) {
@@ -5114,8 +5185,8 @@ static void setbuttonstateall (struct uae_input_device *id, struct uae_input_dev
                                state = buttonstate;
                        }
                        if (setmode) {
-                               if (state)
-                                       state = setval;
+                               if (state || setval == SET_ONOFF_PRESS_VALUE || setval == SET_ONOFF_PRESSREL_VALUE)
+                                       state = setval | (buttonstate ? 1 : 0);
                        }
 
                        if (!state) {
@@ -5680,7 +5751,7 @@ static void setcompakb (struct uae_prefs *p, int *kb, const int *srcmap, int ind
                                if (m == 0 || uid->enabled) {
                                        for (int l = 0; l < MAX_INPUT_DEVICE_EVENTS; l++) {
                                                if (uid->extra[l] == id) {
-                                                       setcompakbevent(p, uid, l, srcmap[k], index, af);
+                                                       setcompakbevent(p, uid, l, srcmap[k], index, af, 0);
                                                        break;
                                                }
                                        }
@@ -6397,8 +6468,16 @@ static void matchdevices (struct inputdevice_functions *inf, struct uae_input_de
                                        TCHAR *p1 ,*p2;
                                        TCHAR *bname1 = uid[j].name;
 
-                                       if (fullmatch && (!bname1 || aname1))
-                                               continue;
+                                       if (fullmatch) {
+                                               if (!bname1 || aname1)
+                                                       continue;
+                                               if (!(currprefs.input_device_match_mask & INPUT_MATCH_BOTH))
+                                                       continue;
+                                       } else {
+                                               if (!(currprefs.input_device_match_mask & INPUT_MATCH_CONFIG_NAME_ONLY))
+                                                       continue;
+                                       }
+
                                        _tcscpy (bname, uid[j].configname);
                                        _tcscpy (bname2, aname2);
                                        // strip possible local guid part
@@ -6434,7 +6513,7 @@ static void matchdevices (struct inputdevice_functions *inf, struct uae_input_de
                                if (match == -2) {
                                        for (j = 0; j < MAX_INPUT_DEVICES; j++) {
                                                TCHAR *bname2 = uid[j].configname;
-                                               if (aname2 && bname2 && !_tcscmp (aname2, bname2)) {
+                                               if (aname2 && bname2 && (currprefs.input_device_match_mask & INPUT_MATCH_CONFIG_NAME_ONLY) && !_tcscmp (aname2, bname2)) {
                                                        match = j;
                                                        break;
                                                }
@@ -6444,7 +6523,7 @@ static void matchdevices (struct inputdevice_functions *inf, struct uae_input_de
                                        // no match, try friendly names only
                                        for (j = 0; j < MAX_INPUT_DEVICES; j++) {
                                                TCHAR *bname1 = uid[j].name;
-                                               if (aname1 && bname1 && !_tcscmp (aname1, bname1)) {
+                                               if (aname1 && bname1 && (currprefs.input_device_match_mask & INPUT_MATCH_FRIENDLY_NAME_ONLY) && !_tcscmp (aname1, bname1)) {
                                                        match = j;
                                                        break;
                                                }
@@ -6838,6 +6917,7 @@ void inputdevice_default_prefs (struct uae_prefs *p)
        p->input_autofire_linecnt = 600;
        p->input_keyboard_type = 0;
        p->input_autoswitch = true;
+       p->input_device_match_mask = -1;
        keyboard_default = keyboard_default_table[p->input_keyboard_type];
        inputdevice_default_kb_all (p);
 
@@ -6942,7 +7022,9 @@ static int inputdevice_translatekeycode_2 (int keyboard, int scancode, int keyst
                                int inverttoggle = (flags & ID_FLAG_INVERTTOGGLE) ? 1 : 0;
                                int invert = (flags & ID_FLAG_INVERT) ? 1 : 0;
                                int setmode = (flags & ID_FLAG_SET_ONOFF) ? 1: 0;
-                               int setval = (flags & ID_FLAG_SET_ONOFF_VAL) ? SET_ONOFF_ON_VALUE : SET_ONOFF_OFF_VALUE;
+                               int setvalval = (flags & (ID_FLAG_SET_ONOFF_VAL1 | ID_FLAG_SET_ONOFF_VAL2));
+                               int setval = setvalval == (ID_FLAG_SET_ONOFF_VAL1 | ID_FLAG_SET_ONOFF_VAL2) ? SET_ONOFF_PRESSREL_VALUE :
+                                       (setvalval == ID_FLAG_SET_ONOFF_VAL2 ? SET_ONOFF_PRESS_VALUE : (setvalval == ID_FLAG_SET_ONOFF_VAL1 ? SET_ONOFF_ON_VALUE : SET_ONOFF_OFF_VALUE));
                                int toggled;
                                int state;
 
@@ -6954,8 +7036,8 @@ static int inputdevice_translatekeycode_2 (int keyboard, int scancode, int keyst
                                        state = keystate;
                                }
                                if (setmode) {
-                                       if (state)
-                                               state = setval;
+                                       if (state || setval == SET_ONOFF_PRESS_VALUE || setval == SET_ONOFF_PRESSREL_VALUE)
+                                               state = setval | (keystate ? 1 : 0);
                                }
 
                                setqualifiers (evt, state > 0);
@@ -7492,8 +7574,10 @@ int inputdevice_get_mapping (int devnum, int num, uae_u64 *pflags, int *pport, T
                flags |= flag & ID_FLAG_QUALIFIER_MASK;
        if (flag & ID_FLAG_SET_ONOFF)
                flags |= IDEV_MAPPED_SET_ONOFF;
-       if (flag & ID_FLAG_SET_ONOFF_VAL)
-               flags |= IDEV_MAPPED_SET_ONOFF_VAL;
+       if (flag & ID_FLAG_SET_ONOFF_VAL1)
+               flags |= IDEV_MAPPED_SET_ONOFF_VAL1;
+       if (flag & ID_FLAG_SET_ONOFF_VAL2)
+               flags |= IDEV_MAPPED_SET_ONOFF_VAL2;
        if (pflags)
                *pflags = flags;
        if (pport)
@@ -7550,10 +7634,11 @@ int inputdevice_set_mapping (int devnum, int num, const TCHAR *name, TCHAR *cust
                flag |= (flags & IDEV_MAPPED_GAMEPORTSCUSTOM1) ? ID_FLAG_GAMEPORTSCUSTOM1 : 0;
                flag |= (flags & IDEV_MAPPED_GAMEPORTSCUSTOM2) ? ID_FLAG_GAMEPORTSCUSTOM2 : 0;
                flag |= flags & IDEV_MAPPED_QUALIFIER_MASK;
-               flag &= ~(IDEV_MAPPED_SET_ONOFF | IDEV_MAPPED_SET_ONOFF_VAL);
+               flag &= ~(IDEV_MAPPED_SET_ONOFF | IDEV_MAPPED_SET_ONOFF_VAL1 | IDEV_MAPPED_SET_ONOFF_VAL2);
                if (amask & AM_SETTOGGLE) {
                        flag |= (flags & IDEV_MAPPED_SET_ONOFF) ? ID_FLAG_SET_ONOFF : 0;
-                       flag |= (flags & IDEV_MAPPED_SET_ONOFF_VAL) ? ID_FLAG_SET_ONOFF_VAL : 0;
+                       flag |= (flags & IDEV_MAPPED_SET_ONOFF_VAL1) ? ID_FLAG_SET_ONOFF_VAL1 : 0;
+                       flag |= (flags & IDEV_MAPPED_SET_ONOFF_VAL2) ? ID_FLAG_SET_ONOFF_VAL2 : 0;
                }
                if (port >= 0)
                        portp = port;
@@ -7943,7 +8028,7 @@ void inputdevice_settest (int set)
 
 int inputdevice_testread_count (void)
 {
-       inputdevice_read ();
+       inputdevice_read (false);
        if (testmode != 1) {
                testmode = 0;
                return -1;
@@ -7954,7 +8039,7 @@ int inputdevice_testread_count (void)
 int inputdevice_testread (int *devnum, int *wtype, int *state, bool doread)
 {
        if (doread) {
-               inputdevice_read ();
+               inputdevice_read (false);
                if (testmode != 1) {
                        testmode = 0;
                        return -1;
@@ -8660,7 +8745,7 @@ void inputdevice_fix_prefs(struct uae_prefs *p, bool userconfig)
        for (int i = 0; i < MAX_JPORTS; i++) {
                struct jport *jp = &jport_config_store[i];
                matched[i] = false;
-               if (jp->idc.configname[0] && jp->idc.name[0]) {
+               if (jp->idc.configname[0] && jp->idc.name[0] && (currprefs.input_device_match_mask & INPUT_MATCH_BOTH)) {
                        if (inputdevice_joyport_config(p, jp->idc.name, jp->idc.configname, i, jp->mode, 1, userconfig)) {
                                inputdevice_validate_jports(p, i, matched);
                                inputdevice_store_used_device(&p->jports[i], i, defaultports);
@@ -8673,7 +8758,7 @@ void inputdevice_fix_prefs(struct uae_prefs *p, bool userconfig)
        for (int i = 0; i < MAX_JPORTS; i++) {
                if (!matched[i]) {
                        struct jport *jp = &jport_config_store[i];
-                       if (jp->idc.configname[0]) {
+                       if (jp->idc.configname[0] && (currprefs.input_device_match_mask & INPUT_MATCH_CONFIG_NAME_ONLY)) {
                                if (inputdevice_joyport_config(p, NULL, jp->idc.configname, i, jp->mode, 1, userconfig)) {
                                        inputdevice_validate_jports(p, i, matched);
                                        inputdevice_store_used_device(&p->jports[i], i, defaultports);
@@ -8687,7 +8772,7 @@ void inputdevice_fix_prefs(struct uae_prefs *p, bool userconfig)
        for (int i = 0; i < MAX_JPORTS; i++) {
                if (!matched[i]) {
                        struct jport *jp = &jport_config_store[i];
-                       if (jp->idc.name[0]) {
+                       if (jp->idc.name[0] && (currprefs.input_device_match_mask & INPUT_MATCH_FRIENDLY_NAME_ONLY)) {
                                if (inputdevice_joyport_config(p, jp->idc.name, NULL, i, jp->mode, 1, userconfig)) {
                                        inputdevice_validate_jports(p, i, matched);
                                        inputdevice_store_used_device(&p->jports[i], i, defaultports);
index 0c42ab2a65d9bd6dee2dbb0e35aa804f073b9610..4ac4b046dd69b79cf00d0c677b8b7d2d4e57c687 100644 (file)
@@ -337,6 +337,7 @@ DEFEVENT(SPC_EFLOPPY1,_T("Eject disk in DF1:"),AM_K,0,0,AKS_EFLOPPY1)
 DEFEVENT(SPC_EFLOPPY2,_T("Eject disk in DF2:"),AM_K,0,0,AKS_EFLOPPY2)
 DEFEVENT(SPC_EFLOPPY3,_T("Eject disk in DF3:"),AM_K,0,0,AKS_EFLOPPY3)
 DEFEVENT(SPC_PAUSE,_T("Pause emulation"),AM_KT,0,0,AKS_PAUSE)
+DEFEVENT(SPC_SINGLESTEP,_T("Single step"),AM_KT,0,0,AKS_SINGLESTEP)
 DEFEVENT(SPC_WARP,_T("Warp mode"),AM_KT,0,0,AKS_WARP)
 DEFEVENT(SPC_INHIBITSCREEN,_T("Toggle screen updates"),AM_KT,0,0,AKS_INHIBITSCREEN)
 DEFEVENT(SPC_IRQ7,_T("Level 7 interrupt"),AM_K,0,0,AKS_IRQ7)
index db1ef0ec55c1a1639ed730f2a64472932a7b466b..c0b460d1d28b9af60054606f447fd2690d1896f8 100644 (file)
--- a/main.cpp
+++ b/main.cpp
@@ -320,6 +320,7 @@ void fixup_cpu (struct uae_prefs *p)
                error_log(_T("Cycle-exact mode requires at least Disabled but emulated sound setting."));
        }
 
+#if 0
        if (p->cachesize && p->cpuboard_type && !cpuboard_jitdirectompatible(p) && !p->comptrustbyte) {
                error_log(_T("JIT direct is not compatible with emulated Blizzard accelerator boards."));
                p->comptrustbyte = 1;
@@ -327,6 +328,7 @@ void fixup_cpu (struct uae_prefs *p)
                p->comptrustlong = 1;
                p->comptrustnaddr = 1;
        }
+#endif
 }
 
 void fixup_prefs (struct uae_prefs *p, bool userconfig)
@@ -335,6 +337,8 @@ void fixup_prefs (struct uae_prefs *p, bool userconfig)
 
        built_in_chipset_prefs (p);
        fixup_cpu (p);
+       cfgfile_compatibility_rtg(p);
+       cfgfile_compatibility_romtype(p);
 
        if (p->cpuboard_type && p->cpuboardmem1_size > cpuboard_maxmemory(p)) {
                error_log(_T("Unsupported accelerator board memory size %d (0x%x).\n"), p->cpuboardmem1_size, p->cpuboardmem1_size);
@@ -343,7 +347,7 @@ void fixup_prefs (struct uae_prefs *p, bool userconfig)
        if (cpuboard_memorytype(p) == BOARD_MEMORY_HIGHMEM) {
                p->mbresmem_high_size = p->cpuboardmem1_size;
        } else if (cpuboard_memorytype(p) == BOARD_MEMORY_Z2) {
-               p->fastmem2_size = p->cpuboardmem1_size;
+               p->fastmem[0].size = p->cpuboardmem1_size;
        } else if (cpuboard_memorytype(p) == BOARD_MEMORY_25BITMEM) {
                p->mem25bit_size = p->cpuboardmem1_size;
        } else if (cpuboard_memorytype(p) == BOARD_MEMORY_EMATRIX) {
@@ -374,27 +378,12 @@ void fixup_prefs (struct uae_prefs *p, bool userconfig)
                err = 1;
        }
 
-       if ((p->fastmem_size & (p->fastmem_size - 1)) != 0
-               || (p->fastmem_size != 0 && (p->fastmem_size < 0x10000 || p->fastmem_size > 0x800000)))
-       {
-               error_log (_T("Unsupported fastmem size %d (0x%x)."), p->fastmem_size, p->fastmem_size);
-               p->fastmem_size = 0;
-               err = 1;
-       }
-       if ((p->fastmem2_size & (p->fastmem2_size - 1)) != 0 || (p->fastmem2_size != 0 && (p->fastmem2_size < 0x10000 || p->fastmem2_size > 0x800000)))
-       {
-               error_log (_T("Unsupported fastmem2 size %d (0x%x)."), p->fastmem2_size, p->fastmem2_size);
-               p->fastmem2_size = 0;
-               err = 1;
-       }
-       if (p->cachesize) {
-               if (p->fastmem_size + p->fastmem2_size > 0x800000) {
-                       error_log (_T("Unsupported fastmem2 size %d (0x%x)."), p->fastmem2_size, p->fastmem2_size);
-                       err = 1;
-               }
-               if (p->fastmem2_size > p->fastmem_size && p->fastmem_size > 0) {
-                       error_log (_T("Fastmem2 size can't be larger than fastmem1 if JIT is enabled."));
-                       p->fastmem2_size = 0;
+       for (int i = 0; i < MAX_RAM_BOARDS; i++) {
+               if ((p->fastmem[i].size & (p->fastmem[i].size - 1)) != 0
+                       || (p->fastmem[i].size != 0 && (p->fastmem[i].size < 0x10000 || p->fastmem[i].size > 0x800000)))
+               {
+                       error_log (_T("Unsupported fastmem size %d (0x%x)."), p->fastmem[i].size, p->fastmem[i].size);
+                       p->fastmem[i].size = 0;
                        err = 1;
                }
        }
@@ -417,28 +406,13 @@ void fixup_prefs (struct uae_prefs *p, bool userconfig)
                }
        }
        
-       if (p->z3fastmem_size > max_z3fastmem) {
-               error_log (_T("Zorro III fastmem size %d (0x%x) larger than max reserved %d (0x%x)."), p->z3fastmem_size, p->z3fastmem_size, max_z3fastmem, max_z3fastmem);
-               p->z3fastmem_size = max_z3fastmem;
-               err = 1;
-       }
-       if ((p->z3fastmem_size & (p->z3fastmem_size - 1)) != 0 || (p->z3fastmem_size != 0 && p->z3fastmem_size < 0x100000))
-       {
-               error_log (_T("Unsupported Zorro III fastmem size %d (0x%x)."), p->z3fastmem_size, p->z3fastmem_size);
-               p->z3fastmem_size = 0;
-               err = 1;
-       }
-
-       if (p->z3fastmem2_size > max_z3fastmem) {
-               error_log (_T("Zorro III fastmem2 size %d (0x%x) larger than max reserved %d (0x%x)."), p->z3fastmem2_size, p->z3fastmem2_size, max_z3fastmem, max_z3fastmem);
-               p->z3fastmem2_size = max_z3fastmem;
-               err = 1;
-       }
-       if ((p->z3fastmem2_size & (p->z3fastmem2_size - 1)) != 0 || (p->z3fastmem2_size != 0 && p->z3fastmem2_size < 0x100000))
-       {
-               error_log (_T("Unsupported Zorro III fastmem2 size %x (%x)."), p->z3fastmem2_size, p->z3fastmem2_size);
-               p->z3fastmem2_size = 0;
-               err = 1;
+       for (int i = 0; i < MAX_RAM_BOARDS; i++) {
+               if ((p->z3fastmem[i].size & (p->z3fastmem[i].size - 1)) != 0 || (p->z3fastmem[i].size != 0 && p->z3fastmem[i].size < 0x100000))
+               {
+                       error_log (_T("Unsupported Zorro III fastmem size %d (0x%x)."), p->z3fastmem[i].size, p->z3fastmem[i].size);
+                       p->z3fastmem[i].size = 0;
+                       err = 1;
+               }
        }
 
        p->z3autoconfig_start &= ~0xffff;
@@ -457,8 +431,9 @@ void fixup_prefs (struct uae_prefs *p, bool userconfig)
                err = 1;
        }
 
-       if (p->address_space_24 && (p->z3fastmem_size != 0 || p->z3fastmem2_size != 0 || p->z3chipmem_size != 0)) {
-               p->z3fastmem_size = p->z3fastmem2_size = p->z3chipmem_size = 0;
+       if (p->address_space_24 && (p->z3fastmem[0].size != 0 || p->z3fastmem[1].size != 0 || p->z3fastmem[2].size != 0 || p->z3fastmem[3].size != 0 || p->z3chipmem_size != 0)) {
+               p->z3fastmem[0].size = p->z3fastmem[1].size = p->z3fastmem[2].size = p->z3fastmem[3].size = 0;
+               p->z3chipmem_size = 0;
                error_log (_T("Can't use a Z3 graphics card or 32-bit memory when using a 24 bit address space."));
        }
 
@@ -472,7 +447,7 @@ void fixup_prefs (struct uae_prefs *p, bool userconfig)
                p->bogomem_size = 0x180000;
                error_log (_T("Possible Gayle bogomem conflict fixed."));
        }
-       if (p->chipmem_size > 0x200000 && p->fastmem_size > 262144) {
+       if (p->chipmem_size > 0x200000 && (p->fastmem[0].size > 262144 || p->fastmem[1].size > 262144)) {
                error_log(_T("You can't use fastmem and more than 2MB chip at the same time."));
                p->chipmem_size = 0x200000;
                err = 1;
@@ -518,10 +493,6 @@ void fixup_prefs (struct uae_prefs *p, bool userconfig)
                        error_log (_T("Z3 RTG and 24bit address space are not compatible."));
                        rbc->rtgmem_type = GFXBOARD_UAE_Z2;
                }
-               if (rbc->rtgmem_size && rbc->rtgmem_type == GFXBOARD_UAE_Z2 && (p->chipmem_size > 2 * 1024 * 1024 || getz2size (p) > 8 * 1024 * 1024 || getz2size (p) < 0)) {
-                       rbc->rtgmem_size = 0;
-                       error_log (_T("Too large Z2 RTG memory size."));
-               }
        }
 
        if (p->cs_z3autoconfig && p->address_space_24) {
@@ -567,10 +538,12 @@ void fixup_prefs (struct uae_prefs *p, bool userconfig)
                p->cachesize = 0;
                err = 1;
        }
-       if ((p->z3fastmem_size || p->z3fastmem2_size || p->z3chipmem_size) && p->address_space_24) {
+       if ((p->z3fastmem[0].size || p->z3fastmem[1].size || p->z3fastmem[2].size || p->z3fastmem[3].size || p->z3chipmem_size) && p->address_space_24) {
                error_log (_T("Z3 fast memory can't be used if address space is 24-bit."));
-               p->z3fastmem_size = 0;
-               p->z3fastmem2_size = 0;
+               p->z3fastmem[0].size = 0;
+               p->z3fastmem[1].size = 0;
+               p->z3fastmem[2].size = 0;
+               p->z3fastmem[3].size = 0;
                p->z3chipmem_size = 0;
                err = 1;
        }
@@ -710,6 +683,8 @@ void fixup_prefs (struct uae_prefs *p, bool userconfig)
 #endif
        }
 #endif
+       if (p->gfx_framerate < 1)
+               p->gfx_framerate = 1;
        if (p->maprom && !p->address_space_24) {
                p->maprom = 0x0f000000;
        }
@@ -719,20 +694,6 @@ void fixup_prefs (struct uae_prefs *p, bool userconfig)
        if (p->tod_hack && p->cs_ciaatod == 0)
                p->cs_ciaatod = p->ntscmode ? 2 : 1;
 
-       if (p->sound_toccata + p->sound_es1370 + p->sound_fm801 > 1) {
-               error_log(_T("Only one sound card can be enabled at the same time."));
-               if (p->sound_toccata) {
-                       p->sound_es1370 = 0;
-                       p->sound_fm801 = 0;
-               } else if (p->sound_es1370) {
-                       p->sound_toccata = 0;
-                       p->sound_fm801 = 0;
-               } else {
-                       p->sound_toccata = 0;
-                       p->sound_es1370 = 0;
-               }
-       }
-
        built_in_chipset_prefs (p);
        blkdev_fix_prefs (p);
        inputdevice_fix_prefs(p, userconfig);
@@ -860,7 +821,7 @@ static TCHAR *parsetext (const TCHAR *s)
 static TCHAR *parsetextpath (const TCHAR *s)
 {
        TCHAR *s2 = parsetext (s);
-       TCHAR *s3 = target_expand_environment (s2);
+       TCHAR *s3 = target_expand_environment (s2, NULL, 0);
        xfree (s2);
        return s3;
 }
@@ -1120,7 +1081,11 @@ static int real_main2 (int argc, TCHAR **argv)
                                                 a config using the cmd-line.  This case handles loads through the GUI. */
 
 #ifdef NATMEM_OFFSET
-       init_shm ();
+       if (!init_shm ()) {
+               if (currprefs.start_gui)
+                       uae_restart(-1, NULL);
+               return 0;
+       }
 #endif
 #ifdef WITH_LUA
        uae_lua_init ();
index dd8698258ee9948acf90c81392ee92e1d1db94b5..e0d32f6b09f25d27ebf5f40ca10662518eeb57f3 100644 (file)
@@ -48,6 +48,7 @@ static int a2410_overlay_blink_rate_off;
 static int a2410_overlay_blink_cnt;
 static int tms_configured;
 static uae_u8 tms_config[128];
+static int a2410_gfxboard = -1;
 extern addrbank tms_bank;
 
 int mscreen::hpos()
@@ -139,11 +140,11 @@ UINT32 total_cycles(void)
 
 void m_to_shiftreg_cb(address_space space, offs_t offset, UINT16 *shiftreg)
 {
-       memcpy(shiftreg, &gfxmem_bank.baseaddr[TOWORD(offset)], 256 * sizeof(UINT16));
+       memcpy(shiftreg, &gfxmem_banks[a2410_gfxboard]->baseaddr[TOWORD(offset)], 256 * sizeof(UINT16));
 }
 void m_from_shiftreg_cb(address_space space, offs_t offset, UINT16* shiftreg)
 {
-       memcpy(&gfxmem_bank.baseaddr[TOWORD(offset)], shiftreg, 256 * sizeof(UINT16));
+       memcpy(&gfxmem_banks[a2410_gfxboard]->baseaddr[TOWORD(offset)], shiftreg, 256 * sizeof(UINT16));
 }
 
 UINT16 direct_read_data::read_decrypted_word(UINT32 pc)
@@ -325,7 +326,7 @@ UINT8 address_space::read_byte(UINT32 a)
                //write_log(_T("TMS byte read RAM %08x (%08x) =%02x PC=%08x\n"), aa, addr, v, M68K_GETPC);
                break;
                case A2410_BANK_FRAMEBUFFER:
-               v = gfxmem_bank.baseaddr[addr];
+               v = gfxmem_banks[a2410_gfxboard]->baseaddr[addr];
                //write_log(_T("TMS byte read framebuffer %08x (%08x) = %02x PC=%08x\n"), aa, addr, v, M68K_GETPC);
                break;
                case A2410_BANK_RAMDAC:
@@ -369,8 +370,8 @@ UINT16 address_space::read_word(UINT32 a)
                //write_log(_T("TMS program word read RAM %08x (%08x) = %04x PC=%08x\n"), aa, addr, v, M68K_GETPC);
                break;
                case A2410_BANK_FRAMEBUFFER:
-               v = gfxmem_bank.baseaddr[addr] << 8;
-               v |= gfxmem_bank.baseaddr[addr + 1];
+               v = gfxmem_banks[a2410_gfxboard]->baseaddr[addr] << 8;
+               v |= gfxmem_banks[a2410_gfxboard]->baseaddr[addr + 1];
                //write_log(_T("TMS gfx word read %08x (%08x) = %04x PC=%08x\n"), aa, addr, v, M68K_GETPC);
                break;
                case A2410_BANK_RAMDAC:
@@ -410,7 +411,7 @@ void address_space::write_byte(UINT32 a, UINT8 b)
                //write_log(_T("TMS program byte write %08x (%08x) = %02x PC=%08x\n"), aa, addr, b, M68K_GETPC);
                break;
                case A2410_BANK_FRAMEBUFFER:
-               gfxmem_bank.baseaddr[addr] = b;
+               gfxmem_banks[a2410_gfxboard]->baseaddr[addr] = b;
                //write_log(_T("TMS gfx byte write %08x (%08x) = %02x PC=%08x\n"), aa, addr, b, M68K_GETPC);
                break;
                case A2410_BANK_RAMDAC:
@@ -453,8 +454,8 @@ void address_space::write_word(UINT32 a, UINT16 b)
                //write_log(_T("TMS program word write RAM %08x (%08x) = %04x PC=%08x\n"), aa, addr, b, M68K_GETPC);
                break;
                case A2410_BANK_FRAMEBUFFER:
-               gfxmem_bank.baseaddr[addr] = b >> 8;
-               gfxmem_bank.baseaddr[addr + 1] = b & 0xff;
+               gfxmem_banks[a2410_gfxboard]->baseaddr[addr] = b >> 8;
+               gfxmem_banks[a2410_gfxboard]->baseaddr[addr + 1] = b & 0xff;
                //write_log(_T("TMS gfx word write %08x (%08x) = %04x PC=%08x\n"), aa, addr, b, M68K_GETPC);
                break;
                case A2410_BANK_RAMDAC:
@@ -574,6 +575,7 @@ static uae_u8 *a2410_surface;
 static int a2410_interlace;
 static int a2410_interrupt;
 static int a2410_hsync_max;
+static bool a2410_visible;
 
 void tms_reset(void)
 {
@@ -609,12 +611,16 @@ void tms_free(void)
        if (a2410_surface)
                gfx_unlock_picasso(true);
        a2410_surface = NULL;
-       mapped_free(&gfxmem_bank);
+       if (a2410_gfxboard >= 0) {
+               gfxboard_free_vram(a2410_gfxboard);
+               gfxboard_free_slot(a2410_gfxboard);
+       }
+       a2410_gfxboard = -1;
        xfree(program_ram);
        program_ram = NULL;
 }
 
-addrbank *tms_init(int devnum)
+bool tms_init(struct autoconfig_info *aci)
 {
        memset(tms_config, 0xff, sizeof tms_config);
        ew(0x00, 0xc0 | 0x01);
@@ -624,14 +630,34 @@ addrbank *tms_init(int devnum)
        ew(0x10, 1030 >> 8);
        ew(0x14, 1030 & 0xff);
 
-       mapped_free(&gfxmem_bank);
+       aci->addrbank = &tms_bank;
+       aci->label = _T("A2410");
+       if (!aci->doinit) {
+               memcpy(aci->autoconfig_raw, tms_config, sizeof tms_config);
+               return true;
+       }
+
+       for (int i = 0; i < MAX_RTG_BOARDS; i++) {
+               if (currprefs.rtgboards[i].rtgmem_type == GFXBOARD_A2410) {
+                       a2410_gfxboard = currprefs.rtgboards[i].rtg_index;
+                       break;
+               }
+       }
+
+       if (a2410_gfxboard < 0)
+               return false;
+
+       gfxboard_allocate_slot(currprefs.rtgboards[a2410_gfxboard].rtgmem_type, a2410_gfxboard);
+
+       mapped_free(gfxmem_banks[a2410_gfxboard]);
        xfree(program_ram);
 
-       gfxmem_bank.label = _T("ram_a8");
-       gfxmem_bank.allocated = 1 * 1024 * 1024;
-       mapped_malloc(&gfxmem_bank);
-       picasso_allocatewritewatch(gfxmem_bank.allocated);
-       gfxmem_bank.start = 0xa80000;
+       gfxmem_banks[a2410_gfxboard]->label = _T("ram_a8");
+       gfxmem_banks[a2410_gfxboard]->allocated = 1 * 1024 * 1024;
+       gfxboard_get_a8_vram(a2410_gfxboard);
+
+       picasso_allocatewritewatch(a2410_gfxboard, gfxmem_banks[a2410_gfxboard]->allocated);
+       gfxmem_banks[a2410_gfxboard]->start = 0xa80000;
 
        program_ram = xcalloc(uae_u8, 1 * 1024 * 1024);
 
@@ -639,7 +665,7 @@ addrbank *tms_init(int devnum)
        tms_device.device_start();
        tms_reset();
 
-       return &tms_bank;
+       return true;
 }
 
 void mscreen::configure(int width, int height, rectangle vis)
@@ -679,22 +705,40 @@ bool tms_toggle(int mode)
        if (!tms_configured)
                return false;
 
-       if (a2410_enabled) {
+       if (!mode) {
+               if (!a2410_enabled)
+                       return false;
                a2410_enabled = false;
                a2410_modechanged = false;
-               picasso_requested_on = 0;
                a2410_gotmode = -1;
+               a2410_visible = false;
                return true;
        } else {
                if (!a2410_gotmode)
                        return false;
+               if (a2410_enabled)
+                       return false;
                a2410_gotmode = 1;
                a2410_modechanged = true;
+               a2410_visible = true;
+               if (currprefs.rtgboards[1].rtgmem_size)
+                       statusline_add_message(_T("RTG %d: A2410"), a2410_gfxboard + 1);
                return true;
        }
        return false;
 }
 
+static void a2410_setmode(void)
+{
+       picasso96_state.Width = a2410_width;
+       picasso96_state.Height = a2410_height;
+       picasso96_state.BytesPerPixel = 1;
+       picasso96_state.RGBFormat = RGBFB_CLUT;
+       write_log(_T("A2410 %d*%d\n"), a2410_width, a2410_height);
+       gfx_set_picasso_modeinfo(a2410_width, a2410_height, 1, RGBFB_NONE);
+       init_hz_p96();
+}
+
 static void tms_vsync_handler2(bool internalsync)
 {
        if (!tms_configured)
@@ -704,48 +748,48 @@ static void tms_vsync_handler2(bool internalsync)
        tms_device.get_display_params(&parms);
        bool enabled = parms.enabled != 0 && a2410_gotmode > 0;
 
-       if (enabled != a2410_enabled || a2410_modechanged) {
-               if (a2410_surface)
-                       gfx_unlock_picasso(false);
-               a2410_surface = NULL;
-
-               if (!enabled) {
-                       picasso_requested_on = 0;
-               } else {
-                       if (a2410_modechanged) {
-                               picasso96_state.Width = a2410_width;
-                               picasso96_state.Height = a2410_height;
-                               picasso96_state.BytesPerPixel = 1;
-                               picasso96_state.RGBFormat = RGBFB_CLUT;
-                               write_log(_T("A2410 %d*%d\n"), a2410_width, a2410_height);
-                               gfx_set_picasso_modeinfo(a2410_width, a2410_height, 1, RGBFB_NONE);
-                               init_hz_p96();
-                       }
-                       picasso_requested_on = 1;
-                       a2410_modechanged = false;
-                       fullrefresh = 2;
+       if (!a2410_visible && a2410_modechanged) {
+               if (gfxboard_rtg_enable_initial(a2410_gfxboard)) {
+                       a2410_setmode();
+                       return;
                }
-               a2410_enabled = enabled;
-               write_log(_T("A2410 ACTIVE=%d\n"), a2410_enabled);
        }
 
-       if (picasso_on) {
-               if (currprefs.leds_on_screen & STATUSLINE_RTG) {
-                       get_a2410_surface();
+       if (a2410_visible) {
+               if (enabled != a2410_enabled || a2410_modechanged) {
+                       if (a2410_surface)
+                               gfx_unlock_picasso(false);
+                       a2410_surface = NULL;
+
+                       if (enabled) {
+                               if (a2410_modechanged) {
+                                       a2410_setmode();
+                                       if (!picasso_on)
+                                               picasso_requested_on = true;
+                               }
+                               a2410_modechanged = false;
+                               fullrefresh = 2;
+                       }
+                       a2410_enabled = enabled;
+                       write_log(_T("A2410 ACTIVE=%d\n"), a2410_enabled);
                }
-               if (internalsync) {
-                       if (fullrefresh > 0)
-                               fullrefresh--;
-                       if (request_fullrefresh) {
-                               fullrefresh = 1;
-                               request_fullrefresh = 0;
+
+               if (picasso_on) {
+                       if (currprefs.leds_on_screen & STATUSLINE_RTG) {
+                               get_a2410_surface();
+                       }
+                       if (internalsync) {
+                               if (request_fullrefresh) {
+                                       fullrefresh = 2;
+                                       request_fullrefresh = 0;
+                               }
                        }
                }
-       }
 
-       if (a2410_surface)
-               gfx_unlock_picasso(true);
-       a2410_surface = NULL;
+               if (a2410_surface)
+                       gfx_unlock_picasso(true);
+               a2410_surface = NULL;
+       }
 
        a2410_interlace = -a2410_interlace;
 
@@ -753,7 +797,7 @@ static void tms_vsync_handler2(bool internalsync)
        if (a2410_overlay_blink_cnt == 0 || a2410_overlay_blink_cnt == a2410_overlay_blink_rate_on) {
                // any blink mode enabled?
                if (a2410_palette_control[5 - 4] != 0 || (a2410_palette_control[6 - 4] & (4 | 8)))
-                       fullrefresh++;
+                       fullrefresh = 2;
        }
        if (a2410_overlay_blink_cnt > a2410_overlay_blink_rate_off + a2410_overlay_blink_rate_on) {
                a2410_overlay_blink_cnt = 0;
@@ -798,12 +842,16 @@ static void tms_hsync_handler2(void)
 
        if (a2410_vpos == 0) {
                tms_vsync_handler2(true);
-               picasso_getwritewatch(a2410_vram_start_offset);
+               picasso_getwritewatch(a2410_gfxboard, a2410_vram_start_offset);
        }
 
-       if (a2410_modechanged)
+       if (a2410_modechanged || !picasso_on)
                return;
 
+       if (a2410_vpos == 0 && fullrefresh > 0) {
+               fullrefresh--;
+       }
+
        tms34010_display_params parms;
        tms_device.get_display_params(&parms);
 
@@ -815,7 +863,7 @@ static void tms_hsync_handler2(void)
 
        int coladdr = parms.coladdr;
        int vramoffset = ((parms.rowaddr << 8) & 0x7ffff);
-       uae_u16 *vram = (uae_u16*)gfxmem_bank.baseaddr + vramoffset;
+       uae_u16 *vram = (uae_u16*)gfxmem_banks[a2410_gfxboard]->baseaddr + vramoffset;
 
        int overlayoffset = a2410_vpos - parms.veblnk;
 
@@ -833,8 +881,8 @@ static void tms_hsync_handler2(void)
 
 
        if (!fullrefresh && !a2410_modified[overlay_yoffset]) {
-               if (!picasso_is_vram_dirty(gfxmem_bank.start + (vramoffset << 1), a2410_displaywidth)) {
-                       if (!picasso_is_vram_dirty(gfxmem_bank.start + ((vramoffset + 0x200) << 1), a2410_displaywidth)) {
+               if (!picasso_is_vram_dirty(a2410_gfxboard, gfxmem_banks[a2410_gfxboard]->start + (vramoffset << 1), a2410_displaywidth)) {
+                       if (!picasso_is_vram_dirty(a2410_gfxboard, gfxmem_banks[a2410_gfxboard]->start + ((vramoffset + 0x200) << 1), a2410_displaywidth)) {
                                return;
                        }
                }
index 9ab39f1800d0cda65661d3e9a787a4561239d772..25fe04db09032a62696626fe30661001b5bb0eaf 100644 (file)
@@ -1283,7 +1283,7 @@ static bool load_extendedkickstart (const TCHAR *romextfile, int type)
                        extendedkickmem_type = EXTENDED_ROM_CDTV;
                } else if (size > 300000) {
                        extendedkickmem_type = EXTENDED_ROM_CD32;
-               } else if (need_uae_boot_rom () != 0xf00000) {
+               } else if (need_uae_boot_rom (&currprefs) != 0xf00000) {
                        extendedkickmem_type = EXTENDED_ROM_CDTV;
                }       
        } else {
@@ -1344,7 +1344,7 @@ static int patch_residents (uae_u8 *kickmemory, int size)
        // "scsi.device", "carddisk.device", "card.resource" };
        uaecptr base = size == ROM_SIZE_512 ? 0xf80000 : 0xfc0000;
 
-       if (currprefs.cs_mbdmac != 2) {
+       if (is_device_rom(&currprefs, ROMTYPE_SCSI_A4000T, 0) < 0) {
                for (i = 0; i < size - 100; i++) {
                        if (kickmemory[i] == 0x4a && kickmemory[i + 1] == 0xfc) {
                                uaecptr addr;
@@ -1419,8 +1419,8 @@ static bool load_kickstart_replacement (void)
        // if 68000-68020 config without any other fast ram with m68k aros: enable special extra RAM.
        if (currprefs.cpu_model <= 68020 &&
                currprefs.cachesize == 0 &&
-               currprefs.fastmem_size == 0 &&
-               currprefs.z3fastmem_size == 0 &&
+               currprefs.fastmem[0].size == 0 &&
+               currprefs.z3fastmem[0].size == 0 &&
                currprefs.mbresmem_high_size == 0 &&
                currprefs.mbresmem_low_size == 0 &&
                currprefs.cpuboardmem1_size == 0) {
@@ -1684,6 +1684,13 @@ bool mapped_malloc (addrbank *ab)
        bool rtgmem = (ab->flags & ABFLAG_RTG) != 0;
        static int recurse;
 
+       if (!_tcscmp(ab->label, _T("*"))) {
+               if (ab->start == 0 || ab->start == 0xffffffff) {
+                       write_log(_T("mapped_malloc(*) without start address!\n"));
+                       return false;
+               }
+       }
+
        ab->startmask = ab->start;
        if ((!needmman () && (!rtgmem || currprefs.cpu_model < 68020)) || (ab->flags & ABFLAG_ALLOCINDIRECT)) {
                if (!(ab->flags & ABFLAG_ALLOCINDIRECT))
@@ -1843,12 +1850,6 @@ static void allocate_memory (void)
                int memsize;
                mapped_free (&chipmem_bank);
                chipmem_bank.flags &= ~ABFLAG_NOALLOC;
-               if (currprefs.chipmem_size > 2 * 1024 * 1024) {
-                       if (currprefs.fastmem_size >= 524288)
-                               free_fastmemory (0);
-                       if (currprefs.fastmem2_size >= 524288)
-                               free_fastmemory (1);
-               }
 
                memsize = chipmem_bank.allocated = chipmem_full_size = currprefs.chipmem_size;
                chipmem_full_mask = chipmem_bank.mask = chipmem_bank.allocated - 1;
@@ -2022,10 +2023,13 @@ static void fill_ce_banks (void)
        }
        // data cachable regions (2 = burst supported)
        memset(ce_cachable, 0, sizeof ce_cachable);
-       memset(ce_cachable + (0x00200000 >> 16), 1 | 2, currprefs.fastmem_size >> 16);
        memset(ce_cachable + (0x00c00000 >> 16), 1, currprefs.bogomem_size >> 16);
-       memset(ce_cachable + (z3fastmem_bank.start >> 16), 1 | 2, currprefs.z3fastmem_size >> 16);
-       memset(ce_cachable + (z3fastmem2_bank.start >> 16), 1 | 2, currprefs.z3fastmem2_size >> 16);
+       for (int i = 0; i < MAX_RAM_BOARDS; i++) {
+               if (fastmem_bank[i].start != 0xffffffff)
+                       memset(ce_cachable + (fastmem_bank[i].start >> 16), 1 | 2, currprefs.fastmem[i].size >> 16);
+               if (z3fastmem_bank[i].start != 0xffffffff)
+                       memset(ce_cachable + (z3fastmem_bank[i].start >> 16), 1 | 2, currprefs.z3fastmem[i].size >> 16);
+       }
        memset(ce_cachable + (a3000hmem_bank.start >> 16), 1 | 2, currprefs.mbresmem_high_size >> 16);
        memset(ce_cachable + (a3000lmem_bank.start >> 16), 1 | 2, currprefs.mbresmem_low_size >> 16);
        memset(ce_cachable + (mem25bit_bank.start >> 16), 1 | 2, currprefs.mem25bit_size >> 16);
@@ -2061,7 +2065,7 @@ static void fill_ce_banks (void)
        }
 
        // A4000T NCR is 32-bit
-       if (currprefs.cs_mbdmac == 2) {
+       if (is_device_rom(&currprefs, ROMTYPE_SCSI_A4000T, 0) >= 0) {
                ce_banktype[0xdd0000 >> 16] = CE_MEMBANK_FAST32;
        }
 
@@ -2128,33 +2132,6 @@ void map_overlay (int chip)
                m68k_setpc_normal (m68k_getpc ());
 }
 
-uae_s32 getz2size (struct uae_prefs *p)
-{
-       ULONG start;
-       start = p->fastmem_size;
-       if (p->rtgboards[0].rtgmem_size && gfxboard_get_configtype(&p->rtgboards[0]) == 2) {
-               while (start & (p->rtgboards[0].rtgmem_size - 1) && start < 8 * 1024 * 1024)
-                       start += 1024 * 1024;
-               if (start + p->rtgboards[0].rtgmem_size > 8 * 1024 * 1024)
-                       return -1;
-       }
-       start += p->rtgboards[0].rtgmem_size;
-       return start;
-}
-
-uae_u32 getz2endaddr (void)
-{
-       ULONG start;
-       start = currprefs.fastmem_size;
-       if (currprefs.rtgboards[0].rtgmem_size && gfxboard_get_configtype(&currprefs.rtgboards[0]) == 2) {
-               if (!start)
-                       start = 0x00200000;
-               while (start & (currprefs.rtgboards[0].rtgmem_size - 1) && start < 4 * 1024 * 1024)
-                       start += 1024 * 1024;
-       }
-       return start + 2 * 1024 * 1024;
-}
-
 static void map_banks_set(addrbank *bank, int start, int size, int realsize)
 {
        bank->startmask = start << 16;
@@ -2311,8 +2288,8 @@ void memory_reset (void)
 
        /* map "nothing" to 0x200000 - 0x9FFFFF (0xBEFFFF if Gayle or Fat Gary) */
        bnk = chipmem_bank.allocated >> 16;
-       if (bnk < 0x20 + (currprefs.fastmem_size >> 16))
-               bnk = 0x20 + (currprefs.fastmem_size >> 16);
+       if (bnk < 0x20 + (currprefs.fastmem[0].size >> 16))
+               bnk = 0x20 + (currprefs.fastmem[0].size >> 16);
        bnk_end = currprefs.cs_cd32cd ? 0xBE : (gayleorfatgary ? 0xBF : 0xA0);
        map_banks (&dummy_bank, bnk, bnk_end - bnk, 0);
        if (gayleorfatgary) {
@@ -2345,7 +2322,7 @@ void memory_reset (void)
                        map_banks (&gayle2_bank, 0xDD, 2, 0);
                }
                gayle_map_pcmcia ();
-               if (currprefs.cs_ide == IDE_A4000 || currprefs.cs_mbdmac == 2)
+               if (currprefs.cs_ide == IDE_A4000 || is_device_rom(&currprefs, ROMTYPE_SCSI_A4000T, 0))
                        map_banks (&gayle_bank, 0xDD, 1, 0);
                if (currprefs.cs_ide < 0 && !currprefs.cs_pcmcia)
                        map_banks (&gayle_bank, 0xD8, 6, 0);
@@ -2366,18 +2343,6 @@ void memory_reset (void)
                map_banks (&gayle2_bank, 0xDD, 2, 0);
        }
 #endif
-#ifdef CDTV
-       if (currprefs.cs_cdtvcr) {
-               map_banks(&cdtvcr_bank, 0xB8, 1, 0);
-       } else if (currprefs.cs_cdtvcd) {
-               cdtv_check_banks ();
-       }
-#endif
-#ifdef A2091
-       if (currprefs.cs_mbdmac == 1)
-               a3000scsi_reset ();
-#endif
-
        if (mem25bit_bank.baseaddr)
                map_banks(&mem25bit_bank, mem25bit_bank.start >> 16, mem25bit_bank.allocated >> 16, 0);
        if (a3000lmem_bank.baseaddr)
@@ -2397,7 +2362,7 @@ void memory_reset (void)
        /* map beta Kickstarts at 0x200000/0xC00000/0xF00000 */
        if (kickmem_bank.baseaddr[0] == 0x11 && kickmem_bank.baseaddr[2] == 0x4e && kickmem_bank.baseaddr[3] == 0xf9 && kickmem_bank.baseaddr[4] == 0x00) {
                uae_u32 addr = kickmem_bank.baseaddr[5];
-               if (addr == 0x20 && currprefs.chipmem_size <= 0x200000 && currprefs.fastmem_size == 0)
+               if (addr == 0x20 && currprefs.chipmem_size <= 0x200000 && currprefs.fastmem[0].size == 0)
                        map_banks_set(&kickmem_bank, addr, 8, 0);
                if (addr == 0xC0 && currprefs.bogomem_size == 0)
                        map_banks_set(&kickmem_bank, addr, 8, 0);
@@ -2435,7 +2400,7 @@ void memory_reset (void)
        }
 
 #ifdef AUTOCONFIG
-       if (need_uae_boot_rom () && currprefs.uaeboard < 2)
+       if (need_uae_boot_rom (&currprefs) && currprefs.uaeboard < 2)
                map_banks_set(&rtarea_bank, rtarea_base >> 16, 1, 0);
 #endif
 
@@ -2808,6 +2773,8 @@ static void ppc_generate_map_banks(addrbank *bank, int start, int size)
 
 void map_banks (addrbank *bank, int start, int size, int realsize)
 {
+       if (start == 0xffffffff)
+               return;
        map_banks2 (bank, start, size, realsize, 0);
 #ifdef WITH_PPC
        ppc_generate_map_banks(bank, start, size);
@@ -2863,7 +2830,7 @@ bool validate_banks_z2(addrbank *bank, int start, int size)
                }
        }
        if (size <= 0 || size > 0x80) {
-               error_log(_T("Z2 map_banks(%s) with invalid size %08x\n"), size);
+               error_log(_T("Z2 map_banks(%s) with invalid size %08x\n"), bank->name, size);
                cpu_halt(CPU_HALT_AUTOCONFIG_CONFLICT);
                return false;
        }
index 5323858b3404f8e60fb1b9a1d5c88dff23fb6e30..b1c26cc611584e9a67a6d9a33035593b573ce779 100644 (file)
@@ -42,31 +42,32 @@ void moduleripper (void)
        uae_u8 *buf, *p;
 
        size = currprefs.chipmem_size;
-       size += currprefs.fastmem_size;
+       for (int i = 0; i < MAX_RAM_BOARDS; i++) {
+               size += currprefs.fastmem[i].size;
+               size += currprefs.z3fastmem[i].size;
+       }
        size += currprefs.bogomem_size;
        size += currprefs.mbresmem_low_size;
        size += currprefs.mbresmem_high_size;
-       size += currprefs.z3fastmem_size;
-       size += currprefs.z3fastmem2_size;
        buf = p = xmalloc (uae_u8, size);
        if (!buf)
                return;
        memcpy (p, chipmem_bank.baseaddr, currprefs.chipmem_size);
        p += currprefs.chipmem_size;
-       mc (p, fastmem_bank.start, currprefs.fastmem_size);
-       p += currprefs.fastmem_size;
-       mc (p, fastmem2_bank.start, currprefs.fastmem2_size);
-       p += currprefs.fastmem2_size;
+       for (int i = 0; i < MAX_RAM_BOARDS; i++) {
+               mc (p, fastmem_bank[i].start, currprefs.fastmem[i].size);
+               p += currprefs.fastmem[i].size;
+       }
        mc (p, bogomem_bank.start, currprefs.bogomem_size);
        p += currprefs.bogomem_size;
        mc (p, a3000lmem_bank.start, currprefs.mbresmem_low_size);
        p += currprefs.mbresmem_low_size;
        mc (p, a3000hmem_bank.start, currprefs.mbresmem_high_size);
        p += currprefs.mbresmem_high_size;
-       mc (p, z3fastmem_bank.start, currprefs.z3fastmem_size);
-       p += currprefs.z3fastmem_size;
-       mc (p, z3fastmem_bank.start + currprefs.z3fastmem_size, currprefs.z3fastmem2_size);
-       p += currprefs.z3fastmem2_size;
+       for (int i = 0; i < MAX_RAM_BOARDS; i++) {
+               mc (p, z3fastmem_bank[i].start, currprefs.z3fastmem[i].size);
+               p += currprefs.z3fastmem[i].size;
+       }
 
        got = 0;
        canceled = 0;
index 4874b81c5e655cdf880ac1b15e9c79194616f295..3efb64b20830bb5bdbacc02dcb6951f2c863c271 100644 (file)
@@ -1288,8 +1288,8 @@ static void REGPARAM2 ncr9x_wput(struct ncr9x_state *ncr, uaecptr addr, uae_u32
                switch (addr)
                {
                        case 0x44:
-                       map_banks_z3(ncr->bank, expamem_z3_pointer >> 16, FASTLANE_BOARD_SIZE >> 16);
-                       ncr->baseaddress = expamem_z3_pointer;
+                       map_banks_z3(ncr->bank, expamem_board_pointer >> 16, FASTLANE_BOARD_SIZE >> 16);
+                       ncr->baseaddress = expamem_board_pointer;
                        ncr->configured = 1;
                        expamem_next (ncr->bank, NULL);
                        break;
@@ -1316,9 +1316,9 @@ static void REGPARAM2 ncr9x_bput(struct ncr9x_state *ncr, uaecptr addr, uae_u32
                        case 0x48:
                        if (isncr(ncr, ncr_fastlane_scsi))
                                return;
-                       map_banks_z2(ncr->bank, expamem_z2_pointer >> 16, expamem_z2_size >> 16);
+                       map_banks_z2(ncr->bank, expamem_board_pointer >> 16, expamem_board_size >> 16);
                        ncr->configured = 1;
-                       ncr->baseaddress = expamem_z2_pointer;
+                       ncr->baseaddress = expamem_board_pointer;
                        expamem_next (ncr->bank, NULL);
                        break;
                        case 0x4c:
@@ -1479,15 +1479,18 @@ void ncr_golemfast_autoconfig_init(struct romconfig *rc, uaecptr baseaddress)
        ncr9x_reset_board(ncr);
 }
 
-addrbank *ncr_multievolution_init(struct romconfig *rc)
+bool ncr_multievolution_init(struct autoconfig_info *aci)
 {
-       struct ncr9x_state *ncr = getscsi(rc);
+       if (!aci->doinit)
+               return true;
+
+       struct ncr9x_state *ncr = getscsi(aci->rc);
 
        xfree(ncr->rom);
        ncr->rom = NULL;
 
        if (!ncr)
-               return &expamem_null;
+               return false;
 
        ncr->bank = &ncr9x_bank_generic;
        ncr->enabled = true;
@@ -1505,25 +1508,52 @@ addrbank *ncr_multievolution_init(struct romconfig *rc)
        ncr->io_end = ncr->io_start + 0x2000;
        ncr->irq6 = true;
 
-       load_rom_rc(rc, ROMTYPE_MEVOLUTION, 65536, 0, ncr->rom, 65536, 0);
+       load_rom_rc(aci->rc, ROMTYPE_MEVOLUTION, 65536, 0, ncr->rom, 65536, 0);
 
        map_banks(ncr->bank, ncr->baseaddress2 >> 16, (ncr->board_mask + 1) >> 16, 0);
 
-       return &expamem_null;
+       aci->addrbank = &expamem_null;
+       return true;
 }
 
-addrbank *ncr_fastlane_autoconfig_init(struct romconfig *rc)
+bool ncr_fastlane_autoconfig_init(struct autoconfig_info *aci)
 {
-       struct ncr9x_state *ncr = getscsi(rc);
+       struct zfile *z = read_device_from_romconfig(aci->rc, ROMTYPE_FASTLANE);
+       uae_u8 *rom = xcalloc(uae_u8, FASTLANE_ROM_SIZE * 4);
+       if (z) {
+               // memory board at offset 0x100
+               int autoconfig_offset = 0;
+               memset(rom, 0xff, FASTLANE_ROM_SIZE * 4);
+               for (int i = 0; i < FASTLANE_ROM_SIZE; i++) {
+                       int ia = i - autoconfig_offset;
+                       uae_u8 b;
+                       zfile_fread(&b, 1, 1, z);
+                       rom[i * 4 + 0] = b | 0x0f;
+                       rom[i * 4 + 2] = (b << 4) | 0x0f;
+                       if (ia >= 0 && ia < 0x20) {
+                               aci->autoconfig_raw[ia * 4 + 0] = b;
+                       } else if (ia >= 0x40 && ia < 0x60) {
+                               aci->autoconfig_raw[(ia - 0x40) * 4 + 2] = b;
+                       }
+               }
+               zfile_fclose(z);
+       }
+
+       if (!aci->doinit) {
+               xfree(rom);
+               return true;
+       }
+
+       struct ncr9x_state *ncr = getscsi(aci->rc);
 
        xfree(ncr->rom);
-       ncr->rom = NULL;
+       ncr->rom = rom;
 
        if (!ncr)
-               return &expamem_null;
+               return false;
 
        ncr->enabled = true;
-       memset (ncr->acmemory, 0xff, sizeof ncr->acmemory);
+       memcpy(ncr->acmemory, aci->autoconfig_raw, sizeof ncr->acmemory);
        ncr->rom_start = 0x800;
        ncr->rom_offset = 0;
        ncr->rom_end = FASTLANE_ROM_SIZE * 4;
@@ -1533,28 +1563,8 @@ addrbank *ncr_fastlane_autoconfig_init(struct romconfig *rc)
 
        ncr9x_reset_board(ncr);
 
-       struct zfile *z = read_device_from_romconfig(rc, ROMTYPE_FASTLANE);
-       ncr->rom = xcalloc (uae_u8, FASTLANE_ROM_SIZE * 4);
-       if (z) {
-               // memory board at offset 0x100
-               int autoconfig_offset = 0;
-               memset(ncr->rom, 0xff, FASTLANE_ROM_SIZE * 4);
-               for (int i = 0; i < FASTLANE_ROM_SIZE; i++) {
-                       int ia = i - autoconfig_offset;
-                       uae_u8 b;
-                       zfile_fread (&b, 1, 1, z);
-                       ncr->rom[i * 4 + 0] = b | 0x0f;
-                       ncr->rom[i * 4 + 2] = (b << 4) | 0x0f;
-                       if (ia >= 0 && ia < 0x20) {
-                               ncr->acmemory[ia * 4 + 0] = b;
-                       } else if (ia >= 0x40 && ia < 0x60) {
-                               ncr->acmemory[(ia - 0x40) * 4 + 2] = b;
-                       }
-               }
-               zfile_fclose(z);
-       }
-
-       return ncr->bank;
+       aci->addrbank = ncr->bank;
+       return true;
 }
 
 static const uae_u8 oktagon_autoconfig[16] = {
@@ -1567,12 +1577,15 @@ static const uae_u8 oktagon_eeprom[16] =
        0x0b, 0xf4, 0x3f, 0x0a, 0xff, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0xaf, 0xff
 };
 
-addrbank *ncr_oktagon_autoconfig_init(struct romconfig *rc)
+bool ncr_oktagon_autoconfig_init(struct autoconfig_info *aci)
 {
-       struct ncr9x_state *ncr = getscsi(rc);
+       aci->autoconfigp = oktagon_autoconfig;
+       if (!aci->doinit)
+               return true;
 
+       struct ncr9x_state *ncr = getscsi(aci->rc);
        if (!ncr)
-               return &expamem_null;
+               return false;
 
        xfree(ncr->rom);
        ncr->rom = NULL;
@@ -1597,8 +1610,8 @@ addrbank *ncr_oktagon_autoconfig_init(struct romconfig *rc)
 
        ncr9x_reset_board(ncr);
 
-       if (!rc->autoboot_disabled) {
-               struct zfile *z = read_device_from_romconfig(rc, ROMTYPE_OKTAGON);
+       if (!aci->rc->autoboot_disabled) {
+               struct zfile *z = read_device_from_romconfig(aci->rc, ROMTYPE_OKTAGON);
                if (z) {
                        // memory board at offset 0x100
                        memset(ncr->rom, 0xff, OKTAGON_ROM_SIZE * 4);
@@ -1624,16 +1637,19 @@ addrbank *ncr_oktagon_autoconfig_init(struct romconfig *rc)
                ew(ncr, i * 4, b);
        }
 
-       return ncr->bank;
+       aci->addrbank = ncr->bank;
+       return true;
 }
 
 
-addrbank *ncr_dkb_autoconfig_init(struct romconfig *rc)
+bool ncr_dkb_autoconfig_init(struct autoconfig_info *aci)
 {
-       struct ncr9x_state *ncr = getscsi(rc);
+       if (!aci->doinit)
+               return true;
 
+       struct ncr9x_state *ncr = getscsi(aci->rc);
        if (!ncr)
-               return &expamem_null;
+               return false;
 
        xfree(ncr->rom);
        ncr->rom = NULL;
@@ -1650,7 +1666,7 @@ addrbank *ncr_dkb_autoconfig_init(struct romconfig *rc)
 
        ncr9x_reset_board(ncr);
 
-       struct zfile *z = read_device_from_romconfig(rc, ROMTYPE_CB_DKB12x0);
+       struct zfile *z = read_device_from_romconfig(aci->rc, ROMTYPE_CB_DKB12x0);
        ncr->rom = xcalloc (uae_u8, DKB_ROM_SIZE * 2);
        if (z) {
                // memory board at offset 0x100
@@ -1673,21 +1689,48 @@ addrbank *ncr_dkb_autoconfig_init(struct romconfig *rc)
                zfile_fclose(z);
        }
 
-       return ncr->bank;
+       aci->addrbank = ncr->bank;
+       return true;
 }
 
-addrbank *ncr_ematrix_autoconfig_init(struct romconfig *rc)
+bool ncr_ematrix_autoconfig_init(struct autoconfig_info *aci)
 {
-       struct ncr9x_state *ncr = getscsi(rc);
+       struct zfile *z = read_device_from_romconfig(aci->rc, ROMTYPE_CB_EMATRIX);
+       uae_u8 *rom = xcalloc(uae_u8, 65536);
+       if (z) {
+               int i;
+               memset(rom, 0xff, 65536);
 
+               zfile_fseek(z, 32768, SEEK_SET);
+               for (i = 0; i < (sizeof aci->autoconfig_raw) / 2; i++) {
+                       uae_u8 b;
+                       zfile_fread(&b, 1, 1, z);
+                       aci->autoconfig_raw[i * 2] = b;
+               }
+               for (;;) {
+                       uae_u8 b;
+                       if (!zfile_fread(&b, 1, 1, z))
+                               break;
+                       rom[i * 2] = b;
+                       i++;
+               }
+               zfile_fclose(z);
+       }
+
+       if (!aci->doinit) {
+               xfree(rom);
+               return true;
+       }
+
+       struct ncr9x_state *ncr = getscsi(aci->rc);
        if (!ncr)
-               return &expamem_null;
+               return false;
 
        xfree(ncr->rom);
        ncr->rom = NULL;
 
        ncr->enabled = true;
-       memset(ncr->acmemory, 0xff, sizeof ncr->acmemory);
+       memcpy(ncr->acmemory, aci->autoconfig_raw, sizeof aci->autoconfig_raw);
        ncr->rom_start = 0;
        ncr->rom_offset = 0;
        ncr->rom_end = 0x8000;
@@ -1698,29 +1741,8 @@ addrbank *ncr_ematrix_autoconfig_init(struct romconfig *rc)
 
        ncr9x_reset_board(ncr);
 
-       struct zfile *z = read_device_from_romconfig(rc, ROMTYPE_CB_EMATRIX);
-       ncr->rom = xcalloc(uae_u8, 65536);
-       if (z) {
-               int i;
-               memset(ncr->rom, 0xff, 65536);
-
-               zfile_fseek(z, 32768, SEEK_SET);
-               for (i = 0; i < (sizeof ncr->acmemory) / 2; i++) {
-                       uae_u8 b;
-                       zfile_fread(&b, 1, 1, z);
-                       ncr->acmemory[i * 2] = b;
-               }
-               for (;;) {
-                       uae_u8 b;
-                       if (!zfile_fread(&b, 1, 1, z))
-                               break;
-                       ncr->rom[i * 2] = b;
-                       i++;
-               }
-               zfile_fclose(z);
-       }
-
-       return ncr->bank;
+       aci->addrbank = ncr->bank;
+       return true;
 }
 
 void ncr_masoboshi_autoconfig_init(struct romconfig *rc, uaecptr baseaddress)
index 1f6bd4cd8386444452000a8010322f9a50070294..6ca84800f2cac218afdaea351fd0aa65db0f9c38 100644 (file)
@@ -536,9 +536,9 @@ static void REGPARAM2 ncr_wput (struct ncr_state *ncr, uaecptr addr, uae_u32 w)
                switch (addr)
                {
                        case 0x44:
-                       map_banks_z3(ncr->bank, expamem_z3_pointer >> 16, BOARD_SIZE >> 16);
+                       map_banks_z3(ncr->bank, expamem_board_pointer >> 16, BOARD_SIZE >> 16);
                        ncr->board_mask = 0x00ffffff;
-                       ncr->baseaddress = expamem_z3_pointer;
+                       ncr->baseaddress = expamem_board_pointer;
                        ncr->configured = 1;
                        expamem_next (ncr->bank, NULL);
                        break;
@@ -747,12 +747,15 @@ static const uae_u8 warpengine_a4000_autoconfig[16] = {
 };
 #define WARP_ENGINE_ROM_SIZE 32768
 
-addrbank *ncr710_warpengine_autoconfig_init(struct romconfig *rc)
+bool ncr710_warpengine_autoconfig_init(struct autoconfig_info *aci)
 {
-       struct ncr_state *ncr = getscsi(rc);
+       aci->autoconfigp = warpengine_a4000_autoconfig;
+       if (!aci->doinit)
+               return true;
 
+       struct ncr_state *ncr = getscsi(aci->rc);
        if (!ncr)
-               return &expamem_null;
+               return false;
 
        ncr_we = ncr;
        xfree(ncr->rom);
@@ -778,7 +781,7 @@ addrbank *ncr710_warpengine_autoconfig_init(struct romconfig *rc)
                ew(ncr, i * 4, b);
        }
        ncr->rom = xcalloc (uae_u8, WARP_ENGINE_ROM_SIZE * 4);
-       struct zfile *z = read_device_from_romconfig(rc, ROMTYPE_CB_WENGINE);
+       struct zfile *z = read_device_from_romconfig(aci->rc, ROMTYPE_CB_WENGINE);
        if (z) {
                for (int i = 0; i < WARP_ENGINE_ROM_SIZE; i++) {
                        uae_u8 b = 0xff;
@@ -793,21 +796,44 @@ addrbank *ncr710_warpengine_autoconfig_init(struct romconfig *rc)
 
        ncr_reset_board(ncr);
 
-       return &ncr_bank_generic;
+       aci->addrbank = &ncr_bank_generic;
+       return true;
 }
 
-addrbank *ncr710_a4091_autoconfig_init (struct romconfig *rc)
+bool ncr710_a4091_autoconfig_init (struct autoconfig_info *aci)
 {
-       struct ncr_state *ncr = getscsi(rc);
+       uae_u8 *rom = NULL;
+       struct zfile *z = read_device_from_romconfig(aci->rc, ROMTYPE_A4091);
+       if (z) {
+               rom = xmalloc(uae_u8, A4091_ROM_SIZE * 4);
+               for (int i = 0; i < A4091_ROM_SIZE; i++) {
+                       uae_u8 b;
+                       zfile_fread(&b, 1, 1, z);
+                       rom[i * 4 + 0] = b | 0x0f;
+                       rom[i * 4 + 2] = (b << 4) | 0x0f;
+                       if (i < 0x20) {
+                               aci->autoconfig_raw[i * 4 + 0] = b;
+                       } else if (i >= 0x40 && i < 0x60) {
+                               aci->autoconfig_raw[(i - 0x40) * 4 + 2] = b;
+                       }
+               }
+               zfile_fclose(z);
+       }
+
+       if (!aci->doinit) {
+               xfree(rom);
+               return true;
+       }
 
+       struct ncr_state *ncr = getscsi(aci->rc);
        if (!ncr)
-               return &expamem_null;
+               return false;
 
        xfree(ncr->rom);
-       ncr->rom = NULL;
+       ncr->rom = rom;
 
        ncr->enabled = true;
-       memset (ncr->acmemory, 0xff, sizeof ncr->acmemory);
+       memcpy(ncr->acmemory, aci->autoconfig_raw, sizeof ncr->acmemory);
        ncr->rom_start = 0;
        ncr->rom_offset = A4091_ROM_OFFSET;
        ncr->rom_end = A4091_IO_OFFSET;
@@ -816,24 +842,8 @@ addrbank *ncr710_a4091_autoconfig_init (struct romconfig *rc)
 
        ncr_reset_board(ncr);
 
-       struct zfile *z = read_device_from_romconfig(rc, ROMTYPE_A4091);
-       if (z) {
-               ncr->rom = xmalloc (uae_u8, A4091_ROM_SIZE * 4);
-               for (int i = 0; i < A4091_ROM_SIZE; i++) {
-                       uae_u8 b;
-                       zfile_fread (&b, 1, 1, z);
-                       ncr->rom[i * 4 + 0] = b | 0x0f;
-                       ncr->rom[i * 4 + 2] = (b << 4) | 0x0f;
-                       if (i < 0x20) {
-                               ncr->acmemory[i * 4 + 0] = b;
-                       } else if (i >= 0x40 && i < 0x60) {
-                               ncr->acmemory[(i - 0x40) * 4 + 2] = b;
-                       }
-               }
-               zfile_fclose(z);
-       }
-
-       return &ncr_bank_generic;
+       aci->addrbank = &ncr_bank_generic;
+       return true;
 }
 
 void ncr_free(void)
@@ -915,6 +925,19 @@ static void ncr_add_scsi_unit(struct ncr_state **ncrp, int ch, struct uaedev_con
        }
 }
 
+bool a4000t_scsi_init(struct autoconfig_info *aci)
+{
+       aci->start = 0xdd0000;
+       aci->size = 0x10000;
+       aci->addrbank = &expamem_nonautoconfig;
+       return true;
+}
+
+bool is_a4000t_scsi(void)
+{
+       return ncr_a4000t && ncr_a4000t->enabled;
+}
+
 void a4000t_add_scsi_unit (int ch, struct uaedev_config_info *ci, struct romconfig *rc)
 {
        ncr_add_scsi_unit(&ncr_a4000t, ch, ci, rc, false);
index 412909111e02b292b058e6e558bb675503e83dbf..d0a0188cd7695da4b8ec86671b6edc8b2202a4d8 100644 (file)
@@ -115,6 +115,8 @@ static int icachelinecnt, dcachelinecnt;
 static struct cache040 icaches040[CACHESETS040];
 static struct cache040 dcaches040[CACHESETS040];
 
+int cpu_last_stop_vpos, cpu_stopped_lines;
+
 #if COUNT_INSTRS
 static unsigned long int instrcount[65536];
 static uae_u16 opcodenums[65536];
@@ -2013,6 +2015,23 @@ STATIC_INLINE int adjust_cycles (int cycles)
        return cycles + mc;
 }
 
+static void m68k_set_stop(void)
+{
+       if (regs.stopped)
+               return;
+       regs.stopped = 1;
+       set_special(SPCFLAG_STOP);
+       cpu_last_stop_vpos = vpos;
+}
+
+static void m68k_unset_stop(void)
+{
+       regs.stopped = 0;
+       unset_special(SPCFLAG_STOP);
+       cpu_stopped_lines += vpos - cpu_last_stop_vpos;
+       cpu_last_stop_vpos = vpos;
+}
+
 void REGPARAM2 MakeSR (void)
 {
        regs.sr = ((regs.t1 << 15) | (regs.t0 << 14)
@@ -2966,8 +2985,7 @@ static void do_interrupt (int nr)
                        inprec_playdebug_cpu (2);
        }
 
-       regs.stopped = 0;
-       unset_special (SPCFLAG_STOP);
+       m68k_unset_stop();
        assert (nr < 8 && nr >= 0);
 
        for (;;) {
@@ -3505,8 +3523,9 @@ bool execute_other_cpu(int until)
        return true;
 }
 
-void cpu_sleep_millis(int ms)
+int cpu_sleep_millis(int ms)
 {
+       int ret = 0;
 #ifdef WITH_THREADED_CPU
        cpu_semaphore_release();
 #endif
@@ -3519,7 +3538,7 @@ void cpu_sleep_millis(int ms)
        if (x86_turbo_on) {
                execute_other_cpu(read_processor_time() + vsynctimebase / 20);
        } else {
-               sleep_millis_main(ms);
+               ret = sleep_millis_main(ms);
        }
 #endif
 #ifdef WITH_PPC
@@ -3529,6 +3548,7 @@ void cpu_sleep_millis(int ms)
 #ifdef WITH_THREADED_CPU
        cpu_semaphore_get();
 #endif
+       return ret;
 }
 
 #define PPC_HALTLOOP_SCANLINES 25
@@ -3700,8 +3720,6 @@ void doint (void)
                set_special (SPCFLAG_DOINT);
 }
 
-#define IDLETIME (currprefs.cpu_idle * sleep_resolution / 1000)
-
 static int do_specialties (int cycles)
 {
        if (regs.spcflags & SPCFLAG_MODE_CHANGE)
@@ -6863,11 +6881,10 @@ void cpureset (void)
 
 void m68k_setstopped (void)
 {
-       regs.stopped = 1;
        /* A traced STOP instruction drops through immediately without
        actually stopping.  */
        if ((regs.spcflags & SPCFLAG_DOTRACE) == 0) {
-               set_special (SPCFLAG_STOP);
+               m68k_set_stop();
        } else {
                m68k_resumestopped ();
        }
@@ -6877,12 +6894,11 @@ void m68k_resumestopped (void)
 {
        if (!regs.stopped)
                return;
-       regs.stopped = 0;
        if (currprefs.cpu_cycle_exact && currprefs.cpu_model == 68000) {
                x_do_cycles (6 * cpucycleunit);
        }
        fill_prefetch ();
-       unset_special (SPCFLAG_STOP);
+       m68k_unset_stop();
 }
 
 
index 8c17f0469497bfdcfdeed7cbe8e3815d3c97e465..10ba36961c3b8e981c84d4bde685078b27302d1d 100644 (file)
@@ -107,7 +107,7 @@ static uae_u32 REGPARAM2 emulib_ExecuteNativeCode2 (TrapContext *context)
        uae_u32 a7 = m68k_areg (regs, 7);
        uae_u32 regs_ = (uae_u32)&regs;
        CREATE_NATIVE_FUNC_PTR2;
-       uaevar.z3offset = (uae_u32)(get_real_address (z3fastmem_bank.start) - z3fastmem_bank.start);
+       uaevar.z3offset = (uae_u32)(get_real_address (z3fastmem_bank[0].start) - z3fastmem_bank[0].start);
        uaevar.amigawnd = hAmigaWnd;
        a6 = &uaevar;
        if (object_UAM)  {
index 8676e41d6d5390433ce3d2361cbc71d2bcc8517a..5995e285717d51239101673317cb15a866b34ddd 100644 (file)
@@ -239,7 +239,7 @@ static void storesettings (UAEREG *avikey)
        regsetint(avikey, _T("RecordMode"), avioutput_audio);
        regsetstr(avikey, _T("FileName"), avioutput_filename_gui);
 }
-static void getsettings (UAEREG *avikey)
+static void getsettings (UAEREG *avikey, bool allowaudio)
 {
        int val;
        if (regqueryint (avikey, _T("NoSoundOutput"), &val))
@@ -254,8 +254,10 @@ static void getsettings (UAEREG *avikey)
                avioutput_nosoundoutput = 1;
        if (regqueryint (avikey, _T("FPS"), &val))
                avioutput_fps = val;
-       if (regqueryint(avikey, _T("RecordMode"), &val))
-               avioutput_audio = val;
+       if (allowaudio) {
+               if (regqueryint(avikey, _T("RecordMode"), &val))
+                       avioutput_audio = val;
+       }
        val = sizeof avioutput_filename_gui / sizeof(TCHAR);
        regquerystr(avikey, _T("FileName"), avioutput_filename_gui, &val);
 }
@@ -264,7 +266,7 @@ void AVIOutput_GetSettings (void)
 {
        UAEREG *avikey = openavikey ();
        if (avikey)
-               getsettings (avikey);
+               getsettings (avikey, true);
        regclosetree (avikey);
 }
 void AVIOutput_SetSettings (void)
@@ -373,8 +375,10 @@ static int AVIOutput_ValidateAudio (WAVEFORMATEX *wft, TCHAR *name, int len)
        aftd.cbStruct = sizeof (ACMFORMATTAGDETAILS);
        aftd.dwFormatTag = wft->wFormatTag;
        ret = acmFormatTagDetails (NULL, &aftd, ACM_FORMATTAGDETAILSF_FORMATTAG);
-       if (ret)
+       if (ret) {
+               write_log(_T("acmFormatTagDetails %08x failed\n"), wft->wFormatTag);
                return 0;
+       }
 
        memset (&afd, 0, sizeof (ACMFORMATDETAILS));
        afd.cbStruct = sizeof (ACMFORMATDETAILS);
@@ -382,8 +386,10 @@ static int AVIOutput_ValidateAudio (WAVEFORMATEX *wft, TCHAR *name, int len)
        afd.pwfx = wft;
        afd.cbwfx = sizeof (WAVEFORMATEX) + wft->cbSize;
        ret = acmFormatDetails (NULL, &afd, ACM_FORMATDETAILSF_FORMAT);
-       if (ret)
+       if (ret) {
+               write_log(_T("acmFormatDetails %08x failed\n"), wft->wFormatTag);
                return 0;
+       }
 
        if (name)
                _stprintf (name, _T("%s %s"), aftd.szFormatTag, afd.szFormat);
@@ -400,7 +406,7 @@ static int AVIOutput_GetAudioFromRegistry (WAVEFORMATEX *wft)
        avikey = openavikey ();
        if (!avikey)
                return 0;
-       getsettings (avikey);
+       getsettings (avikey, true);
        if (wft) {
                ok = -1;
                ss = wfxMaxFmtSize;
@@ -428,8 +434,11 @@ int AVIOutput_GetAudioCodec (TCHAR *name, int len)
        if (!AVIOutput_AllocateAudio ())
                return 0;
        if (AVIOutput_GetAudioFromRegistry (pwfxDst) > 0) {
-               AVIOutput_GetAudioCodecName (pwfxDst, name, len);
-               return 1;
+               if (AVIOutput_GetAudioCodecName (pwfxDst, name, len)) {
+                       write_log(_T("Audio: %s\n"), name);
+                       return 1;
+               }
+               write_log(_T("Failed to open audio %08x\n"), pwfxDst->wFormatTag);
        }
        AVIOutput_ReleaseAudio ();
        return 0;
@@ -597,7 +606,7 @@ static int AVIOutput_GetCOMPVARSFromRegistry (COMPVARS *pcv)
        avikey = openavikey ();
        if (!avikey)
                return 0;
-       getsettings (avikey);
+       getsettings (avikey, false);
        if (pcv) {
                ok = -1;
                ss = pcv->cbSize;
@@ -655,8 +664,11 @@ int AVIOutput_GetVideoCodec (TCHAR *name, int len)
                return 0;
        AVIOutput_FreeVideoDstFormat ();
        if (AVIOutput_GetCOMPVARSFromRegistry (pcompvars) > 0) {
-               AVIOutput_GetVideoCodecName (pcompvars, name, len);
-               return 1;
+               if (AVIOutput_GetVideoCodecName (pcompvars, name, len)) {
+                       write_log(_T("Video %s\n"), name);
+                       return 1;
+               }
+               write_log(_T("Failed to open video %08x\n"), pcompvars->fccType);
        }
        AVIOutput_ReleaseVideo ();
        return 0;
index b34b88df4b41dbbb71b88254b970b37c8d218b50..62f4e0289ab98a13911d0bc13b12293012f0224c 100644 (file)
@@ -475,11 +475,11 @@ static int cdda_openwav (struct dev_info_ioctl *ciw)
        return 1;
 }
 
-static int setstate (struct dev_info_ioctl *ciw, int state)
+static int setstate (struct dev_info_ioctl *ciw, int state, int playpos)
 {
        ciw->cdda_play_state = state;
        if (ciw->cdda_statusfunc)
-               return ciw->cdda_statusfunc (ciw->cdda_play_state);
+               return ciw->cdda_statusfunc (ciw->cdda_play_state, playpos);
        return 0;
 }
 
@@ -602,13 +602,13 @@ static void *cdda_play (void *v)
                                cdda_pos += ch;
                        }
 
-                       setstate (ciw, AUDIO_STATUS_IN_PROGRESS);
+                       setstate (ciw, AUDIO_STATUS_IN_PROGRESS, cdda_pos);
                }
 
                if ((cdda_pos < ciw->cdda_end || ciw->cdda_end == 0xffffffff) && !ciw->cdda_paused && ciw->cdda_play) {
 
                        if (idleframes <= 0 && cdda_pos >= ciw->cdda_start && !isaudiotrack (&ciw->di.toc, cdda_pos)) {
-                               setstate (ciw, AUDIO_STATUS_PLAY_ERROR);
+                               setstate (ciw, AUDIO_STATUS_PLAY_ERROR, -1);
                                write_log (_T("IOCTL: attempted to play data track %d\n"), cdda_pos);
                                goto end; // data track?
                        }
@@ -622,6 +622,9 @@ static void *cdda_play (void *v)
                        memset (cda->buffers[bufnum], 0, CDDA_BUFFERS * readblocksize);
 
                        if (cdda_pos >= 0) {
+
+                               setstate(ciw, AUDIO_STATUS_IN_PROGRESS, cdda_pos);
+
                                if (read_block (ciw, -1, cda->buffers[bufnum], cdda_pos, CDDA_BUFFERS, readblocksize)) {
                                        for (i = 0; i < CDDA_BUFFERS; i++) {
                                                memcpy (ciw->subcode + i * SUB_CHANNEL_SIZE, cda->buffers[bufnum] + readblocksize * i + 2352, SUB_CHANNEL_SIZE);
@@ -671,7 +674,7 @@ static void *cdda_play (void *v)
                                cda_bufon[bufnum] = 1;
                                cda->setvolume (ciw->cdda_volume[0], ciw->cdda_volume[1]);
                                if (!cda->play (bufnum)) {
-                                       setstate (ciw, AUDIO_STATUS_PLAY_ERROR);
+                                       setstate (ciw, AUDIO_STATUS_PLAY_ERROR, -1);
                                        goto end; // data track?
                                }
                        }
@@ -689,10 +692,10 @@ static void *cdda_play (void *v)
 
                        if (idleframes <= 0) {
                                if (cdda_pos - CDDA_BUFFERS < ciw->cdda_end && cdda_pos >= ciw->cdda_end) {
-                                       setstate (ciw, AUDIO_STATUS_PLAY_COMPLETE);
+                                       cdda_pos = ciw->cdda_end;
+                                       setstate (ciw, AUDIO_STATUS_PLAY_COMPLETE, cdda_pos);
                                        ciw->cdda_play_finished = 1;
                                        ciw->cdda_play = -1;
-                                       cdda_pos = ciw->cdda_end;
                                }
                                ciw->cd_last_pos = cdda_pos;
                        }
@@ -782,16 +785,16 @@ static int ioctl_command_play (int unitnum, int startlsn, int endlsn, int scan,
        ciw->cdda_subfunc = subfunc;
        ciw->cdda_statusfunc = statusfunc;
        ciw->cdda_scan = scan > 0 ? 10 : (scan < 0 ? 10 : 0);
-       ciw->cdda_delay = setstate (ciw, -1);
-       ciw->cdda_delay_frames = setstate (ciw, -2);
-       setstate (ciw, AUDIO_STATUS_NOT_SUPPORTED);
+       ciw->cdda_delay = setstate (ciw, -1, -1);
+       ciw->cdda_delay_frames = setstate (ciw, -2, -1);
+       setstate (ciw, AUDIO_STATUS_NOT_SUPPORTED, -1);
 
        if (!open_createfile (ciw, 0)) {
-               setstate (ciw, AUDIO_STATUS_PLAY_ERROR);
+               setstate (ciw, AUDIO_STATUS_PLAY_ERROR, -1);
                return 0;
        }
        if (!isaudiotrack (&ciw->di.toc, startlsn)) {
-               setstate (ciw, AUDIO_STATUS_PLAY_ERROR);
+               setstate (ciw, AUDIO_STATUS_PLAY_ERROR, -1);
                return 0;
        }
        if (!ciw->cdda_play) {
index 827d27a5d257c5c2c0f60227e439e7123c6b3a4e..aacba436dcb9a763679eddccabaad9c15ad6e5e0 100644 (file)
@@ -12,6 +12,7 @@
 #include "clipboard.h"
 #include "keybuf.h"
 
+#include "options.h"
 #include "threaddep/thread.h"
 #include "memory.h"
 #include "native2amiga_api.h"
index fc8f34206a30bb3456a960d44253831fe8f46f95..586bd55ce804aac8b556a456e9d28dd9d75d4e0c 100644 (file)
@@ -2,14 +2,14 @@
  Name    : RetroPlatformGuestIPC.c
  Project : RetroPlatform Player
  Support : http://www.retroplatform.com
- Legal   : Copyright 2007-2012 Cloanto Italia srl - All rights reserved. This
+ Legal   : Copyright 2007-2016 Cloanto Italia srl - All rights reserved. This
          : file is multi-licensed under the terms of the Mozilla Public License
          : version 2.0 as published by Mozilla Corporation and the GNU General
          : Public License, version 2 or later, as published by the Free
          : Software Foundation.
  Authors : os, mcb
  Created : 2007-08-24 15:28:48
- Updated : 2012-11-29 13:47:00
+ Updated : 2016-06-17 11:18:00
  Comment : RetroPlatform Player interprocess communication functions (guest side)
  Note    : Can be compiled both in Unicode and Multibyte projects
  *****************************************************************************/
@@ -25,6 +25,18 @@ static const _TCHAR g_szHostWndClass[]  = _T(RPIPC_HostWndClass);
 static const _TCHAR g_szGuestWndClass[] = _T(RPIPC_GuestWndClass);
 static const WCHAR g_szRegistration[]   = L"Cloanto(R) RetroPlatform(TM)";
 
+#define VK_NOP 0xFF // do-nothing key (disables Windows keys functionality)
+
+static BOOL g_bLeftWinDown = FALSE;
+static BOOL g_bRightWinDown = FALSE;
+static int g_nIgnoreLeftWinUp = 0;
+static int g_nIgnoreRightWinUp = 0;
+
+struct VKeyFlags
+{
+       int nVKey;
+       DWORD dwFlags;
+};
 
 
 /*****************************************************************************
@@ -57,23 +69,33 @@ HRESULT RPInitializeGuest(RPGUESTINFO *pInfo, HINSTANCE hInstance, LPCTSTR pszHo
        pInfo->bGuestClassRegistered = FALSE;
        pInfo->pfnMsgFunction = pfnMsgFunction;
        pInfo->lMsgFunctionParam = lMsgFunctionParam;
+    pInfo->hUser32 = LoadLibrary(_T("user32.dll"));
+    pInfo->pfnToUnicode = pInfo->hUser32 ? (TOUNICODEFN)GetProcAddress(pInfo->hUser32, "ToUnicode") : NULL;
 
        // find the host message window
        //
        pszHostClass = (_TCHAR *)LocalAlloc(LMEM_FIXED, (_tcslen(g_szHostWndClass) + _tcslen(pszHostInfo) + 1) * sizeof(_TCHAR));
        if (!pszHostClass)
+       {
+               RPUninitializeGuest(pInfo);
                return E_OUTOFMEMORY;
+       }
        wsprintf(pszHostClass, g_szHostWndClass, pszHostInfo);
        pInfo->hHostMessageWindow = FindWindow(pszHostClass, NULL);
        LocalFree(pszHostClass);
        if (!pInfo->hHostMessageWindow)
+       {
+               RPUninitializeGuest(pInfo);
                return HRESULT_FROM_WIN32(ERROR_HOST_UNREACHABLE);
-
+       }
        // create the guest message window
        //
        wsprintf(szGuestClass, g_szGuestWndClass, GetCurrentProcessId());
        if (!RegisterWndClass(szGuestClass, hInstance))
+       {
+               RPUninitializeGuest(pInfo);
                return HRESULT_FROM_WIN32(GetLastError());
+       }
        pInfo->bGuestClassRegistered = TRUE;
        //
        pInfo->hGuestMessageWindow = CreateWindow(szGuestClass, NULL, 0, 0,0, 1,1, NULL, NULL, hInstance, (LPVOID)pInfo);
@@ -127,6 +149,12 @@ void RPUninitializeGuest(RPGUESTINFO *pInfo)
                UnregisterClass(szGuestClass, pInfo->hInstance);
                pInfo->bGuestClassRegistered = FALSE;
        }
+    if (pInfo->hUser32)
+       {
+               FreeLibrary(pInfo->hUser32);
+               pInfo->hUser32 = NULL;
+               pInfo->pfnToUnicode = NULL;
+       }
 }
 
 /*****************************************************************************
@@ -277,3 +305,229 @@ static LRESULT CALLBACK RPGuestWndProc(HWND hWnd, UINT uMessage, WPARAM wParam,
                return DefWindowProc(hWnd, uMessage, wParam, lParam);
        }
 }
+
+/*****************************************************************************
+ Name      : RPProcessKeyboardInput
+ Arguments : DWORD dwFlags            - 
+           : BYTE btVirtualKey        - wParam & 0xFF, for a WM_KEYDOWN/WM_KEYUP message
+           : BYTE btScanCode          - (lParam >> 16) & 0xFF, for a WM_KEYDOWN/WM_KEYUP message
+           : const RPGUESTINFO *pInfo - 
+           : LRESULT *plResult        - 
+ Return    : HRESULT                  - 
+ Authors   : os
+ Created   : 2016-06-21 11:04:38
+ Comment   : 
+ *****************************************************************************/
+
+HRESULT RPProcessKeyboardInput(DWORD dwFlags, BYTE btVirtualKey, BYTE btScanCode, const RPGUESTINFO *pInfo, LRESULT *plResult)
+{
+       static const struct VKeyFlags s_VKeyFlags[] =
+       {
+               { VK_CAPITAL,  RP_PREPROCESSKEY_CAPS_DOWN   },
+               { VK_SHIFT,    RP_PREPROCESSKEY_SHIFT_DOWN  },
+               { VK_LSHIFT,   RP_PREPROCESSKEY_LSHIFT_DOWN },
+               { VK_RSHIFT,   RP_PREPROCESSKEY_RSHIFT_DOWN },
+               { VK_MENU,     RP_PREPROCESSKEY_ALT_DOWN    },
+               { VK_LMENU,    RP_PREPROCESSKEY_LALT_DOWN   },
+               { VK_RMENU,    RP_PREPROCESSKEY_RALT_DOWN   },
+               { VK_CONTROL,  RP_PREPROCESSKEY_CTRL_DOWN   },
+               { VK_LCONTROL, RP_PREPROCESSKEY_LCTRL_DOWN  },
+               { VK_RCONTROL, RP_PREPROCESSKEY_RCTRL_DOWN  },
+       };
+    static const int s_nVKeyFlagsCount = sizeof(s_VKeyFlags) / sizeof(s_VKeyFlags[0]);
+    BYTE btKeyboardState[256], btProcessedVirtualKey, btProcessedScanCode;
+       WPARAM wParam;
+       LPARAM lParam;
+       LRESULT lResult;
+    wchar_t wcChars[2];
+       int n;
+
+       if (!pInfo || !plResult)
+               return E_POINTER;
+
+       if (!pInfo->pfnToUnicode)
+               return S_FALLBACK_HANDLING;
+
+    if (dwFlags & (RPPKIF_EXTENDED0 | RPPKIF_EXTENDED1))
+    {
+        switch (btVirtualKey)
+        {
+            case VK_CONTROL: btVirtualKey = VK_RCONTROL; break;
+            case VK_MENU: btVirtualKey = VK_RMENU; break;
+        }
+    }
+    else
+    {
+        switch (btVirtualKey)
+        {
+            case VK_CONTROL: btVirtualKey = VK_LCONTROL; break;
+            case VK_MENU: btVirtualKey = VK_LMENU; break;
+            case VK_SHIFT: btVirtualKey = (MapVirtualKey(VK_RSHIFT, MAPVK_VK_TO_VSC) == btScanCode) ? VK_RSHIFT : VK_LSHIFT; break;
+        }
+    }
+
+       if (dwFlags & RPPKIF_MORE)
+       {
+               if (!RPSendMessage(RP_IPC_TO_HOST_PROCESSKEY, RP_PROCESSKEY_MORE, 0, NULL, 0, pInfo, plResult))
+                       return E_FAIL;
+               if (!(*plResult & RP_PROCESSKEY_OK))
+                       return S_FALLBACK_HANDLING;
+       }
+       else if (dwFlags & RPPKIF_KEYDOWN)
+       {
+               if (dwFlags & RPPKIF_DISABLEWIN)
+               {
+                       switch (btVirtualKey)
+                       {
+                               case VK_LWIN:
+                               case VK_RWIN: // disable Windows-key system functions (e.g. WinKey = Start Menu, WinKey+1/2/3 = activate first/second/third appbar program)
+                               {
+                                       keybd_event(VK_NOP, 255, 0, 0); // a do-nothing key must precede the "up" event, or the Start Menu pops up
+                                       keybd_event(VK_NOP, 255, KEYEVENTF_KEYUP, 0);
+                                       keybd_event(btVirtualKey, btScanCode, KEYEVENTF_KEYUP, 0);
+                                       GetKeyboardState(btKeyboardState);
+                                       btKeyboardState[btVirtualKey] = 0;
+                                       SetKeyboardState(btKeyboardState);
+                                       if (btVirtualKey == VK_LWIN)
+                                       {
+                                               g_nIgnoreLeftWinUp += 1; // ignore the up event just synthesized
+                                               if (g_bLeftWinDown)
+                                                       dwFlags |= RPPKIF_AUTOREPEAT; // flag as auto-repeated key event
+                                               else
+                                                       g_bLeftWinDown = TRUE;
+                                       }
+                                       else
+                                       {
+                                               g_nIgnoreRightWinUp += 1;
+                                               if (g_bRightWinDown)
+                                                       dwFlags |= RPPKIF_AUTOREPEAT;
+                                               else
+                                                       g_bRightWinDown = TRUE;
+                                       }
+                                       break;
+                               }
+                               case VK_NOP:
+                                       return S_IGNORE;
+                       }
+               }
+           if (dwFlags & RPPKIF_AUTOREPEAT) // ignore repeated keys (autorepeat handled on guest side)
+               return S_IGNORE_REPEATED;
+
+               wParam = RP_PREPROCESSKEY_SET_VKEY(btVirtualKey) |
+                        RP_PREPROCESSKEY_SET_SCANCODE(btScanCode);
+               if (dwFlags & RPPKIF_EXTENDED0)
+                       wParam |= RP_PREPROCESSKEY_EXTENDED0;
+               if (dwFlags & RPPKIF_EXTENDED1)
+                       wParam |= RP_PREPROCESSKEY_EXTENDED1;
+               if (dwFlags & RPPKIF_RAWINPUT)
+                       wParam |= RP_PREPROCESSKEY_RAWINPUT;
+               if (GetKeyState(VK_CAPITAL) & 0x01)
+                       wParam |= RP_PREPROCESSKEY_CAPS_TOGGLED;
+
+               for (n = 0; n < s_nVKeyFlagsCount; n++)
+               {
+                       if (GetKeyState(s_VKeyFlags[n].nVKey) & 0x80)
+                               wParam |= (WPARAM)s_VKeyFlags[n].dwFlags;
+               }
+               if (!RPSendMessage(RP_IPC_TO_HOST_PREPROCESSKEY, wParam, 0, NULL, 0, pInfo, &lResult)) // ask how we are supposed to handle this event
+                       return E_FAIL;
+               if (!(lResult & RP_PREPROCESSKEY_OK)) // host does not support RP_IPC_TO_HOST_PREPROCESSKEY (or other type of error - e.g. system not supported)
+                       return S_FALLBACK_HANDLING;
+
+               btProcessedVirtualKey = RP_PREPROCESSKEY_GET_VKEY(lResult);
+               btProcessedScanCode = RP_PREPROCESSKEY_GET_SCANCODE(lResult);
+               if (btProcessedVirtualKey == 0) // event consumed by host
+                       return S_IGNORE;
+
+               wParam = RP_PROCESSKEY_KEYDOWN;
+               lParam = 0;
+
+               if ((lResult & RP_PREPROCESSKEY_CHAR_KEY) &&
+                       btProcessedVirtualKey != 0)
+               {
+                       // just set qualifier state, so that multiple keypresses can be detected
+                       // (e.g. press 'B' while pressing 'A')
+                       memset(btKeyboardState, 0, sizeof(btKeyboardState));
+                       for (n = 0; n < s_nVKeyFlagsCount; n++)
+                       {
+                               if (lResult & s_VKeyFlags[n].dwFlags)
+                                       btKeyboardState[s_VKeyFlags[n].nVKey] |= 0x80;
+                       }
+                       if (lResult & RP_PREPROCESSKEY_CAPS_TOGGLED)
+                               btKeyboardState[VK_CAPITAL] |= 0x01;
+
+                       btKeyboardState[btProcessedVirtualKey] = 0x80;
+
+                       memset(wcChars, 0, sizeof(wcChars));
+                       n = pInfo->pfnToUnicode((UINT)btProcessedVirtualKey, btProcessedScanCode, btKeyboardState, wcChars, 2, 0);
+                       lParam = MAKELONG(wcChars[0], wcChars[1]);
+                       if (n < 0)
+                       {
+                               pInfo->pfnToUnicode((UINT)btProcessedVirtualKey, btProcessedScanCode, btKeyboardState, wcChars, 2, 0); // reset ToUnicode() internal flags
+                               n = 3;
+                       }
+                       else if (n > 2)
+                               n = 2;
+                       wParam |= RP_PROCESSKEY_SET_CHARCOUNT(n);
+               }
+               wParam |= RP_PROCESSKEY_SET_VKEY(btProcessedVirtualKey) |
+                         RP_PROCESSKEY_SET_SCANCODE(btProcessedScanCode);
+               if (lResult & RP_PREPROCESSKEY_EXTENDED0)
+                       wParam |= RP_PROCESSKEY_EXTENDED0;
+               if (lResult & RP_PREPROCESSKEY_EXTENDED1)
+                       wParam |= RP_PROCESSKEY_EXTENDED1;
+               if (lResult & RP_PREPROCESSKEY_RAWINPUT)
+                       wParam |= RP_PROCESSKEY_RAWINPUT;
+
+               if (!RPSendMessage(RP_IPC_TO_HOST_PROCESSKEY, wParam, lParam, NULL, 0, pInfo, plResult))
+                       return E_FAIL;
+               if (!(*plResult & RP_PROCESSKEY_OK)) // host does not support RP_IPC_TO_HOST_PROCESSKEY
+                       return S_FALLBACK_HANDLING;
+    }
+       else
+       {
+               switch (btVirtualKey)
+               {
+                       case VK_NOP:
+                               return S_IGNORE;
+                       case VK_LWIN:
+                               if (dwFlags & RPPKIF_DISABLEWIN)
+                               {
+                                       if (g_nIgnoreLeftWinUp)
+                                       {
+                                               g_nIgnoreLeftWinUp -= 1;
+                                               return S_IGNORE;
+                                       }
+                                       g_bLeftWinDown = FALSE;
+                               }
+                               break;
+                       case VK_RWIN:
+                               if (dwFlags & RPPKIF_DISABLEWIN)
+                               {
+                                       if (g_nIgnoreRightWinUp)
+                                       {
+                                               g_nIgnoreRightWinUp -= 1;
+                                               return S_IGNORE;
+                                       }
+                                       g_bRightWinDown = FALSE;
+                               }
+                               break;
+               }
+               wParam = RP_PROCESSKEY_SET_VKEY(btVirtualKey) |
+                        RP_PROCESSKEY_SET_SCANCODE(btScanCode);
+               if (dwFlags & RPPKIF_EXTENDED0)
+                       wParam |= RP_PROCESSKEY_EXTENDED0;
+               if (dwFlags & RPPKIF_EXTENDED1)
+                       wParam |= RP_PROCESSKEY_EXTENDED1;
+               if (dwFlags & RPPKIF_RAWINPUT)
+                       wParam |= RP_PROCESSKEY_RAWINPUT;
+
+               if (!RPSendMessage(RP_IPC_TO_HOST_PROCESSKEY, wParam, 0, NULL, 0, pInfo, plResult))
+                       return E_FAIL;
+               if (!(*plResult & RP_PROCESSKEY_OK)) // host does not support RP_IPC_TO_HOST_PROCESSKEY
+                       return S_FALLBACK_HANDLING;
+               if (*plResult == RP_PROCESSKEY_OK) // event consumed by host (e.g. Escape key) or no equivalent key in guest keyboard
+                       return S_IGNORE;
+       }
+       return NOERROR;
+}
index c064e125003abb0495776a4b25931e25f201a831..a1959a83c006fd7cf5f28d70372946c8a3834f61 100644 (file)
@@ -2,14 +2,14 @@
  Name    : RetroPlatformGuestIPC.h
  Project : RetroPlatform Player
  Support : http://www.retroplatform.com
- Legal   : Copyright 2007-2013 Cloanto Italia srl - All rights reserved. This
+ Legal   : Copyright 2007-2016 Cloanto Italia srl - All rights reserved. This
          : file is multi-licensed under the terms of the Mozilla Public License
          : version 2.0 as published by Mozilla Corporation and the GNU General
          : Public License, version 2 or later, as published by the Free
          : Software Foundation.
  Authors : os, mcb
  Created : 2007-08-24 15:29:26
- Updated : 2012-11-29 13:47:00
+ Updated : 2016-06-17 11:18:00
  Comment : RetroPlatform Player interprocess communication include file (guest side)
  *****************************************************************************/
 
@@ -20,6 +20,7 @@
 #include <tchar.h>
 
 typedef LRESULT (CALLBACK *RPGUESTMSGFN)(UINT uMessage, WPARAM wParam, LPARAM lParam, LPCVOID pData, DWORD dwDataSize, LPARAM lMsgFunctionParam);
+typedef int (WINAPI *TOUNICODEFN)(UINT wVirtKey, UINT wScanCode, const PBYTE lpKeyState, LPWSTR pwszBuff, int cchBuff, UINT wFlags);
 
 // the RPGuestInfo fields should be considered private,
 // since future implementations of RetroPlatform interprocess communication
@@ -36,6 +37,8 @@ typedef struct RPGuestInfo
        BOOL bGuestClassRegistered;
        RPGUESTMSGFN pfnMsgFunction;
        LPARAM lMsgFunctionParam;
+       HMODULE hUser32;
+       TOUNICODEFN pfnToUnicode;
 } RPGUESTINFO;
 
 #ifdef __cplusplus
@@ -49,6 +52,21 @@ HRESULT RPInitializeGuest(RPGUESTINFO *pInfo, HINSTANCE hInstance, LPCTSTR pszHo
 void RPUninitializeGuest(RPGUESTINFO *pInfo);
 BOOL RPSendMessage(UINT uMessage, WPARAM wParam, LPARAM lParam, LPCVOID pData, DWORD dwDataSize, const RPGUESTINFO *pInfo, LRESULT *plResult);
 BOOL RPPostMessage(UINT uMessage, WPARAM wParam, LPARAM lParam, const RPGUESTINFO *pInfo);
+HRESULT RPProcessKeyboardInput(DWORD dwFlags, BYTE btVirtualKey, BYTE btScanCode, const RPGUESTINFO *pInfo, LRESULT *plResult);
+
+// RPProcessKeyboardInput dwFlags
+#define RPPKIF_KEYDOWN         (1<<0) // bit set, if WM_KEYDOWN, or if (RAWKEYBOARD.Flags & RI_KEY_BREAK) == 0
+#define RPPKIF_AUTOREPEAT      (1<<1) // bit set, if lParam & (1<<30) in a WM_KEYDOWN/WM_KEYUP message
+#define RPPKIF_EXTENDED0       (1<<2) // bit set, if lParam & (1<<24) in a WM_KEYDOWN/WM_KEYUP message, or if RAWKEYBOARD.Flags & RI_KEY_E0
+#define RPPKIF_EXTENDED1       (1<<3) // bit set, if RAWKEYBOARD.Flags & RI_KEY_E1
+#define RPPKIF_DISABLEWIN      (1<<4) // bit set, if Windows keys need to be disabled (e.g. for WM_KEYDOWN/WM_KEYUP, or non-exclusive DirectInput client)
+#define RPPKIF_RAWINPUT                (1<<5) // bit set, if DirectInput/rawinput client
+#define RPPKIF_MORE                    (1<<6) // bit set, if additional guest key events must be retrieved for the same keyboard input
+
+// RPProcessKeyboardInput return codes
+#define S_FALLBACK_HANDLING    ((HRESULT)1L)
+#define S_IGNORE            ((HRESULT)2L)
+#define S_IGNORE_REPEATED   ((HRESULT)3L)
 
 #ifdef __cplusplus
 }   // ... extern "C"
index 3b3b8f1756c8466c473d98bb0bf26e5cb740351c..d862f352d466a0f708937c50bfd094513bc1d321 100644 (file)
@@ -2,14 +2,14 @@
  Name    : RetroPlatformIPC.h
  Project : RetroPlatform Player
  Support : http://www.retroplatform.com
- Legal   : Copyright 2007-2013 Cloanto Italia srl - All rights reserved. This
+ Legal   : Copyright 2007-2015 Cloanto Italia srl - All rights reserved. This
          : file is multi-licensed under the terms of the Mozilla Public License
          : version 2.0 as published by Mozilla Corporation and the GNU General
          : Public License, version 2 or later, as published by the Free
          : Software Foundation.
  Authors : os, mcb
  Created : 2007-08-27 13:55:49
- Updated : 2013-12-06 11:14:00
+ Updated : 2015-09-04 16:43:00
  Comment : RetroPlatform Player interprocess communication include file
  *****************************************************************************/
 
 
 #include <windows.h>
 
-#define RETROPLATFORM_API_VER       "3.4"
-#define RETROPLATFORM_API_VER_MAJOR  3
-#define RETROPLATFORM_API_VER_MINOR  4
+#define RETROPLATFORM_API_VER       "7.1"
+#define RETROPLATFORM_API_VER_MAJOR  7
+#define RETROPLATFORM_API_VER_MINOR  1
 
 #define RPIPC_HostWndClass   "RetroPlatformHost%s"
 #define RPIPC_GuestWndClass  "RetroPlatformGuest%d"
 
-// Legacy Compatibility (pre-3.0)
+// Legacy Compatibility
 #define RP_NO_LEGACY   // We don't need legacy #defines
 
 
@@ -58,6 +58,9 @@
 #define RP_IPC_TO_HOST_HOSTVERSION         (WM_APP + 25)
 #define RP_IPC_TO_HOST_INPUTDEVICE         (WM_APP + 26) // introduced in RetroPlatform API 3.0
 #define RP_IPC_TO_HOST_DEVICECONTENT       (WM_APP + 27) // extended in RetroPlatform API 3.0
+#define RP_IPC_TO_HOST_PREPROCESSKEY       (WM_APP + 28) // introduced in RetroPlatform API 7.1
+#define RP_IPC_TO_HOST_PROCESSKEY          (WM_APP + 29) // introduced in RetroPlatform API 7.1
+#define RP_IPC_TO_HOST_KEYBOARDLAYOUT      (WM_APP + 30) // introduced in RetroPlatform API 7.1
 
 
 // ****************************************************************************
 typedef struct RPScreenMode
 {
        DWORD dwScreenMode; // RP_SCREENMODE_* values and flags
-       LONG lClipLeft;     // in guest pixel units (Amiga: Super Hires or RTG); -1 = ignore (0 is a valid value); guest should also ignore this if RP_CLIPFLAGS_AUTOCLIP or RP_CLIPFLAGS_NOCLIP; see http://www.retroplatform.com/kb/19-115
-       LONG lClipTop;      // in guest pixel units (Amiga: interlaced or RTG); -1 = ignore (0 is a valid value); guest should also ignore this if RP_CLIPFLAGS_AUTOCLIP or RP_CLIPFLAGS_NOCLIP
-       LONG lClipWidth;    // in guest pixel units (Amiga: Super Hires or RTG); -1 = ignore; guest should also ignore this if RP_CLIPFLAGS_AUTOCLIP or RP_CLIPFLAGS_NOCLIP
-       LONG lClipHeight;   // in guest pixel units (Amiga: interlaced or RTG); -1 = ignore; guest should also ignore this if RP_CLIPFLAGS_AUTOCLIP or RP_CLIPFLAGS_NOCLIP
+       LONG lClipLeft;     // in guest pixel units (Amiga: Super Hires or RTG); -1 = ignore (0 is a valid value); guest should also ignore this when receiving data if RP_CLIPFLAGS_AUTOCLIP or RP_CLIPFLAGS_NOCLIP; see http://www.retroplatform.com/kb/19-115
+       LONG lClipTop;      // in guest pixel units (Amiga: interlaced or RTG); -1 = ignore (0 is a valid value); guest should also ignore this when receiving data if RP_CLIPFLAGS_AUTOCLIP or RP_CLIPFLAGS_NOCLIP
+       LONG lClipWidth;    // in guest pixel units (Amiga: Super Hires or RTG); -1 = ignore; guest should also ignore this when receiving data if RP_CLIPFLAGS_AUTOCLIP or RP_CLIPFLAGS_NOCLIP
+       LONG lClipHeight;   // in guest pixel units (Amiga: interlaced or RTG); -1 = ignore; guest should also ignore this when receiving data if RP_CLIPFLAGS_AUTOCLIP or RP_CLIPFLAGS_NOCLIP
        HWND hGuestWindow;  // only valid for RP_IPC_TO_HOST_SCREENMODE
        DWORD dwClipFlags;      // clip flags (or 0)
        LONG lTargetWidth;  // in exact host pixels; if set, must also set lTargetHeight; ignored unless RP_SCREENMODE_SCALE_TARGET is set (resulting size is result of clipping and scaling); RP_SCREENMODE_SCALING_SUBPIXEL and RP_SCREENMODE_SCALING_STRETCH are taken into account
@@ -327,7 +330,7 @@ typedef struct RPDeviceContent
 #define RP_HOSTINPUT_KEYJOY_MAP3    5 // [LEGACY] Keyboard Layout 3; Amiga/C64: Keyboard Layout C for WinUAE/VICE (W, S, A, D keys, left Alt to fire, etc.)
 #define RP_HOSTINPUT_ARCADE_LEFT    6 // [LEGACY] Left part of arcade dual joystick input device ("player 1")
 #define RP_HOSTINPUT_ARCADE_RIGHT   7 // [LEGACY] Right part of arcade dual joystick input device ("player 2")
-#define RP_HOSTINPUT_KEYBOARD       8 // Keyboard Layout (e.g. "KeyboardJoystick Left=0x4B Right=0x4D Up=0x48 Down=0x50 Fire=0x4C Autofire=0x38 Fire2=0x52 Rewind=0xB5 Play=0x37 FastForward=0x4A Green=0x47 Yellow=0x49 Red=0x4F Blue=0x51" set in szContent); introduced in RP API 3.3 to replace other keyboard layout modes
+#define RP_HOSTINPUT_KEYBOARD       8 // Keyboard Layout, using DirectInput keyboard scan codes (e.g. "KeyboardJoystick Left=0x4B Right=0x4D Up=0x48 Down=0x50 Fire=0x4C Autofire=0x38 Fire2=0x52 Rewind=0xB5 Play=0x37 FastForward=0x4A Green=0x47 Yellow=0x49 Red=0x4F Blue=0x51" set in szContent); introduced in RP API 3.3 to replace other keyboard layout modes
 #define RP_HOSTINPUT_END            9 // "End of device enumeration" (dummy device used to terminate an input device set that began with the first input device)
 #define RP_HOSTINPUT_COUNT         10 // total number of device types
 
@@ -391,7 +394,12 @@ typedef struct RPDeviceContent
 
 // RP_IPC_TO_HOST_MOUSECAPTURE/RP_IPC_TO_GUEST_MOUSECAPTURE
 #define RP_MOUSECAPTURE_CAPTURED     0x00000001
-#define RP_MOUSECAPTURE_MAGICMOUSE   0x00000002
+#define RP_MOUSECAPTURE_INTEGRATED   0x00000002 // aka "magic mouse"
+
+// RP_IPC_TO_GUEST_EVENT
+//
+// KEY_RAW_<x>: <x> is a hex keycode that uniquely identifies the raw key on the guest system
+//
 
 // RP_IPC_TO_HOST_DEVICEACTIVITY
 #define RP_DEVICEACTIVITY_GREEN    0x0000 // green led
@@ -483,9 +491,51 @@ typedef struct RPScreenCapture
 #define RP_HOSTVERSION_BUILD(ver)    ((ver) & 0x3FF)
 #define RP_MAKE_HOSTVERSION(major,minor,build) ((LPARAM) (((LPARAM)((major) & 0xFFF)<<20) | ((LPARAM)((minor) & 0x3FF)<<10) | ((LPARAM)((build) & 0x3FF))))
 
-
-// Legacy Compatibility (pre-3.0)
+// RP_IPC_TO_HOST_PREPROCESSKEY flags
+#define RP_PREPROCESSKEY_SET_VKEY(f)           ((f) & 0xFF)
+#define RP_PREPROCESSKEY_GET_VKEY(f)           ((f) & 0xFF)
+#define RP_PREPROCESSKEY_SET_SCANCODE(f)       (((f) & 0xFF) << 8)
+#define RP_PREPROCESSKEY_GET_SCANCODE(f)       (((f) >> 8) & 0xFF)
+#define RP_PREPROCESSKEY_EXTENDED0                     (1 << 16)
+#define RP_PREPROCESSKEY_EXTENDED1                     (1 << 17)
+#define RP_PREPROCESSKEY_RAWINPUT                      (1 << 18)
+#define RP_PREPROCESSKEY_CAPS_DOWN                     (1 << 19)
+#define RP_PREPROCESSKEY_CAPS_TOGGLED          (1 << 20)
+#define RP_PREPROCESSKEY_SHIFT_DOWN                    (1 << 21)
+#define RP_PREPROCESSKEY_LSHIFT_DOWN           (1 << 22)
+#define RP_PREPROCESSKEY_RSHIFT_DOWN           (1 << 23)
+#define RP_PREPROCESSKEY_ALT_DOWN                      (1 << 24)
+#define RP_PREPROCESSKEY_LALT_DOWN                     (1 << 25)
+#define RP_PREPROCESSKEY_RALT_DOWN                     (1 << 26)
+#define RP_PREPROCESSKEY_CTRL_DOWN                     (1 << 27)
+#define RP_PREPROCESSKEY_LCTRL_DOWN                    (1 << 28)
+#define RP_PREPROCESSKEY_RCTRL_DOWN                    (1 << 29)
+#define RP_PREPROCESSKEY_CHAR_KEY                      (1 << 30)
+#define RP_PREPROCESSKEY_OK                                    (1 << 31) // out flag
+
+// RP_IPC_TO_HOST_PROCESSKEY flags
+#define RP_PROCESSKEY_SET_VKEY(f)              ((f) & 0xFF)
+#define RP_PROCESSKEY_GET_VKEY(f)              ((f) & 0xFF)
+#define RP_PROCESSKEY_SET_SCANCODE(f)  (((f) & 0xFF) << 8)
+#define RP_PROCESSKEY_GET_SCANCODE(f)  (((f) >> 8) & 0xFF)
+#define RP_PROCESSKEY_EXTENDED0                        (1 << 16)
+#define RP_PROCESSKEY_EXTENDED1                        (1 << 17)
+#define        RP_PROCESSKEY_RAWINPUT                  (1 << 18)
+#define RP_PROCESSKEY_SET_CHARCOUNT(f) (((f) & 0x03) << 19)
+#define RP_PROCESSKEY_GET_CHARCOUNT(f) (((f) >> 19) & 0x03)
+#define RP_PROCESSKEY_KEYDOWN                  (1 << 21)
+#define RP_PROCESSKEY_KEYMASK                  0xFFFFFF  // returned key code mask
+#define RP_PROCESSKEY_MORE                             (1 << 28) // in/out flag
+#define RP_PROCESSKEY_PRESSKEY                 (1 << 29) // out flag
+#define RP_PROCESSKEY_RELEASEKEY               (1 << 30) // out flag
+#define RP_PROCESSKEY_OK                               (1 << 31) // out flag
+
+
+// Legacy Compatibility
 #ifndef RP_NO_LEGACY
+// Changed in 7.0
+#define RP_MOUSECAPTURE_MAGICMOUSE RP_MOUSECAPTURE_INTEGRATED
+// Changed in 3.0
 #define RP_IPC_TO_HOST_DEVICECONTENT_LEGACY   (WM_APP + 16)
 #define RP_IPC_TO_GUEST_DEVICECONTENT_LEGACY   (WM_APP + 205)
 #define RPLATFORM_API_VER RETROPLATFORM_API_VER
index 424a5d8c304c39913749d4a318edd2304a402a0a..cc8da81d287a8299fbb73b97f78bdf0c726fc555 100644 (file)
@@ -4,12 +4,12 @@
  Client  : Cloanto Italia srl
  Support : http://www.retroplatform.com
  Legal   : CONFIDENTIAL TRADE SECRET PROPERTY OF CLOANTO ITALIA SRL
-         : Copyright Â© Cloanto Italia srl 2007-2013.
+         : Copyright Â© Cloanto Italia srl 2007-2016.
          : All rights reserved, except where licensed,
          : assigned or transferred by contract.
  Authors : os, mcb
  Created : 2007-08-23 10:08:25
- Updated : 2013-03-16 07:20:00
+ Updated : 2016-06-17 15:07:10
  Comment : Reference for RetroPlatformIPC.h (RP Player interprocess communication include file)
  *****************************************************************************/
 
@@ -452,7 +452,39 @@ Data sent:
    none
 Response:
    none
+   
+   
+Message:
+   RP_IPC_TO_HOST_PREPROCESSKEY
+Description:
+   message sent by the keyboard handling functions;
+   guests are not supposed to send it directly
+Data sent:
+   -
+Response:
+   -
+
+
+Message:
+   RP_IPC_TO_HOST_PROCESSKEY
+Description:
+   message sent by the keyboard handling functions;
+   guests are not supposed to send it directly
+Data sent:
+   -
+Response:
+   -
+
 
+Message:
+   RP_IPC_TO_HOST_KEYBOARDLAYOUT
+Description:
+   the guest sends this message to notify the host
+   about a change of the guest keyboard layout
+Data sent:
+   pData = keyboard layout name (null-terminated Unicode string)
+Response:
+   none
 
 
 
@@ -630,8 +662,19 @@ Description:
    to simulate keyboard, mouse, joystick, tape button press/release
    and other guest-specific events
 Data sent:
-   pData = (Unicode) event string (guest-specific); for keyboard events ("KEY_"... string)
-   the event string is followed by a space and a "1"/"0" character (pressed/released).
+   pData = (Unicode) event string (guest-specific).
+   Keyboard events are "KEY_RAW_DOWN <x>" and "KEY_RAW_UP <x>" strings, where <x>
+   is a keycode that uniquely identifies the raw key on the guest system,
+   independently of higher-level layout (e.g. Amiga SetMap). On the Amiga, <x> would
+   be one byte. By default, <x> is decimal. Prefix hexadecimal values with "0x".
+   It is up to the host to do the appopriate mappings and request the correct raw guest
+   event, taking into account host and guest layouts.
+   Other events may be named as per cloanto.com/specs/ianames.
+LEGACY:
+>>>
+   For keyboard events other than KEY_RAW_DOWN and KEY_RAW_UP, the string is followed
+   by a space and a "1"/"0" character (down/up).
+<<<
 Response:
    LRESULT = 1 if the guest successfully simulated the specified event or 0 otherwise
 
index f71ae55c1b706d85209382280d1c49e1f17e9d00..dd4b86702f81caa57bf5eca46e94e76759453114 100644 (file)
@@ -23,6 +23,8 @@ int no_windowsmouse = 0;
 #define DI_DEBUG 1
 #define IGNOREEVERYTHING 0
 
+#define NEGATIVEMINHACK 0
+
 #include "sysconfig.h"
 
 #include <stdlib.h>
@@ -362,7 +364,7 @@ static void addplusminus (struct didata *did, int i)
        TCHAR tmp[256];
        int j;
 
-       if (did->buttons + 1 >= MAX_MAPPINGS)
+       if (did->buttons + 1 >= ID_BUTTON_TOTAL)
                return;
        for (j = 0; j < 2; j++) {
                _stprintf (tmp, _T("%s [%c]"), did->axisname[i], j ? '+' : '-');
@@ -505,7 +507,7 @@ static int doregister_rawinput (bool add)
 #endif
 
 #if RAWINPUT_DEBUG
-       write_log (_T("RegisterRawInputDevices: ACT=%d NUM=%d HWND=%p\n"), activate, num, hMainWnd);
+       write_log (_T("RegisterRawInputDevices: NUM=%d HWND=%p\n"), num, hMainWnd);
 #endif
 
        rawinput_reg = num;
@@ -1353,19 +1355,11 @@ static void fixhidvcaps (RID_DEVICE_INFO_HID *hid, HIDP_VALUE_CAPS *caps)
 {
        int pid = hid->dwProductId;
        int vid = hid->dwVendorId;
-       ULONG mask = hidmask (caps->BitSize);
-       /* min is always signed.
-        * if min < 0, max is signed, otherwise it is unsigned
-        */
-       if (caps->PhysicalMin >= 0)
-               caps->PhysicalMax = (uae_u32)(caps->PhysicalMax & mask);
-       else
-               caps->PhysicalMax = (uae_s32)caps->PhysicalMax;
 
-       if (caps->LogicalMin >= 0)
-               caps->LogicalMax = (uae_u32)(caps->LogicalMax & mask);
-       else
-               caps->LogicalMax = (uae_s32)caps->LogicalMax;
+       caps->LogicalMin = extractbits(caps->LogicalMin, caps->BitSize, caps->LogicalMin < 0);
+       caps->LogicalMax = extractbits(caps->LogicalMax, caps->BitSize, caps->LogicalMin < 0);
+       caps->PhysicalMin = extractbits(caps->PhysicalMin, caps->BitSize, caps->PhysicalMin < 0);
+       caps->PhysicalMax = extractbits(caps->PhysicalMax, caps->BitSize, caps->PhysicalMin < 0);
 
        for (int i = 0; quirks[i].vid; i++) {
                if (vid == quirks[i].vid && pid == quirks[i].pid) {
@@ -1767,7 +1761,7 @@ static bool initialize_rawinput (void)
                                PRID_DEVICE_INFO_MOUSE rdim = &rdi->mouse;
                                write_log (_T("id=%d buttons=%d hw=%d rate=%d\n"),
                                        rdim->dwId, rdim->dwNumberOfButtons, rdim->fHasHorizontalWheel, rdim->dwSampleRate);
-                               if (rdim->dwNumberOfButtons >= MAX_MAPPINGS) {
+                               if (rdim->dwNumberOfButtons >= ID_BUTTON_TOTAL) {
                                        write_log (_T("bogus number of buttons, ignored\n"));
                                } else {
                                        did->buttons_real = did->buttons = rdim->dwNumberOfButtons;
@@ -1822,7 +1816,8 @@ static bool initialize_rawinput (void)
                                                if (HidP_GetButtonCaps (HidP_Input, bcaps, &size, did->hidpreparseddata) == HIDP_STATUS_SUCCESS) {
                                                        dumphidbuttoncaps (bcaps, size);
                                                        int buttoncnt = 0;
-                                                       for (i = 0; i < size && buttoncnt < MAX_MAPPINGS; i++) {
+                                                       // limit to 20, can only have 32 buttons and it also includes [-][+] axis events.
+                                                       for (i = 0; i < size && buttoncnt < 20; i++) {
                                                                int first, last;
                                                                if (bcaps[i].UsagePage >= 0xff00)
                                                                        continue;
@@ -1832,7 +1827,7 @@ static bool initialize_rawinput (void)
                                                                } else {
                                                                        first = last = bcaps[i].NotRange.Usage;
                                                                }
-                                                               for (j = first; j <= last && buttoncnt < MAX_MAPPINGS; j++) {
+                                                               for (j = first; j <= last && buttoncnt < 20; j++) {
                                                                        int k;
                                                                        for (k = 0; k < buttoncnt; k++) {
                                                                                if (did->buttonmappings[k] == j)
@@ -1857,9 +1852,31 @@ static bool initialize_rawinput (void)
                                                size = did->hidcaps.NumberInputValueCaps;
                                                vcaps = xmalloc (HIDP_VALUE_CAPS, size);
                                                if (HidP_GetValueCaps (HidP_Input, vcaps, &size, did->hidpreparseddata) == HIDP_STATUS_SUCCESS) {
+#if 0
+                                                       for (i = 0; i < size; i++) {
+                                                               int usage1;
+                                                               if (vcaps[i].IsRange)
+                                                                       usage1 = vcaps[i].Range.UsageMin;
+                                                               else
+                                                                       usage1 = vcaps[i].NotRange.Usage;
+                                                               for (j = i + 1; j < size; j++) {
+                                                                       int usage2;
+                                                                       if (vcaps[j].IsRange)
+                                                                               usage2 = vcaps[j].Range.UsageMin;
+                                                                       else
+                                                                               usage2 = vcaps[j].NotRange.Usage;
+                                                                       if (usage1 < usage2) {
+                                                                               HIDP_VALUE_CAPS tcaps;
+                                                                               memcpy(&tcaps, &vcaps[i], sizeof(HIDP_VALUE_CAPS));
+                                                                               memcpy(&vcaps[i], &vcaps[j], sizeof(HIDP_VALUE_CAPS));
+                                                                               memcpy(&vcaps[j], &tcaps, sizeof(HIDP_VALUE_CAPS));
+                                                                       }
+                                                               }
+                                                       }
+#endif
                                                        dumphidvaluecaps (vcaps, size);
                                                        int axiscnt = 0;
-                                                       for (i = 0; i < size && axiscnt < MAX_MAPPINGS; i++) {
+                                                       for (i = 0; i < size && axiscnt < ID_AXIS_TOTAL; i++) {
                                                                int first, last;
                                                                if (vcaps[i].IsRange) {
                                                                        first = vcaps[i].Range.UsageMin;
@@ -1867,7 +1884,7 @@ static bool initialize_rawinput (void)
                                                                } else {
                                                                        first = last = vcaps[i].NotRange.Usage;
                                                                }
-                                                               for (int acnt = first; acnt <= last && axiscnt < MAX_MAPPINGS; acnt++) {
+                                                               for (int acnt = first; acnt <= last && axiscnt < ID_AXIS_TOTAL; acnt++) {
                                                                        int ht;
                                                                        for (ht = 0; hidtable[ht].name; ht++) {
                                                                                if (hidtable[ht].usage == acnt && hidtable[ht].page == vcaps[i].UsagePage) {
@@ -1878,7 +1895,7 @@ static bool initialize_rawinput (void)
                                                                                        }
                                                                                        if (k == axiscnt) {     
                                                                                                if (hidtable[ht].page == 0x01 && acnt == 0x39) { // POV
-                                                                                                       if (axiscnt + 1 < MAX_MAPPINGS) {
+                                                                                                       if (axiscnt + 1 < ID_AXIS_TOTAL) {
                                                                                                                for (int l = 0; l < 2; l++) {
                                                                                                                        TCHAR tmp[256];
                                                                                                                        _stprintf (tmp, _T("%s (%c)"), hidtable[ht].name,  l == 0 ? 'X' : 'Y');
@@ -1896,6 +1913,10 @@ static bool initialize_rawinput (void)
                                                                                                        did->axismappings[axiscnt] = acnt;
                                                                                                        memcpy (&did->hidvcaps[axiscnt], &vcaps[i], sizeof(HIDP_VALUE_CAPS));
                                                                                                        fixhidvcaps (&rdi->hid, &did->hidvcaps[axiscnt]);
+#if NEGATIVEMINHACK
+                                                                                                       did->hidvcaps[axiscnt].LogicalMin -= (did->hidvcaps[axiscnt].LogicalMax / 2);
+                                                                                                       did->hidvcaps[axiscnt].LogicalMax -= (did->hidvcaps[axiscnt].LogicalMax / 2);
+#endif
                                                                                                        did->axistype[axiscnt] = hidtable[ht].type;
                                                                                                        axiscnt++;
                                                                                                        did->analogstick = true;
@@ -2130,11 +2151,21 @@ static void handle_rawinput_2 (RAWINPUT *raw)
                HANDLE h = raw->header.hDevice;
                PCHAR rawdata;
                if ((rawinput_log & 4) || RAWINPUT_DEBUG) {
+                       static uae_u8 *oldbuf;
+                       static int oldbufsize;
+                       if (oldbufsize != hid->dwSizeHid) {
+                               xfree(oldbuf);
+                               oldbufsize = hid->dwSizeHid;
+                               oldbuf = xcalloc(uae_u8, oldbufsize);
+                       }
                        uae_u8 *r = hid->bRawData;
-                       write_log (_T("%d %d "), hid->dwCount, hid->dwSizeHid);
-                       for (int i = 0; i < hid->dwSizeHid; i++)
-                               write_log (_T("%02X"), r[i]);
-                       write_log (_T(" H=%p\n"), h);
+                       if (memcmp(r, oldbuf, oldbufsize)) {
+                               write_log (_T("%d %d "), hid->dwCount, hid->dwSizeHid);
+                               for (int i = 0; i < hid->dwSizeHid; i++)
+                                       write_log (_T("%02X"), r[i]);
+                               write_log (_T(" H=%p\n"), h);
+                               memcpy(oldbuf, r, oldbufsize);
+                       }
                }
                for (num = 0; num < num_joystick; num++) {
                        did = &di_joystick[num];
@@ -2208,7 +2239,6 @@ static void handle_rawinput_2 (RAWINPUT *raw)
                                                
                                                status = HidP_GetUsageValue (HidP_Input, did->hidvcaps[axisnum].UsagePage, 0, usage, &val, did->hidpreparseddata, rawdata, hid->dwSizeHid);
                                                if (status == HIDP_STATUS_SUCCESS) {
-
                                                        int data = 0;
                                                        int digitalrange = 0;
                                                        HIDP_VALUE_CAPS *vcaps = &did->hidvcaps[axisnum];
@@ -2246,19 +2276,23 @@ static void handle_rawinput_2 (RAWINPUT *raw)
                                                        } else {
 
                                                                int v;
-
-                                                               v = extractbits (val, vcaps->BitSize, vcaps->LogicalMin < 0);
-                                               
-                                                               //write_log (L"%d %d: %d\n", num, axisnum, v);
+                               
+#if NEGATIVEMINHACK
+                                                               v = extractbits(val, vcaps->BitSize, 0);
+                                                               v -= (vcaps->LogicalMax - vcaps->LogicalMin) / 2;
+#else
+                                                               v = extractbits(val, vcaps->BitSize, vcaps->LogicalMin < 0);
+#endif
 
                                                                if (v < vcaps->LogicalMin)
                                                                        v = vcaps->LogicalMin;
                                                                else if (v > vcaps->LogicalMax)
                                                                        v = vcaps->LogicalMax;
 
-                                                               v -= logicalrange + vcaps->LogicalMin;
+                                                               data = v - logicalrange + (0 - vcaps->LogicalMin);
 
-                                                               data = v;
+                                                               if (rawinput_log & 4)
+                                                                       write_log(_T("DEV %d AXIS %d: %d %d (%d - %d) %d %d\n"), num, axisnum, digitalrange, logicalrange, vcaps->LogicalMin, vcaps->LogicalMax, v, data);
 
                                                                digitalrange = logicalrange * 2 / 3;
                                                                if (istest) {
@@ -2268,7 +2302,6 @@ static void handle_rawinput_2 (RAWINPUT *raw)
                                                                                data = logicalrange;
                                                                        else
                                                                                data = 0;
-                                                                       //write_log (_T("%d %d: (%d-%d) %d %d\n"), num, axisnum, vcaps->LogicalMin, vcaps->LogicalMax, v, data);
                                                                }
                                                                buttonaxistype = -1;
                                                        }
@@ -2276,10 +2309,11 @@ static void handle_rawinput_2 (RAWINPUT *raw)
                                                        if (data != axisold[num][axisnum] && logicalrange) {
                                                                //write_log (_T("%d %d: %d->%d %d\n"), num, axisnum, axisold[num][axisnum], data, logicalrange);
                                                                axisold[num][axisnum] = data;
-                                                               int bstate = -1;
-                                                               int bstate2 = 0;
                                                                for (j = 0; j < did->buttons; j++) {
                                                                        if (did->buttonaxisparent[j] >= 0 && did->buttonmappings[j] == usage && (did->buttonaxistype[j] == buttonaxistype || buttonaxistype < 0)) {
+                                                                               int bstate = -1;
+                                                                               int bstate2 = 0;
+
                                                                                int axistype = did->axistype[j];
                                                                                if (did->buttonaxisparentdir[j] == 0 && data < -digitalrange) {
                                                                                        bstate = j;
@@ -2293,7 +2327,8 @@ static void handle_rawinput_2 (RAWINPUT *raw)
                                                                                }
 
                                                                                if (bstate >= 0 && buttonold[num][bstate] != bstate2) {
-                                                                                       //write_log (_T("%d %d %d (%s)\n"), num, bstate, bstate2, did->buttonname[bstate]);
+                                                                                       if (rawinput_log & 4)
+                                                                                               write_log (_T("[+-] DEV %d AXIS %d: %d %d %d %d (%s)\n"), num, axisnum, digitalrange, data, bstate, bstate2, did->buttonname[bstate]);
                                                                                        buttonold[num][bstate] = bstate2;
                                                                                        setjoybuttonstate (num, bstate, bstate2);
                                                                                }
@@ -2738,7 +2773,7 @@ static BOOL CALLBACK EnumObjectsCallback (const DIDEVICEOBJECTINSTANCE* pdidoi,
 #endif
        if (pdidoi->dwType & DIDFT_AXIS) {
                int sort = 0;
-               if (did->axles >= MAX_MAPPINGS)
+               if (did->axles >= ID_AXIS_TOTAL)
                        return DIENUM_CONTINUE;
                did->axismappings[did->axles] = DIDFT_GETINSTANCE (pdidoi->dwType);
                did->axisname[did->axles] = my_strdup (pdidoi->tszName);
@@ -2761,7 +2796,7 @@ static BOOL CALLBACK EnumObjectsCallback (const DIDEVICEOBJECTINSTANCE* pdidoi,
        }
        if (pdidoi->dwType & DIDFT_POV) {
                int numpov = 0;
-               if (did->axles + 1 >= MAX_MAPPINGS)
+               if (did->axles + 1 >= ID_AXIS_TOTAL)
                        return DIENUM_CONTINUE;
                for (i = 0; i < did->axles; i++) {
                        if (did->axistype[i]) {
@@ -2784,7 +2819,7 @@ static BOOL CALLBACK EnumObjectsCallback (const DIDEVICEOBJECTINSTANCE* pdidoi,
        }
 
        if (pdidoi->dwType & DIDFT_BUTTON) {
-               if (did->buttons >= MAX_MAPPINGS)
+               if (did->buttons >= ID_BUTTON_TOTAL)
                        return DIENUM_CONTINUE;
                TCHAR *bname = did->buttonname[did->buttons] = my_strdup (pdidoi->tszName);
                if (did->type == DID_JOYSTICK) {
index 0d6d8ff6bb1089aadb760ac85599fde1f2abec57..f982b4bb50a7a042ac0ebffdab367dc86aa8d6dd 100644 (file)
@@ -2409,7 +2409,7 @@ static const TCHAR *D3D_init2 (HWND ahwnd, int w_w, int w_h, int depth, int *fre
                                getvsyncrate(mode.RefreshRate, &hzmult);
                                if (hzmult < 0) {
                                        if (!ap.gfx_strobo) {
-                                               if (d3dCaps.PresentationIntervals & D3DPRESENT_INTERVAL_TWO)
+                                               if ((d3dCaps.PresentationIntervals & D3DPRESENT_INTERVAL_TWO) && isfullscreen() > 0)
                                                        dpp.PresentationInterval = D3DPRESENT_INTERVAL_TWO;
                                        } else {
                                                vsync2 = -2;
@@ -2431,7 +2431,7 @@ static const TCHAR *D3D_init2 (HWND ahwnd, int w_w, int w_h, int depth, int *fre
                        if (ap.gfx_strobo) {
                                vsync2 = -2;
                        } else if (ap.gfx_vflip) {
-                               if (d3dCaps.PresentationIntervals & D3DPRESENT_INTERVAL_TWO)
+                               if ((d3dCaps.PresentationIntervals & D3DPRESENT_INTERVAL_TWO) && isfullscreen() > 0)
                                        dpp.PresentationInterval = D3DPRESENT_INTERVAL_TWO;
                                else
                                        vsync2 = -1;
index 0766261a9db2b63dc0b223788a5481d4d51f2117..9c78c749e32306cecd2757925915b83165998851 100644 (file)
@@ -1033,3 +1033,4 @@ const TCHAR *my_getfilepart(const TCHAR *filename)
                return p + 1;
        return filename;
 }
+
index 8cf5720f9fed95a3f8365dc6b3a9e0de63fe48fa..a43ba450ac5e1d24e567aa5d3d45d570c446724a 100644 (file)
@@ -1984,7 +1984,7 @@ int win32_hardfile_media_change (const TCHAR *drvname, int inserted)
                extern struct hd_hardfiledata *pcmcia_sram;
                int reopen = 0;
                struct uaedev_config_data *uci = &currprefs.mountconfig[i];
-               if (uci->ci.controller_type == HD_CONTROLLER_TYPE_PCMCIA_SRAM) {
+               if (uci->ci.controller_type == HD_CONTROLLER_TYPE_PCMCIA && uci->ci.controller_type_unit == 0) {
                        hmc_check (&pcmcia_sram->hfd, uci, &rescanned, &reopen, &gotinsert, drvname, inserted);
                }
        }
index b1cfe0fc985b268528d4fcf74933b5c70221c50d..0b4c405bf21c6d5feda42cfe55dde870d01931db 100644 (file)
@@ -163,7 +163,8 @@ static struct uae_input_device_kbr_default keytrans_amiga[] = {
        { DIK_SYSRQ, INPUTEVENT_SPC_SCREENSHOT_CLIPBOARD, 0, INPUTEVENT_SPC_SCREENSHOT, ID_FLAG_QUALIFIER_SPECIAL },
 
        { DIK_END, INPUTEVENT_SPC_QUALIFIER_SPECIAL },
-       { DIK_PAUSE, INPUTEVENT_SPC_PAUSE, 0, INPUTEVENT_SPC_WARP, ID_FLAG_QUALIFIER_SPECIAL, INPUTEVENT_SPC_IRQ7, ID_FLAG_QUALIFIER_SPECIAL | ID_FLAG_QUALIFIER_SHIFT },
+       { DIK_PAUSE, INPUTEVENT_SPC_PAUSE, 0, INPUTEVENT_SPC_SINGLESTEP, ID_FLAG_QUALIFIER_SPECIAL | ID_FLAG_QUALIFIER_CONTROL, INPUTEVENT_SPC_IRQ7, ID_FLAG_QUALIFIER_SPECIAL | ID_FLAG_QUALIFIER_SHIFT, INPUTEVENT_SPC_WARP, ID_FLAG_QUALIFIER_SPECIAL },
+       { DIK_PAUSE+1, INPUTEVENT_SPC_SINGLESTEP, ID_FLAG_QUALIFIER_SPECIAL | ID_FLAG_QUALIFIER_CONTROL, INPUTEVENT_SPC_IRQ7, ID_FLAG_QUALIFIER_SPECIAL | ID_FLAG_QUALIFIER_SHIFT },
 
        { DIK_F12, INPUTEVENT_SPC_ENTERGUI, 0, INPUTEVENT_SPC_ENTERDEBUGGER, ID_FLAG_QUALIFIER_SPECIAL, INPUTEVENT_SPC_ENTERDEBUGGER, ID_FLAG_QUALIFIER_SHIFT, INPUTEVENT_SPC_TOGGLEDEFAULTSCREEN, ID_FLAG_QUALIFIER_CONTROL },
 
index 3c5a8e2a2b672a13ce13521c392f22146ab431ce..0cc084018593a6f7d242f6e1db8c28010631a72d 100644 (file)
@@ -6,10 +6,10 @@
 
 #include "sysconfig.h"
 #include "sysdeps.h"
+#include "options.h"
 #include "memory.h"
 #include "uae/mman.h"
 #include "uae/vm.h"
-#include "options.h"
 #include "autoconf.h"
 #include "gfxboard.h"
 #include "cpuboard.h"
@@ -57,6 +57,7 @@ static void virtualfreewithlock (LPVOID addr, SIZE_T size, DWORD freetype)
 static uae_u32 lowmem (void)
 {
        uae_u32 change = 0;
+#if 0
        struct rtgboardconfig *rbc = &changed_prefs.rtgboards[0];
        struct rtgboardconfig *crbc = &currprefs.rtgboards[0];
 
@@ -85,6 +86,7 @@ static uae_u32 lowmem (void)
        }
        if (currprefs.z3fastmem2_size < 128 * 1024 * 1024)
                currprefs.z3fastmem2_size = changed_prefs.z3fastmem2_size = 0;
+#endif
        return change;
 }
 
@@ -130,6 +132,7 @@ bool preinit_shm (void)
 #endif
        natmem_reserved = NULL;
        natmem_offset = NULL;
+#if 0
        if (p96mem_offset) {
 #ifdef _WIN32
                VirtualFree (p96mem_offset, 0, MEM_RELEASE);
@@ -137,7 +140,7 @@ bool preinit_shm (void)
 #endif
        }
        p96mem_offset = NULL;
-
+#endif
        GetSystemInfo (&si);
        max_allowed_mman = 512 + 256;
 #if 1
@@ -206,8 +209,7 @@ bool preinit_shm (void)
        write_log(_T("NATMEM: Attempting to reserve: %u MB\n"), natmem_size >> 20);
 
 #if 1
-       natmem_reserved = (uae_u8 *) uae_vm_reserve(
-               natmem_size, UAE_VM_32BIT | UAE_VM_WRITE_WATCH);
+       natmem_reserved = (uae_u8 *) uae_vm_reserve(natmem_size, UAE_VM_32BIT | UAE_VM_WRITE_WATCH);
 #else
        natmem_size = 0x20000000;
        natmem_reserved = (uae_u8 *) uae_vm_reserve_fixed(
@@ -239,7 +241,7 @@ bool preinit_shm (void)
                        natmem_reserved = (uae_u8*)VirtualAlloc (NULL, natmem_size, vaflags, PAGE_READWRITE);
                        if (natmem_reserved)
                                break;
-                       natmem_size -= 128 * 1024 * 1024;
+                       natmem_size -= 64 * 1024 * 1024;
                        if (!natmem_size) {
                                write_log (_T("Can't allocate 257M of virtual address space!?\n"));
                                natmem_size = 17 * 1024 * 1024;
@@ -304,19 +306,6 @@ static void resetmem (bool decommit)
        }
 }
 
-static ULONG getz2rtgaddr(struct rtgboardconfig *rbc)
-{
-       ULONG start;
-       start = changed_prefs.fastmem_size;
-       if (changed_prefs.fastmem2_size >= 524288)
-               start += changed_prefs.fastmem2_size;
-       start += rbc->rtgmem_size - 1;
-       start &= ~(rbc->rtgmem_size - 1);
-       while (start & (rbc->rtgmem_size - 1) && start < 4 * 1024 * 1024)
-               start += 1024 * 1024;
-       return start + 2 * 1024 * 1024;
-}
-
 static uae_u8 *va (uae_u32 offset, uae_u32 len, DWORD alloc, DWORD protect)
 {
        uae_u8 *addr;
@@ -334,59 +323,62 @@ static uae_u8 *va (uae_u32 offset, uae_u32 len, DWORD alloc, DWORD protect)
 
 static int doinit_shm (void)
 {
-       uae_u32 size, totalsize, z3size, natmemsize, othersize;
-       uae_u32 startbarrier, z3offset, align;
-       int rounds = 0;
+       uae_u32 totalsize;
+       uae_u32 startbarrier, align;
        uae_u32 z3rtgmem_size;
        struct rtgboardconfig *rbc = &changed_prefs.rtgboards[0];
        struct rtgboardconfig *crbc = &currprefs.rtgboards[0];
 
+       changed_prefs.z3autoconfig_start = currprefs.z3autoconfig_start = 0;
+       set_expamem_z3_hack_mode(0);
+       expansion_scan_autoconfig(&currprefs, true);
+
        canbang = 1;
        natmem_offset = natmem_reserved;
-       for (;;) {
-               int lowround = 0;
-               if (rounds > 0)
-                       write_log (_T("NATMEM: retrying %d..\n"), rounds);
-               rounds++;
-
-               align = 16 * 1024 * 1024 - 1;
-               z3size = 0;
-               othersize = 0;
-               size = 0x1000000;
-               startbarrier = changed_prefs.mbresmem_high_size >= 128 * 1024 * 1024 ? (changed_prefs.mbresmem_high_size - 128 * 1024 * 1024) + 16 * 1024 * 1024 : 0;
-               z3rtgmem_size = gfxboard_get_configtype(rbc) == 3 ? rbc->rtgmem_size : 0;
-               if (changed_prefs.cpu_model >= 68020)
-                       size = 0x10000000;
-               z3size = ((changed_prefs.z3fastmem_size + align) & ~align) + ((changed_prefs.z3fastmem2_size + align) & ~align) + ((changed_prefs.z3chipmem_size + align) & ~align);
-               if (cfgfile_board_enabled(&currprefs, ROMTYPE_A4091, 0))
-                       othersize += 2 * 16 * 1024 * 1024;
-               if (cfgfile_board_enabled(&currprefs, ROMTYPE_FASTLANE, 0))
-                       othersize += 2 * 32 * 1024 * 1024;
-               totalsize = size + z3size + z3rtgmem_size + othersize;
-               while (totalsize > size64) {
-                       int change = lowmem ();
-                       if (!change)
-                               return 0;
-                       write_log (_T("NATMEM: %d, %dM > %lldM = %dM\n"), ++lowround, totalsize >> 20, size64 >> 20, (totalsize - change) >> 20);
-                       totalsize -= change;
+
+       align = 16 * 1024 * 1024 - 1;
+       totalsize = 0x01000000;
+       startbarrier = changed_prefs.mbresmem_high_size >= 128 * 1024 * 1024 ? (changed_prefs.mbresmem_high_size - 128 * 1024 * 1024) + 16 * 1024 * 1024 : 0;
+
+       z3rtgmem_size = gfxboard_get_configtype(rbc) == 3 ? rbc->rtgmem_size : 0;
+
+       if (changed_prefs.cpu_model >= 68020)
+               totalsize = 0x10000000;
+       totalsize += (changed_prefs.z3chipmem_size + align) & ~align;
+
+       if (changed_prefs.z3_mapping_mode == Z3MAPPING_UAE || cpuboard_memorytype(&changed_prefs) == BOARD_MEMORY_BLIZZARD_12xx ||
+               (expamem_z3_pointer_real + 16 * si.dwPageSize >= natmem_reserved_size && changed_prefs.z3_mapping_mode == Z3MAPPING_AUTO)) {
+               changed_prefs.z3autoconfig_start = currprefs.z3autoconfig_start = Z3BASE_UAE;
+               if (changed_prefs.z3_mapping_mode == Z3MAPPING_AUTO)
+                       write_log(_T("MMAN: Selected UAE Z3 mapping mode\n"));
+               set_expamem_z3_hack_mode(Z3MAPPING_UAE);
+               if (expamem_z3_pointer_uae > totalsize) {
+                       totalsize = expamem_z3_pointer_uae;
+                       startbarrier = 0;
                }
-               if ((rounds > 1 && totalsize < 0x10000000) || rounds > 20) {
-                       write_log (_T("NATMEM: No special area could be allocated (3)!\n"));
-                       return 0;
+       } else {
+               changed_prefs.z3autoconfig_start = currprefs.z3autoconfig_start = Z3BASE_REAL;
+               set_expamem_z3_hack_mode(Z3MAPPING_REAL);
+               if (expamem_z3_pointer_real > totalsize) {
+                       totalsize = expamem_z3_pointer_real;
+                       if (totalsize + 16 * si.dwPageSize >= natmem_reserved_size && expamem_z3_pointer_uae < totalsize) {
+                               totalsize = expamem_z3_pointer_uae;
+                       }
+                       startbarrier = 0;
                }
-               natmemsize = size + z3size;
+       }
+       if (totalsize < expamem_highmem_pointer)
+               totalsize = expamem_highmem_pointer;
 
-               if (startbarrier + natmemsize + z3rtgmem_size + 16 * si.dwPageSize <= natmem_reserved_size)
-                       break;
-               write_log (_T("NATMEM: %dM area failed to allocate, err=%d (Z3=%dM,RTG=%dM)\n"),
-                       natmemsize >> 20, GetLastError (), (changed_prefs.z3fastmem_size + changed_prefs.z3fastmem2_size + changed_prefs.z3chipmem_size) >> 20, z3rtgmem_size >> 20);
-               if (!lowmem ()) {
-                       write_log (_T("NATMEM: No special area could be allocated (2)!\n"));
-                       return 0;
-               }
+       if (totalsize > size64 || totalsize + 16 * si.dwPageSize >= natmem_reserved_size) {
+               write_log(_T("NATMEM: Not enough memory!\n"));
+               return -1;
        }
 
-       set_expamem_z3_hack_override(false);
+       jit_direct_compatible_memory = true;
+
+       expansion_scan_autoconfig(&currprefs, true);
+#if 0
        z3offset = 0;
        if (changed_prefs.z3_mapping_mode != Z3MAPPING_UAE && cpuboard_memorytype(&changed_prefs) != BOARD_MEMORY_BLIZZARD_12xx) {
                if (1 && natmem_reserved_size > 0x40000000 && natmem_reserved_size - 0x40000000 >= (totalsize - 0x10000000 - ((changed_prefs.z3chipmem_size + align) & ~align)) && changed_prefs.z3chipmem_size <= 512 * 1024 * 1024) {
@@ -411,7 +403,9 @@ static int doinit_shm (void)
                jit_direct_compatible_memory = true;
                write_log(_T("Z3 UAE mapping.\n"));
        }
+#endif
 
+#if 0
        p96mem_offset = NULL;
        p96mem_size = z3rtgmem_size;
        p96base_offset = 0;
@@ -461,49 +455,59 @@ static int doinit_shm (void)
                        }
                }
        }
+#endif
 
        if (!natmem_offset) {
                write_log (_T("NATMEM: No special area could be allocated! err=%d\n"), GetLastError ());
        } else {
                write_log(_T("NATMEM: Our special area: %p-%p (0x%08x %dM)\n"),
-                                 natmem_offset, (uae_u8*)natmem_offset + natmemsize,
-                                 natmemsize, natmemsize / (1024 * 1024));
+                       natmem_offset, (uae_u8*)natmem_offset + totalsize,
+                       totalsize, totalsize / (1024 * 1024));
+#if 0
                if (rbc->rtgmem_size)
                        write_log (_T("NATMEM: P96 special area: %p-%p (0x%08x %dM)\n"),
-                       p96mem_offset, (uae_u8*)p96mem_offset + rbc->rtgmem_size,
-                       rbc->rtgmem_size, rbc->rtgmem_size >> 20);
+                               p96mem_offset, (uae_u8*)p96mem_offset + rbc->rtgmem_size,
+                               rbc->rtgmem_size, rbc->rtgmem_size >> 20);
+#endif
                canbang = jit_direct_compatible_memory ? 1 : 0;
                if (p96mem_size)
                        natmem_offset_end = p96mem_offset + p96mem_size;
                else
-                       natmem_offset_end = natmem_offset + natmemsize;
+                       natmem_offset_end = natmem_offset + totalsize;
        }
 
        return canbang;
 }
 
-static uae_u32 oz3fastmem_size, oz3fastmem2_size;
+static uae_u32 oz3fastmem_size[MAX_RAM_BOARDS];
 static uae_u32 oz3chipmem_size;
-static uae_u32 ortgmem_size;
-static int ortgmem_type = -1;
+static uae_u32 ortgmem_size[MAX_RTG_BOARDS];
+static int ortgmem_type[MAX_RTG_BOARDS];
 
 bool init_shm (void)
 {
-       if (
-               oz3fastmem_size == changed_prefs.z3fastmem_size &&
-               oz3fastmem2_size == changed_prefs.z3fastmem2_size &&
-               oz3chipmem_size == changed_prefs.z3chipmem_size &&
-               ortgmem_size == changed_prefs.rtgboards[0].rtgmem_size &&
-               ortgmem_type == changed_prefs.rtgboards[0].rtgmem_type)
-               return false;
+       bool changed = false;
+
+       for (int i = 0; i < MAX_RAM_BOARDS; i++) {
+               if (oz3fastmem_size[i] != changed_prefs.z3fastmem[i].size)
+                       changed = true;
+               if (ortgmem_size[i] != changed_prefs.rtgboards[i].rtgmem_size)
+                       changed = true;
+               if (ortgmem_type[i] != changed_prefs.rtgboards[i].rtgmem_type)
+                       changed = true;
+       }
+       if (!changed && oz3chipmem_size == changed_prefs.z3chipmem_size)
+               return true;
 
-       oz3fastmem_size = changed_prefs.z3fastmem_size;
-       oz3fastmem2_size = changed_prefs.z3fastmem2_size;
-       oz3chipmem_size = changed_prefs.z3chipmem_size;;
-       ortgmem_size = changed_prefs.rtgboards[0].rtgmem_size;
-       ortgmem_type = changed_prefs.rtgboards[0].rtgmem_type;
+       for (int i = 0; i < MAX_RAM_BOARDS;i++) {
+               oz3fastmem_size[i] = changed_prefs.z3fastmem[i].size;
+               ortgmem_size[i] = changed_prefs.rtgboards[i].rtgmem_size;
+               ortgmem_type[i] = changed_prefs.rtgboards[i].rtgmem_type;
+       }
+       oz3chipmem_size = changed_prefs.z3chipmem_size;
 
-       doinit_shm ();
+       if (doinit_shm () < 0)
+               return false;
 
        resetmem (false);
        clear_shm ();
@@ -516,7 +520,9 @@ void free_shm (void)
 {
        resetmem (true);
        clear_shm ();
-       ortgmem_type = -1;
+       for (int i = 0; i < MAX_RAM_BOARDS; i++) {
+               ortgmem_type[i] = -1;
+       }
 }
 
 void mapped_free (addrbank *ab)
@@ -615,17 +621,16 @@ void *uae_shmat (addrbank *ab, int shmid, void *shmaddr, int shmflg)
                return shmids[shmid].attached;
 
        if (ab->flags & ABFLAG_INDIRECT) {
-               result = xcalloc (uae_u8, size);
-               shmids[shmid].attached = result;
+               shmids[shmid].attached = ab->baseaddr;
                shmids[shmid].fake = true;
-               return result;
+               return shmids[shmid].attached;
        }
 
        if ((uae_u8*)shmaddr < natmem_offset) {
                if(!_tcscmp (shmids[shmid].name, _T("chip"))) {
                        shmaddr=natmem_offset;
                        got = true;
-                       if (getz2endaddr () <= 2 * 1024 * 1024 || currprefs.chipmem_size < 2 * 1024 * 1024)
+                       if (!expansion_get_autoconfig_by_address(&currprefs, 0x00200000) || currprefs.chipmem_size < 2 * 1024 * 1024)
                                size += BARRIER;
                } else if(!_tcscmp (shmids[shmid].name, _T("kick"))) {
                        shmaddr=natmem_offset + 0xf80000;
@@ -657,51 +662,6 @@ void *uae_shmat (addrbank *ab, int shmid, void *shmaddr, int shmflg)
                        got = true;
                        readonly = true;
                        readonlysize = RTAREA_TRAPS;
-               } else if (!_tcscmp(shmids[shmid].name, _T("uaeboard"))) {
-                       if (currprefs.uaeboard > 1)
-                               shmaddr = natmem_offset + rtarea_base - 65536;
-                       else
-                               shmaddr = natmem_offset + 0xe90000; // FIXME!
-                       got = true;
-               } else if (!_tcscmp(shmids[shmid].name, _T("fmv_rom"))) {
-                       got = true;
-                       shmaddr = natmem_offset + 0x200000;
-               } else if (!_tcscmp(shmids[shmid].name, _T("fmv_ram"))) {
-                       got = true;
-                       shmaddr = natmem_offset + 0x280000;
-               } else if(!_tcscmp (shmids[shmid].name, _T("fast"))) {
-                       got = true;
-                       if (size < 524288) {
-                               shmaddr=natmem_offset + 0xec0000;
-                       } else {
-                               shmaddr=natmem_offset + 0x200000;
-                               if (!(rbc->rtgmem_size && gfxboard_get_configtype(rbc) == 3))
-                                       size += BARRIER;
-                       }
-               } else if(!_tcscmp (shmids[shmid].name, _T("fast2"))) {
-                       got = true;
-                       if (size < 524288) {
-                               shmaddr=natmem_offset + 0xec0000;
-                       } else {
-                               shmaddr=natmem_offset + 0x200000;
-                               if (currprefs.fastmem_size >= 524288)
-                                       shmaddr=natmem_offset + 0x200000 + currprefs.fastmem_size;
-                               if (!(rbc->rtgmem_size && gfxboard_get_configtype(rbc) == 3))
-                                       size += BARRIER;
-                       }
-               } else if(!_tcscmp (shmids[shmid].name, _T("fast2"))) {
-                       shmaddr=natmem_offset + 0x200000;
-                       got = true;
-                       if (!(rbc->rtgmem_size && gfxboard_get_configtype(rbc) == 3))
-                               size += BARRIER;
-               } else if(!_tcscmp (shmids[shmid].name, _T("z2_gfx"))) {
-                       ULONG start = getz2rtgaddr(rbc);
-                       got = true;
-                       p96special = true;
-                       shmaddr = natmem_offset + start;
-                       gfxmem_bank.start = start;
-                       if (start + rbc->rtgmem_size < 10 * 1024 * 1024)
-                               size += BARRIER;
                } else if(!_tcscmp (shmids[shmid].name, _T("ramsey_low"))) {
                        shmaddr=natmem_offset + a3000lmem_bank.start;
                        if (!a3000hmem_bank.start)
@@ -737,28 +697,12 @@ void *uae_shmat (addrbank *ab, int shmid, void *shmaddr, int shmflg)
                } else if (!_tcscmp(shmids[shmid].name, _T("cyberstorm"))) {
                        shmaddr = natmem_offset + 0x0c000000;
                        got = true;
+               } else if (!_tcscmp(shmids[shmid].name, _T("*"))) {
+                       shmaddr = natmem_offset + ab->start;
+                       got = true;
                } else if (!_tcscmp(shmids[shmid].name, _T("cyberstormmaprom"))) {
                        shmaddr = natmem_offset + 0xfff00000;
                        got = true;
-               } else if (!_tcscmp(shmids[shmid].name, _T("z3"))) {
-                       shmaddr=natmem_offset + z3fastmem_bank.start;
-                       if (!currprefs.z3fastmem2_size)
-                               size += BARRIER;
-                       got = true;
-               } else if(!_tcscmp (shmids[shmid].name, _T("z3_2"))) {
-                       shmaddr=natmem_offset + z3fastmem_bank.start + currprefs.z3fastmem_size;
-                       size += BARRIER;
-                       got = true;
-               } else if(!_tcscmp (shmids[shmid].name, _T("z3_chip"))) {
-                       shmaddr=natmem_offset + z3chipmem_bank.start;
-                       size += BARRIER;
-                       got = true;
-               } else if(!_tcscmp (shmids[shmid].name, _T("z3_gfx"))) {
-                       got = true;
-                       p96special = true;
-                       gfxmem_bank.start = p96mem_offset - natmem_offset;
-                       shmaddr = natmem_offset + gfxmem_bank.start;
-                       size += BARRIER;
                } else if(!_tcscmp (shmids[shmid].name, _T("bogo"))) {
                        shmaddr=natmem_offset+0x00C00000;
                        got = true;
@@ -839,8 +783,8 @@ void *uae_shmat (addrbank *ab, int shmid, void *shmaddr, int shmflg)
                result = virtualallocwithlock (shmaddr, size, MEM_COMMIT, PAGE_READWRITE);
                if (result == NULL) {
                        result = (void*)-1;
-                       error_log (_T("Memory %s failed to allocate %p: VA %08X - %08X %x (%dk). Error %d."),
-                               shmids[shmid].name, shmaddr,
+                       error_log (_T("Memory %s (%s) failed to allocate %p: VA %08X - %08X %x (%dk). Error %d."),
+                               shmids[shmid].name, ab ? ab->name : _T("?"), shmaddr,
                                (uae_u8*)shmaddr - natmem_offset, (uae_u8*)shmaddr - natmem_offset + size,
                                size, size >> 10, GetLastError ());
                } else {
index 3b62aa6065769fd637c920f56db9ee54b3dd1d6d..ce0af62d9200d80475edd07608045a2f231a720a 100644 (file)
@@ -126,6 +126,7 @@ static uae_atomic picasso_state_change;
 static uae_u8 all_ones_bitmap, all_zeros_bitmap; /* yuk */
 
 struct picasso96_state_struct picasso96_state;
+static struct picasso96_state_struct picasso96_state_uaegfx;
 struct picasso_vidbuf_description picasso_vidinfo;
 static struct PicassoResolution *newmodes;
 
@@ -194,6 +195,9 @@ static int set_gc_called = 0, init_picasso_screen_called = 0;
 //fastscreen
 static uaecptr oldscr = 0;
 
+extern addrbank gfxmem_bank;
+extern addrbank *gfxmem_banks[MAX_RTG_BOARDS];
+extern int rtg_index;
 
 STATIC_INLINE void endianswap (uae_u32 *vp, int bpp)
 {
@@ -350,8 +354,8 @@ static void ShowSupportedResolutions (void)
 
 #endif
 
-static void **gwwbuf;
-static int gwwbufsize, gwwpagesize, gwwpagemask;
+static void **gwwbuf[MAX_RTG_BOARDS];
+static int gwwbufsize[MAX_RTG_BOARDS], gwwpagesize[MAX_RTG_BOARDS], gwwpagemask[MAX_RTG_BOARDS];
 extern uae_u8 *natmem_offset;
 
 static uae_u8 GetBytesPerPixel (uae_u32 RGBfmt)
@@ -738,13 +742,13 @@ void picasso_trigger_vblank(void)
 static bool rtg_render (void)
 {
        bool flushed = false;
-       bool uaegfx = currprefs.rtgboards[0].rtgmem_type < GFXBOARD_HARDWARE;
+       bool uaegfx = currprefs.rtgboards[rtg_index].rtgmem_type < GFXBOARD_HARDWARE;
 
        if (doskip () && p96skipmode == 0) {
                ;
        } else {
                if (uaegfx) {
-                       flushed = picasso_flushpixels (gfxmem_bank.start + natmem_offset, picasso96_state.XYOffset - gfxmem_bank.start);
+                       flushed = picasso_flushpixels (rtg_index, gfxmem_banks[rtg_index]->start + natmem_offset, picasso96_state.XYOffset - gfxmem_banks[rtg_index]->start);
                } else {
                        flushed = gfxboard_vsync_handler ();
                }
@@ -799,13 +803,6 @@ enum {
        RGBFB_CLUT_8
 };
 
-static uae_u32 setspriteimage(TrapContext *ctx, uaecptr bi);
-static void recursor(TrapContext *ctx)
-{
-       cursorok = FALSE;
-       setspriteimage(ctx, boardinfo);
-}
-
 static int getconvert(int rgbformat, int pixbytes)
 {
        int v = 0;
@@ -900,7 +897,7 @@ static int getconvert(int rgbformat, int pixbytes)
        return v;
 }
 
-static void setconvert(TrapContext *ctx)
+static void setconvert(void)
 {
        static int ohost_mode, orgbformat;
 
@@ -922,7 +919,6 @@ static void setconvert(TrapContext *ctx)
                ohost_mode = host_mode;
                orgbformat = picasso96_state.RGBFormat;
        }
-       recursor(ctx);
        full_refresh = 1;
 }
 
@@ -941,14 +937,14 @@ void picasso_refresh (void)
 {
        struct RenderInfo ri;
 
-       if (! picasso_on)
+       if (!picasso_on || rtg_index < 0)
                return;
        full_refresh = 1;
-       setconvert(NULL);
+       setconvert();
        setupcursor();
        rtg_clear();
 
-       if (currprefs.rtgboards[0].rtgmem_type >= GFXBOARD_HARDWARE) {
+       if (currprefs.rtgboards[rtg_index].rtgmem_type >= GFXBOARD_HARDWARE) {
                gfxboard_refresh ();
                return;
        }
@@ -983,6 +979,10 @@ void picasso_refresh (void)
        }
 }
 
+static void selectuaegfx(void)
+{
+       memcpy(&picasso96_state, &picasso96_state_uaegfx, sizeof picasso96_state);
+}
 
 static void picasso_handle_vsync2(void)
 {
@@ -991,7 +991,7 @@ static void picasso_handle_vsync2(void)
        int vsync = isvsync_rtg();
        int mult;
        bool rendered = false;
-       bool uaegfx = currprefs.rtgboards[0].rtgmem_type < GFXBOARD_HARDWARE;
+       bool uaegfx = currprefs.rtgboards[rtg_index].rtgmem_type < GFXBOARD_HARDWARE;
 
        int state = picasso_state_change;
        if (state & PICASSO_STATE_SETDAC) {
@@ -1000,6 +1000,7 @@ static void picasso_handle_vsync2(void)
        }
        if (state & PICASSO_STATE_SETGC) {
                atomic_and(&picasso_state_change, ~PICASSO_STATE_SETGC);
+               selectuaegfx();
                set_gc_called = 1;
                picasso_changed = true;
                init_picasso_screen();
@@ -1007,6 +1008,7 @@ static void picasso_handle_vsync2(void)
        }
        if (state & PICASSO_STATE_SETSWITCH) {
                atomic_and(&picasso_state_change, ~PICASSO_STATE_SETSWITCH);
+               selectuaegfx();
                /* Do not switch immediately.  Tell the custom chip emulation about the
                * desired state, and wait for custom.c to call picasso_enablescreen
                * whenever it is ready to change the screen state.  */
@@ -1018,11 +1020,11 @@ static void picasso_handle_vsync2(void)
        }
        if (state & PICASSO_STATE_SETPANNING) {
                atomic_and(&picasso_state_change, ~PICASSO_STATE_SETPANNING);
+               selectuaegfx();
                full_refresh = 1;
                set_panning_called = 1;
                init_picasso_screen();
                set_panning_called = 0;
-
        }
 
        if (picasso_on) {
@@ -1078,9 +1080,12 @@ static int p96hsync;
 
 void picasso_handle_vsync(void)
 {
-       bool uaegfx = currprefs.rtgboards[0].rtgmem_type < GFXBOARD_HARDWARE;
+       if (rtg_index < 0)
+               return;
 
-       if (currprefs.rtgboards[0].rtgmem_size == 0)
+       bool uaegfx = currprefs.rtgboards[rtg_index].rtgmem_type < GFXBOARD_HARDWARE;
+
+       if (currprefs.rtgboards[rtg_index].rtgmem_size == 0)
                return;
 
        if (!picasso_on && uaegfx) {
@@ -1100,9 +1105,12 @@ void picasso_handle_vsync(void)
 
 void picasso_handle_hsync(void)
 {
-       bool uaegfx = currprefs.rtgboards[0].rtgmem_type < GFXBOARD_HARDWARE;
+       if (rtg_index < 0)
+               return;
 
-       if (currprefs.rtgboards[0].rtgmem_size == 0)
+       bool uaegfx = currprefs.rtgboards[rtg_index].rtgmem_type < GFXBOARD_HARDWARE;
+
+       if (currprefs.rtgboards[rtg_index].rtgmem_size == 0)
                return;
 
        int vsync = isvsync_rtg();
@@ -1939,11 +1947,11 @@ static uae_u32 REGPARAM2 picasso_FindCard (TrapContext *ctx)
                picasso96_alloc2 (ctx);
        }
        boardinfo = AmigaBoardInfo;
-       if (gfxmem_bank.allocated && !picasso96_state.CardFound) {
+       if (gfxmem_bank.allocated && !picasso96_state_uaegfx.CardFound) {
                /* Fill in MemoryBase, MemorySize */
                trap_put_long(ctx, AmigaBoardInfo + PSSO_BoardInfo_MemoryBase, gfxmem_bank.start);
                trap_put_long(ctx, AmigaBoardInfo + PSSO_BoardInfo_MemorySize, gfxmem_bank.allocated - reserved_gfxmem);
-               picasso96_state.CardFound = 1; /* mark our "card" as being found */
+               picasso96_state_uaegfx.CardFound = 1; /* mark our "card" as being found */
                return -1;
        } else
                return 0;
@@ -2108,41 +2116,41 @@ static void CopyLibResolutionStructureU2A(TrapContext *ctx, struct LibResolution
        trap_put_long(ctx, amigamemptr + PSSO_LibResolution_BoardInfo, libres->BoardInfo);
 }
 
-void picasso_allocatewritewatch (int gfxmemsize)
+void picasso_allocatewritewatch (int index, int gfxmemsize)
 {
        SYSTEM_INFO si;
 
-       xfree (gwwbuf);
+       xfree (gwwbuf[index]);
        GetSystemInfo (&si);
-       gwwpagesize = si.dwPageSize;
-       gwwbufsize = gfxmemsize / gwwpagesize + 1;
-       gwwpagemask = gwwpagesize - 1;
-       gwwbuf = xmalloc (void*, gwwbufsize);
+       gwwpagesize[index] = si.dwPageSize;
+       gwwbufsize[index] = gfxmemsize / gwwpagesize[index] + 1;
+       gwwpagemask[index] = gwwpagesize[index] - 1;
+       gwwbuf[index] = xmalloc (void*, gwwbufsize[index]);
 }
 
-static ULONG_PTR writewatchcount;
-static int watch_offset;
-void picasso_getwritewatch (int offset)
+static ULONG_PTR writewatchcount[MAX_RTG_BOARDS];
+static int watch_offset[MAX_RTG_BOARDS];
+void picasso_getwritewatch (int index, int offset)
 {
        ULONG ps;
-       writewatchcount = gwwbufsize;
-       watch_offset = offset;
-       if (GetWriteWatch (WRITE_WATCH_FLAG_RESET, gfxmem_bank.start + natmem_offset + offset, (gwwbufsize - 1) * gwwpagesize, gwwbuf, &writewatchcount, &ps)) {
+       writewatchcount[index] = gwwbufsize[index];
+       watch_offset[index] = offset;
+       if (GetWriteWatch (WRITE_WATCH_FLAG_RESET, gfxmem_banks[index]->start + natmem_offset + offset, (gwwbufsize[index] - 1) * gwwpagesize[index], gwwbuf[index], &writewatchcount[index], &ps)) {
                write_log (_T("picasso_getwritewatch %d\n"), GetLastError ());
-               writewatchcount = 0;
+               writewatchcount[index] = 0;
                return;
        }
 }
-bool picasso_is_vram_dirty (uaecptr addr, int size)
+bool picasso_is_vram_dirty (int index, uaecptr addr, int size)
 {
        static ULONG_PTR last;
-       uae_u8 *a = addr + natmem_offset + watch_offset;
+       uae_u8 *a = addr + natmem_offset + watch_offset[index];
        int s = size;
-       int ms = gwwpagesize;
+       int ms = gwwpagesize[index];
 
        for (;;) {
-               for (ULONG_PTR i = last; i < writewatchcount; i++) {
-                       uae_u8 *ma = (uae_u8*)gwwbuf[i];
+               for (ULONG_PTR i = last; i < writewatchcount[index]; i++) {
+                       uae_u8 *ma = (uae_u8*)gwwbuf[index][i];
                        if (
                                (a < ma && a + s >= ma) ||
                                (a < ma + ms && a + s >= ma + ms) ||
@@ -2170,7 +2178,7 @@ static void init_alloc (TrapContext *ctx, int size)
        }
        picasso96_amemend = picasso96_amem + size;
        write_log (_T("P96 RESINFO: %08X-%08X (%d,%d)\n"), picasso96_amem, picasso96_amemend, size / PSSO_ModeInfo_sizeof, size);
-       picasso_allocatewritewatch (gfxmem_bank.allocated);
+       picasso_allocatewritewatch (0, gfxmem_bank.allocated);
 }
 
 static int p96depth (int depth)
@@ -2557,7 +2565,7 @@ static uae_u32 REGPARAM2 picasso_SetSwitch (TrapContext *ctx)
        p96text[0] = 0;
        if (flag)
                _stprintf(p96text, _T("Picasso96 %dx%dx%d (%dx%dx%d)"),
-                       picasso96_state.Width, picasso96_state.Height, picasso96_state.BytesPerPixel * 8,
+                       picasso96_state_uaegfx.Width, picasso96_state_uaegfx.Height, picasso96_state_uaegfx.BytesPerPixel * 8,
                        picasso_vidinfo.width, picasso_vidinfo.height, picasso_vidinfo.pixbytes * 8);
        write_log(_T("SetSwitch() - %s\n"), flag ? p96text : _T("amiga"));
 
@@ -2568,16 +2576,19 @@ static uae_u32 REGPARAM2 picasso_SetSwitch (TrapContext *ctx)
 
 void picasso_enablescreen (int on)
 {
-       if (!init_picasso_screen_called)
-               init_picasso_screen ();
-
+       if (rtg_index == 0) {
+               selectuaegfx();
+               if (!init_picasso_screen_called)
+                       init_picasso_screen ();
+       }
+       setconvert();
        picasso_refresh ();
 }
 
 static void resetpalette(void)
 {
        for (int i = 0; i < 256; i++)
-               picasso96_state.CLUT[i].Pad = 0xff;
+               picasso96_state_uaegfx.CLUT[i].Pad = 0xff;
 }
 
 /*
@@ -2603,16 +2614,16 @@ static int updateclut(TrapContext *ctx, uaecptr clut, int start, int count)
                int g = clutbuf[i * 3 + 1];
                int b = clutbuf[i * 3 + 2];
                //write_log(_T("%d: %02x%02x%02x\n"), i, r, g, b);
-               changed |= picasso96_state.CLUT[i].Red != r
-                       || picasso96_state.CLUT[i].Green != g
-                       || picasso96_state.CLUT[i].Blue != b;
-               if (picasso96_state.CLUT[i].Pad) {
+               changed |= picasso96_state_uaegfx.CLUT[i].Red != r
+                       || picasso96_state_uaegfx.CLUT[i].Green != g
+                       || picasso96_state_uaegfx.CLUT[i].Blue != b;
+               if (picasso96_state_uaegfx.CLUT[i].Pad) {
                        changed = 1;
-                       picasso96_state.CLUT[i].Pad = 0;
+                       picasso96_state_uaegfx.CLUT[i].Pad = 0;
                }
-               picasso96_state.CLUT[i].Red = r;
-               picasso96_state.CLUT[i].Green = g;
-               picasso96_state.CLUT[i].Blue = b;
+               picasso96_state_uaegfx.CLUT[i].Red = r;
+               picasso96_state_uaegfx.CLUT[i].Green = g;
+               picasso96_state_uaegfx.CLUT[i].Blue = b;
                clut += 3;
        }
        changed |= picasso_palette ();
@@ -2655,17 +2666,17 @@ static uae_u32 REGPARAM2 picasso_SetDAC (TrapContext *ctx)
 static void init_picasso_screen (void)
 {
        if(set_panning_called) {
-               picasso96_state.Extent = picasso96_state.Address + picasso96_state.BytesPerRow * picasso96_state.VirtualHeight;
+               picasso96_state_uaegfx.Extent = picasso96_state_uaegfx.Address + picasso96_state_uaegfx.BytesPerRow * picasso96_state_uaegfx.VirtualHeight;
        }
        if (set_gc_called) {
-               gfx_set_picasso_modeinfo (picasso96_state.Width, picasso96_state.Height,
-                       picasso96_state.GC_Depth, picasso96_state.RGBFormat);
+               gfx_set_picasso_modeinfo (picasso96_state_uaegfx.Width, picasso96_state_uaegfx.Height,
+                       picasso96_state_uaegfx.GC_Depth, picasso96_state_uaegfx.RGBFormat);
                set_gc_called = 0;
        }
-       if((picasso_vidinfo.width == picasso96_state.Width) &&
-               (picasso_vidinfo.height == picasso96_state.Height) &&
-               (picasso_vidinfo.depth == (picasso96_state.GC_Depth >> 3)) &&
-               (picasso_vidinfo.selected_rgbformat == picasso96_state.RGBFormat))
+       if((picasso_vidinfo.width == picasso96_state_uaegfx.Width) &&
+               (picasso_vidinfo.height == picasso96_state_uaegfx.Height) &&
+               (picasso_vidinfo.depth == (picasso96_state_uaegfx.GC_Depth >> 3)) &&
+               (picasso_vidinfo.selected_rgbformat == picasso96_state_uaegfx.RGBFormat))
        {
                picasso_refresh ();
        }
@@ -2695,18 +2706,18 @@ static uae_u32 REGPARAM2 picasso_SetGC (TrapContext *ctx)
        trap_put_long(ctx, AmigaBoardInfo + PSSO_BoardInfo_ModeInfo, modeinfo);
        trap_put_word(ctx, AmigaBoardInfo + PSSO_BoardInfo_Border, border);
 
-       picasso96_state.Width = trap_get_word(ctx, modeinfo + PSSO_ModeInfo_Width);
-       picasso96_state.VirtualWidth = picasso96_state.Width; /* in case SetPanning doesn't get called */
+       picasso96_state_uaegfx.Width = trap_get_word(ctx, modeinfo + PSSO_ModeInfo_Width);
+       picasso96_state_uaegfx.VirtualWidth = picasso96_state_uaegfx.Width; /* in case SetPanning doesn't get called */
 
-       picasso96_state.Height =trap_get_word(ctx, modeinfo + PSSO_ModeInfo_Height);
-       picasso96_state.VirtualHeight = picasso96_state.Height; /* in case SetPanning doesn't get called */
+       picasso96_state_uaegfx.Height = trap_get_word(ctx, modeinfo + PSSO_ModeInfo_Height);
+       picasso96_state_uaegfx.VirtualHeight = picasso96_state_uaegfx.Height; /* in case SetPanning doesn't get called */
 
-       picasso96_state.GC_Depth = trap_get_byte(ctx, modeinfo + PSSO_ModeInfo_Depth);
-       picasso96_state.GC_Flags = trap_get_byte(ctx, modeinfo + PSSO_ModeInfo_Flags);
+       picasso96_state_uaegfx.GC_Depth = trap_get_byte(ctx, modeinfo + PSSO_ModeInfo_Depth);
+       picasso96_state_uaegfx.GC_Flags = trap_get_byte(ctx, modeinfo + PSSO_ModeInfo_Flags);
 
-       P96TRACE_SETUP((_T("SetGC(%d,%d,%d,%d)\n"), picasso96_state.Width, picasso96_state.Height, picasso96_state.GC_Depth, border));
+       P96TRACE_SETUP((_T("SetGC(%d,%d,%d,%d)\n"), picasso96_state_uaegfx.Width, picasso96_state_uaegfx.Height, picasso96_state_uaegfx.GC_Depth, border));
 
-       picasso96_state.HostAddress = NULL;
+       picasso96_state_uaegfx.HostAddress = NULL;
 
        atomic_or(&picasso_state_change, PICASSO_STATE_SETGC);
 
@@ -2738,12 +2749,12 @@ static uae_u32 REGPARAM2 picasso_SetGC (TrapContext *ctx)
 
 static void picasso_SetPanningInit (void)
 {
-       picasso96_state.XYOffset = picasso96_state.Address + (picasso96_state.XOffset * picasso96_state.BytesPerPixel)
-               + (picasso96_state.YOffset * picasso96_state.BytesPerRow);
-       if(picasso96_state.VirtualWidth > picasso96_state.Width || picasso96_state.VirtualHeight > picasso96_state.Height)
-               picasso96_state.BigAssBitmap = 1;
+       picasso96_state_uaegfx.XYOffset = picasso96_state_uaegfx.Address + (picasso96_state_uaegfx.XOffset * picasso96_state_uaegfx.BytesPerPixel)
+               + (picasso96_state_uaegfx.YOffset * picasso96_state_uaegfx.BytesPerRow);
+       if(picasso96_state_uaegfx.VirtualWidth > picasso96_state_uaegfx.Width || picasso96_state_uaegfx.VirtualHeight > picasso96_state_uaegfx.Height)
+               picasso96_state_uaegfx.BigAssBitmap = 1;
        else
-               picasso96_state.BigAssBitmap = 0;
+               picasso96_state_uaegfx.BigAssBitmap = 0;
 }
 
 static uae_u32 REGPARAM2 picasso_SetPanning (TrapContext *ctx)
@@ -2767,27 +2778,29 @@ static uae_u32 REGPARAM2 picasso_SetPanning (TrapContext *ctx)
 
        bme_width = trap_get_word(ctx, bmeptr + PSSO_BitMapExtra_Width);
        bme_height = trap_get_word(ctx, bmeptr + PSSO_BitMapExtra_Height);
-       rgbf = picasso96_state.RGBFormat;
-
-       picasso96_state.Address = start_of_screen; /* Amiga-side address */
-       picasso96_state.XOffset = (uae_s16)(trap_get_dreg(ctx, 1) & 0xFFFF);
-       picasso96_state.YOffset = (uae_s16)(trap_get_dreg(ctx, 2) & 0xFFFF);
-       trap_put_word(ctx, bi + PSSO_BoardInfo_XOffset, picasso96_state.XOffset);
-       trap_put_word(ctx, bi + PSSO_BoardInfo_YOffset, picasso96_state.YOffset);
-       picasso96_state.VirtualWidth = bme_width;
-       picasso96_state.VirtualHeight = bme_height;
-       picasso96_state.RGBFormat = (RGBFTYPE)trap_get_dreg(ctx, 7);
-       picasso96_state.BytesPerPixel = GetBytesPerPixel (picasso96_state.RGBFormat);
-       picasso96_state.BytesPerRow = picasso96_state.VirtualWidth * picasso96_state.BytesPerPixel;
+       rgbf = picasso96_state_uaegfx.RGBFormat;
+
+       picasso96_state_uaegfx.Address = start_of_screen; /* Amiga-side address */
+       picasso96_state_uaegfx.XOffset = (uae_s16)(trap_get_dreg(ctx, 1) & 0xFFFF);
+       picasso96_state_uaegfx.YOffset = (uae_s16)(trap_get_dreg(ctx, 2) & 0xFFFF);
+       trap_put_word(ctx, bi + PSSO_BoardInfo_XOffset, picasso96_state_uaegfx.XOffset);
+       trap_put_word(ctx, bi + PSSO_BoardInfo_YOffset, picasso96_state_uaegfx.YOffset);
+       picasso96_state_uaegfx.VirtualWidth = bme_width;
+       picasso96_state_uaegfx.VirtualHeight = bme_height;
+       picasso96_state_uaegfx.RGBFormat = (RGBFTYPE)trap_get_dreg(ctx, 7);
+       picasso96_state_uaegfx.BytesPerPixel = GetBytesPerPixel (picasso96_state_uaegfx.RGBFormat);
+       picasso96_state_uaegfx.BytesPerRow = picasso96_state_uaegfx.VirtualWidth * picasso96_state_uaegfx.BytesPerPixel;
        picasso_SetPanningInit();
 
-       if (rgbf != picasso96_state.RGBFormat)
-               setconvert(ctx);
+       if (rgbf != picasso96_state_uaegfx.RGBFormat && rtg_index <= 0) {
+               selectuaegfx();
+               setconvert();
+       }
 
        P96TRACE_SETUP((_T("SetPanning(%d, %d, %d) (%dx%d) Start 0x%x, BPR %d Bpp %d RGBF %d\n"),
-               Width, picasso96_state.XOffset, picasso96_state.YOffset,
+               Width, picasso96_state_uaegfx.XOffset, picasso96_state_uaegfx.YOffset,
                bme_width, bme_height,
-               start_of_screen, picasso96_state.BytesPerRow, picasso96_state.BytesPerPixel, picasso96_state.RGBFormat));
+               start_of_screen, picasso96_state_uaegfx.BytesPerRow, picasso96_state_uaegfx.BytesPerPixel, picasso96_state_uaegfx.RGBFormat));
 
        atomic_or(&picasso_state_change, PICASSO_STATE_SETPANNING);
 
@@ -4317,7 +4330,7 @@ void picasso_invalidate (int x, int y, int w, int h)
        DX_Invalidate (x, y, w, h);
 }
 
-bool picasso_flushpixels (uae_u8 *src, int off)
+bool picasso_flushpixels (int index, uae_u8 *src, int off)
 {
        uae_u8 *src_start;
        uae_u8 *src_end;
@@ -4330,15 +4343,15 @@ bool picasso_flushpixels (uae_u8 *src, int off)
        int miny = pheight - 1;
        int flushlines = 0, matchcount = 0;
 
-       src_start = src + (off & ~gwwpagemask);
-       src_end = src + ((off + picasso96_state.BytesPerRow * pheight + gwwpagesize - 1) & ~gwwpagemask);
+       src_start = src + (off & ~gwwpagemask[index]);
+       src_end = src + ((off + picasso96_state.BytesPerRow * pheight + gwwpagesize[index] - 1) & ~gwwpagemask[index]);
 #if 0
        write_log (_T("%dx%d %dx%d %dx%d (%dx%d)\n"), picasso96_state.Width, picasso96_state.Width,
                picasso96_state.VirtualWidth, picasso96_state.VirtualHeight,
                picasso_vidinfo.width, picasso_vidinfo.height,
                pwidth, pheight);
 #endif
-       if (!picasso_vidinfo.extra_mem || !gwwbuf || src_start >= src_end) {
+       if (!picasso_vidinfo.extra_mem || !gwwbuf[index] || src_start >= src_end) {
                return false;
        }
 
@@ -4358,14 +4371,14 @@ bool picasso_flushpixels (uae_u8 *src, int off)
                }
 
                if (full_refresh < 0) {
-                       gwwcnt = (src_end - src_start) / gwwpagesize + 1;
+                       gwwcnt = (src_end - src_start) / gwwpagesize[index] + 1;
                        full_refresh = 1;
                        for (int i = 0; i < gwwcnt; i++)
-                               gwwbuf[i] = src_start + i * gwwpagesize;
+                               gwwbuf[index][i] = src_start + i * gwwpagesize[index];
                } else {
                        ULONG ps;
-                       gwwcnt = gwwbufsize;
-                       if (mman_GetWriteWatch (src_start, src_end - src_start, gwwbuf, &gwwcnt, &ps))
+                       gwwcnt = gwwbufsize[index];
+                       if (mman_GetWriteWatch (src_start, src_end - src_start, gwwbuf[index], &gwwcnt, &ps))
                                break;
                }
 
@@ -4374,7 +4387,7 @@ bool picasso_flushpixels (uae_u8 *src, int off)
                if (gwwcnt == 0)
                        break;
 
-               dofull = gwwcnt >= ((src_end - src_start) / gwwpagesize) * 80 / 100;
+               dofull = gwwcnt >= ((src_end - src_start) / gwwpagesize[index]) * 80 / 100;
 
                dst = gfx_lock_picasso (dofull, rtg_clear_flag != 0);
                if (rtg_clear_flag)
@@ -4407,7 +4420,7 @@ bool picasso_flushpixels (uae_u8 *src, int off)
                }
 
                for (int i = 0; i < gwwcnt; i++) {
-                       uae_u8 *p = (uae_u8*)gwwbuf[i];
+                       uae_u8 *p = (uae_u8*)gwwbuf[index][i];
 
                        if (p >= src_start && p < src_end) {
                                int y, x, realoffset;
@@ -4420,7 +4433,7 @@ bool picasso_flushpixels (uae_u8 *src, int off)
 
                                y = realoffset / picasso96_state.BytesPerRow;
                                if (y < pheight) {
-                                       int w = gwwpagesize / picasso96_state.BytesPerPixel;
+                                       int w = gwwpagesize[index] / picasso96_state.BytesPerPixel;
                                        x = (realoffset % picasso96_state.BytesPerRow) / picasso96_state.BytesPerPixel;
                                        if (x < pwidth) {
                                                copyrow (src + off, dst, x, y, pwidth - x,
@@ -4429,7 +4442,7 @@ bool picasso_flushpixels (uae_u8 *src, int off)
                                                        picasso96_state.RGBFormat == host_mode, picasso_convert);
                                                flushlines++;
                                        }
-                                       w = (gwwpagesize - (picasso96_state.BytesPerRow - x * picasso96_state.BytesPerPixel)) / picasso96_state.BytesPerPixel;
+                                       w = (gwwpagesize[index] - (picasso96_state.BytesPerRow - x * picasso96_state.BytesPerPixel)) / picasso96_state.BytesPerPixel;
                                        if (y < miny)
                                                miny = y;
                                        y++;
@@ -4488,8 +4501,8 @@ bool picasso_flushpixels (uae_u8 *src, int off)
        return lock != 0; 
 }
 
+extern addrbank gfxmem_bank;
 MEMORY_FUNCTIONS(gfxmem);
-
 addrbank gfxmem_bank = {
        gfxmem_lget, gfxmem_wget, gfxmem_bget,
        gfxmem_lput, gfxmem_wput, gfxmem_bput,
@@ -4497,6 +4510,34 @@ addrbank gfxmem_bank = {
        dummy_lgeti, dummy_wgeti,
        ABFLAG_RAM | ABFLAG_RTG, 0, 0
 };
+extern addrbank gfxmem2_bank;
+MEMORY_FUNCTIONS(gfxmem2);
+addrbank gfxmem2_bank = {
+       gfxmem2_lget, gfxmem2_wget, gfxmem2_bget,
+       gfxmem2_lput, gfxmem2_wput, gfxmem2_bput,
+       gfxmem2_xlate, gfxmem2_check, NULL, NULL, _T("RTG RAM #2"),
+       dummy_lgeti, dummy_wgeti,
+       ABFLAG_RAM | ABFLAG_RTG, 0, 0
+};
+extern addrbank gfxmem3_bank;
+MEMORY_FUNCTIONS(gfxmem3);
+addrbank gfxmem3_bank = {
+       gfxmem3_lget, gfxmem3_wget, gfxmem3_bget,
+       gfxmem3_lput, gfxmem3_wput, gfxmem3_bput,
+       gfxmem3_xlate, gfxmem3_check, NULL, NULL, _T("RTG RAM #3"),
+       dummy_lgeti, dummy_wgeti,
+       ABFLAG_RAM | ABFLAG_RTG, 0, 0
+};
+extern addrbank gfxmem4_bank;
+MEMORY_FUNCTIONS(gfxmem4);
+addrbank gfxmem4_bank = {
+       gfxmem4_lget, gfxmem4_wget, gfxmem4_bget,
+       gfxmem4_lput, gfxmem4_wput, gfxmem4_bput,
+       gfxmem4_xlate, gfxmem4_check, NULL, NULL, _T("RTG RAM #4"),
+       dummy_lgeti, dummy_wgeti,
+       ABFLAG_RAM | ABFLAG_RTG, 0, 0
+};
+addrbank *gfxmem_banks[MAX_RTG_BOARDS];
 
 /* Call this function first, near the beginning of code flow
 * Place in InitGraphics() which seems reasonable...
@@ -4505,10 +4546,15 @@ void InitPicasso96 (void)
 {
        int i;
 
+       gfxmem_banks[0] = &gfxmem_bank;
+       gfxmem_banks[1] = &gfxmem2_bank;
+       gfxmem_banks[2] = &gfxmem3_bank;
+       gfxmem_banks[3] = &gfxmem4_bank;
+
        //fastscreen
        oldscr = 0;
        //fastscreen
-       memset (&picasso96_state, 0, sizeof (struct picasso96_state_struct));
+       memset (&picasso96_state_uaegfx, 0, sizeof (struct picasso96_state_struct));
 
        for (i = 0; i < 256; i++) {
                p2ctab[i][0] = (((i & 128) ? 0x01000000 : 0)
@@ -5045,25 +5091,25 @@ uae_u8 *restore_p96 (uae_u8 *src)
        picasso_requested_on = !!(flags & 1);
        hwsprite = !!(flags & 8);
        cursorvisible = !!(flags & 16);
-       picasso96_state.SwitchState = picasso_requested_on;
+       picasso96_state_uaegfx.SwitchState = picasso_requested_on;
        picasso_on = 0;
        init_picasso_screen_called = 0;
        set_gc_called = !!(flags & 2);
        set_panning_called = !!(flags & 4);
        interrupt_enabled = !!(flags & 32);
        changed_prefs.rtgboards[0].rtgmem_size = restore_u32 ();
-       picasso96_state.Address = restore_u32 ();
-       picasso96_state.RGBFormat = (RGBFTYPE)restore_u32 ();
-       picasso96_state.Width = restore_u16 ();
-       picasso96_state.Height = restore_u16 ();
-       picasso96_state.VirtualWidth = restore_u16 ();
-       picasso96_state.VirtualHeight = restore_u16 ();
-       picasso96_state.XOffset = restore_u16 ();
-       picasso96_state.YOffset = restore_u16 ();
-       picasso96_state.GC_Depth = restore_u8 ();
-       picasso96_state.GC_Flags = restore_u8 ();
-       picasso96_state.BytesPerRow = restore_u16 ();
-       picasso96_state.BytesPerPixel = restore_u8 ();
+       picasso96_state_uaegfx.Address = restore_u32 ();
+       picasso96_state_uaegfx.RGBFormat = (RGBFTYPE)restore_u32 ();
+       picasso96_state_uaegfx.Width = restore_u16 ();
+       picasso96_state_uaegfx.Height = restore_u16 ();
+       picasso96_state_uaegfx.VirtualWidth = restore_u16 ();
+       picasso96_state_uaegfx.VirtualHeight = restore_u16 ();
+       picasso96_state_uaegfx.XOffset = restore_u16 ();
+       picasso96_state_uaegfx.YOffset = restore_u16 ();
+       picasso96_state_uaegfx.GC_Depth = restore_u8 ();
+       picasso96_state_uaegfx.GC_Flags = restore_u8 ();
+       picasso96_state_uaegfx.BytesPerRow = restore_u16 ();
+       picasso96_state_uaegfx.BytesPerPixel = restore_u8 ();
        uaegfx_base = restore_u32 ();
        uaegfx_rom = restore_u32 ();
        boardinfo = restore_u32 ();
@@ -5071,14 +5117,14 @@ uae_u8 *restore_p96 (uae_u8 *src)
                cursorrgb[i] = restore_u32 ();
        if (flags & 64) {
                for (i = 0; i < 256; i++) {
-                       picasso96_state.CLUT[i].Red = restore_u8 ();
-                       picasso96_state.CLUT[i].Green = restore_u8 ();
-                       picasso96_state.CLUT[i].Blue = restore_u8 ();
+                       picasso96_state_uaegfx.CLUT[i].Red = restore_u8 ();
+                       picasso96_state_uaegfx.CLUT[i].Green = restore_u8 ();
+                       picasso96_state_uaegfx.CLUT[i].Blue = restore_u8 ();
                }
        }
-       picasso96_state.HostAddress = NULL;
+       picasso96_state_uaegfx.HostAddress = NULL;
        picasso_SetPanningInit();
-       picasso96_state.Extent = picasso96_state.Address + picasso96_state.BytesPerRow * picasso96_state.VirtualHeight;
+       picasso96_state_uaegfx.Extent = picasso96_state_uaegfx.Address + picasso96_state_uaegfx.BytesPerRow * picasso96_state_uaegfx.VirtualHeight;
        return src;
 }
 
@@ -5097,27 +5143,27 @@ uae_u8 *save_p96 (int *len, uae_u8 *dstptr)
        save_u32 ((picasso_on ? 1 : 0) | (set_gc_called ? 2 : 0) | (set_panning_called ? 4 : 0) |
                (hwsprite ? 8 : 0) | (cursorvisible ? 16 : 0) | (interrupt_enabled ? 32 : 0) | 64);
        save_u32 (currprefs.rtgboards[0].rtgmem_size);
-       save_u32 (picasso96_state.Address);
-       save_u32 (picasso96_state.RGBFormat);
-       save_u16 (picasso96_state.Width);
-       save_u16 (picasso96_state.Height);
-       save_u16 (picasso96_state.VirtualWidth);
-       save_u16 (picasso96_state.VirtualHeight);
-       save_u16 (picasso96_state.XOffset);
-       save_u16 (picasso96_state.YOffset);
-       save_u8 (picasso96_state.GC_Depth);
-       save_u8 (picasso96_state.GC_Flags);
-       save_u16 (picasso96_state.BytesPerRow);
-       save_u8 (picasso96_state.BytesPerPixel);
+       save_u32 (picasso96_state_uaegfx.Address);
+       save_u32 (picasso96_state_uaegfx.RGBFormat);
+       save_u16 (picasso96_state_uaegfx.Width);
+       save_u16 (picasso96_state_uaegfx.Height);
+       save_u16 (picasso96_state_uaegfx.VirtualWidth);
+       save_u16 (picasso96_state_uaegfx.VirtualHeight);
+       save_u16 (picasso96_state_uaegfx.XOffset);
+       save_u16 (picasso96_state_uaegfx.YOffset);
+       save_u8 (picasso96_state_uaegfx.GC_Depth);
+       save_u8 (picasso96_state_uaegfx.GC_Flags);
+       save_u16 (picasso96_state_uaegfx.BytesPerRow);
+       save_u8 (picasso96_state_uaegfx.BytesPerPixel);
        save_u32 (uaegfx_base);
        save_u32 (uaegfx_rom);
        save_u32 (boardinfo);
        for (i = 0; i < 4; i++)
                save_u32 (cursorrgb[i]);
        for (i = 0; i < 256; i++) {
-               save_u8 (picasso96_state.CLUT[i].Red);
-               save_u8 (picasso96_state.CLUT[i].Green);
-               save_u8 (picasso96_state.CLUT[i].Blue);
+               save_u8 (picasso96_state_uaegfx.CLUT[i].Red);
+               save_u8 (picasso96_state_uaegfx.CLUT[i].Green);
+               save_u8 (picasso96_state_uaegfx.CLUT[i].Blue);
        }
        *len = dst - dstbak;
        return dstbak;
index ea4c8ad679c4dc65e8b5c05a73a77200a68894b0..097c86e24deeaa04c7998284edaf3d52848f04ee 100644 (file)
@@ -558,10 +558,10 @@ extern void picasso_reset (void);
 extern bool picasso_is_active (void);
 extern int picasso_setwincursor (void);
 extern int picasso_palette (void);
-extern bool picasso_flushpixels (uae_u8 *src, int offset);
-extern void picasso_allocatewritewatch (int gfxmemsize);
-extern void picasso_getwritewatch (int offset);
-extern bool picasso_is_vram_dirty (uaecptr addr, int size);
+extern bool picasso_flushpixels (int index, uae_u8 *src, int offset);
+extern void picasso_allocatewritewatch (int index, int gfxmemsize);
+extern void picasso_getwritewatch (int index, int offset);
+extern bool picasso_is_vram_dirty (int index, uaecptr addr, int size);
 extern void picasso_statusline (uae_u8 *dst);
 extern void picasso_invalidate (int x, int y, int w, int h);
 
index 045c50876586e6b63e019392f7239ac3e7b71ed1..60ad8b63a84584e734c4bf773ef3ab1c89bdb042 100644 (file)
@@ -30,6 +30,7 @@
 #define IDS_EXPANSION                   22
 #define IDS_STRING23                    23
 #define IDS_EXPANSION2                  23
+#define IDS_BOARD                       24
 #define IDS_EXTTEXT                     100
 #define IDS_EXTACTUAL                   101
 #define IDS_SOUND                       102
 #define IDS_SLIRP                       398
 #define IDD_EXPANSION2                  398
 #define IDS_SLIRP_INBOUND               399
+#define IDD_DIALOG2                     399
+#define IDD_BOARDS                      399
 #define IDS_FILTER_PAL_EXTRA            400
 #define IDS_FILTER_3D_EXTRA             401
 #define IDS_ALWAYS_ON                   402
 #define IDC_PORT1_JOYS                  1027
 #define IDC_SCREENMODE_RTG              1027
 #define IDC_DONGLELIST                  1027
-#define IDC_MBMEM1                      1028
 #define IDC_PORT_TABLET_CURSOR          1028
 #define IDC_SAMPLERLIST                 1028
 #define IDC_DISPLAY_BUFFERCNT           1028
+#define IDC_MEMORYMEM                   1028
 #define IDC_PORT0_JOYSMODE              1029
 #define IDC_SCREENMODE_NATIVE2          1029
-#define IDC_FASTMEM2                    1029
 #define IDC_SLOWMEM                     1030
 #define IDC_PORT1_JOYSMODE              1030
 #define IDC_SCREENMODE_RTG2             1030
-#define IDC_MBMEM2                      1031
 #define IDC_PORT2_JOYS                  1031
 #define IDC_PORT3_JOYS                  1032
 #define IDC_PARALLEL                    1033
 #define IDC_CHIPRAM                     1045
 #define IDC_SLOWRAM                     1046
 #define IDC_Z3TEXT                      1047
-#define IDC_FASTRAM2                    1047
 #define IDC_Z3FASTRAM                   1048
 #define IDC_Z3FASTMEM                   1049
-#define IDC_MBRAM1                      1050
-#define IDC_MBRAM2                      1051
+#define IDC_MEMORYRAM                   1050
 #define IDC_Z3CHIPMEM                   1052
 #define IDC_Z3CHIPRAM                   1053
 #define IDC_MAX32RAM                    1054
 #define IDC_ACCELERATORBOARDCHECKBOX    1617
 #define IDC_AVIOUTPUT_AUDIO_STATIC      1618
 #define IDC_FILTERHO                    1618
+#define IDC_NE2001                      1618
+#define IDC_NE2000PCMCIA                1618
 #define IDC_AVIOUTPUT_VIDEO_STATIC      1619
 #define IDC_FILTERVO                    1619
 #define IDC_AVIOUTPUT_8BIT              1620
 #define IDC_CS_DMAC2                    1769
 #define IDC_CS_CDTVSCSI                 1771
 #define IDC_CS_CD32FMV                  1771
-#define IDC_CS_SCSIMODE                 1772
 #define IDC_DF0ENABLE                   1773
-#define IDC_CS_TOCCATA                  1773
 #define IDC_DF1ENABLE                   1774
 #define IDC_FS_SELECT_DIR               1774
-#define IDC_CS_TOCCATAMIXER             1774
 #define IDC_FS_SELECT_FILE              1775
 #define IDC_FLOPPY_FFS                  1775
-#define IDC_CS_ES1370                   1775
 #define IDC_DF2ENABLE                   1776
 #define IDC_FS_SELECT_EJECT             1776
-#define IDC_CS_FM801                    1776
 #define IDC_FS_RW                       1777
 #define IDC_FLOPPY_BOOTABLE             1777
 #define IDC_DF3ENABLE                   1778
 #define IDC_RTG_SCALE_ALLOW2            1798
 #define IDC_RTG_CENTER                  1798
 #define IDC_PORT0_REMAP                 1799
+#define IDC_RTG_Z2Z4                    1799
+#define IDC_RTG_NUM                     1799
 #define IDC_PORT2_REMAP                 1800
 #define IDC_PORT3_REMAP                 1801
 #define IDC_INPUTMAPOUT                 1801
 #define IDC_CD_TEXT                     1805
 #define IDC_CD_TYPE                     1806
 #define IDC_CD_SELECT                   1807
-#define IDC_FASTMEMAUTOCONFIG           1808
 #define IDC_RTG_DISPLAYSELECT           1809
+#define IDC_FASTMEMAUTOCONFIGUSE        1809
 #define IDC_MISCLIST                    1810
 #define IDC_STATENAME                   1811
 #define IDC_SAMPLER_STEREO              1812
 #define IDC_CPUBOARDMEM                 1843
 #define IDC_Z3MAPPING                   1844
 #define IDC_CPUBOARD_SUBTYPE            1845
+#define IDC_Z3MAPPING2                  1845
+#define IDC_MEMORYSELECT                1845
 #define IDC_CYCLEEXACTMEMORY            1846
 #define IDC_UAEBOARD_TYPE               1848
+#define IDC_AUTOCONFIG_MANUFACTURER     1849
+#define IDC_AUTOCONFIG_PRODUCT          1850
+#define IDC_BOARDLIST                   1850
+#define IDC_AUTOCONFIG_DATA             1851
+#define IDC_AUTOCONFIGCUSTOMSORT        1851
+#define IDC_BOARDS_DOWN                 1852
+#define IDC_BOARDS_UP                   1853
 #define ID__FLOPPYDRIVES                40004
 #define ID_FLOPPYDRIVES_DF0             40005
 #define ID_ST_CONFIGURATION             40010
 #ifndef APSTUDIO_READONLY_SYMBOLS
 #define _APS_NO_MFC                     1
 #define _APS_3D_CONTROLS                     1
-#define _APS_NEXT_RESOURCE_VALUE        399
+#define _APS_NEXT_RESOURCE_VALUE        400
 #define _APS_NEXT_COMMAND_VALUE         40050
-#define _APS_NEXT_CONTROL_VALUE         1849
+#define _APS_NEXT_CONTROL_VALUE         1853
 #define _APS_NEXT_SYMED_VALUE           101
 #endif
 #endif
index c5c699c0e98c396f956edea9e9e259e92afba626..a480b43e965abacff801e6d7605d3470ea4282c7 100644 (file)
@@ -102,6 +102,17 @@ END
 // Dialog
 //
 
+IDD_BOARDS DIALOGEX 0, 0, 396, 259
+STYLE DS_LOCALEDIT | DS_SETFONT | DS_3DLOOK | DS_CONTROL | WS_CHILD
+EXSTYLE WS_EX_CONTEXTHELP
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+    CONTROL         "",IDC_BOARDLIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,2,18,390,220
+    CONTROL         "Custom board order",IDC_AUTOCONFIGCUSTOMSORT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,2,242,99,12
+    PUSHBUTTON      "Move down",IDC_BOARDS_DOWN,203,241,78,14
+    PUSHBUTTON      "Move up",IDC_BOARDS_UP,114,241,78,14
+END
+
 IDD_KICKSTART DIALOGEX 0, 0, 396, 259
 STYLE DS_LOCALEDIT | DS_SETFONT | DS_3DLOOK | DS_CONTROL | WS_CHILD
 EXSTYLE WS_EX_CONTEXTHELP
@@ -194,7 +205,7 @@ BEGIN
     CONTROL         "Monochrome video out",IDC_GRAYSCALE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,167,139,10
 END
 
-IDD_MEMORY DIALOGEX 0, 0, 396, 246
+IDD_MEMORY DIALOGEX 0, 0, 396, 247
 STYLE DS_LOCALEDIT | DS_SETFONT | DS_3DLOOK | DS_CONTROL | WS_CHILD
 EXSTYLE WS_EX_CONTEXTHELP
 FONT 8, "MS Sans Serif", 0, 0, 0x1
@@ -216,19 +227,19 @@ BEGIN
     CONTROL         "",IDC_Z3CHIPMEM,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,248,71,60,20
     EDITTEXT        IDC_Z3CHIPRAM,311,76,40,12,ES_CENTER | ES_READONLY
     EDITTEXT        IDC_MAX32RAM,14,99,366,12,ES_CENTER | ES_READONLY
-    GROUPBOX        "Advanced Memory Settings",IDC_STATIC,1,134,393,107
-    RTEXT           "Motherboard Fast:",IDC_STATIC,116,149,129,10,SS_CENTERIMAGE
-    CONTROL         "",IDC_MBMEM1,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,251,145,68,20
-    EDITTEXT        IDC_MBRAM1,326,148,40,12,ES_CENTER | ES_READONLY
-    RTEXT           "Processor Slot Fast:",IDC_STATIC,116,172,129,10,SS_CENTERIMAGE
-    CONTROL         "",IDC_MBMEM2,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,251,168,68,20
-    EDITTEXT        IDC_MBRAM2,326,171,40,12,ES_CENTER | ES_READONLY
-    RTEXT           "Second Z2 Fast RAM board:",IDC_STATIC,129,194,116,15,SS_CENTERIMAGE
-    CONTROL         "",IDC_FASTMEM2,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,251,193,68,20
-    EDITTEXT        IDC_FASTRAM2,326,196,40,12,ES_CENTER | ES_READONLY
-    RTEXT           "Z3 mapping mode:",IDC_STATIC,149,219,93,15,SS_CENTERIMAGE
-    COMBOBOX        IDC_Z3MAPPING,249,220,117,75,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
-    CONTROL         "Autoconfig Z2 Fast RAM",IDC_FASTMEMAUTOCONFIG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,194,120,10
+    GROUPBOX        "Advanced Memory Settings",IDC_STATIC,1,128,393,115
+    CONTROL         "",IDC_MEMORYMEM,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,253,145,68,20
+    EDITTEXT        IDC_MEMORYRAM,328,148,40,12,ES_CENTER | ES_READONLY
+    RTEXT           "Z3 mapping mode:",IDC_STATIC,162,218,93,15,SS_CENTERIMAGE
+    COMBOBOX        IDC_Z3MAPPING,262,218,117,75,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+    COMBOBOX        IDC_MEMORYSELECT,14,151,228,75,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+    EDITTEXT        IDC_AUTOCONFIG_MANUFACTURER,78,175,45,13,ES_AUTOHSCROLL
+    EDITTEXT        IDC_AUTOCONFIG_PRODUCT,196,175,45,13,ES_AUTOHSCROLL
+    EDITTEXT        IDC_AUTOCONFIG_DATA,78,194,164,13,ES_AUTOHSCROLL
+    RTEXT           "Manufacturer",IDC_STATIC,12,175,57,15,SS_CENTERIMAGE
+    RTEXT           "Product",IDC_STATIC,133,175,55,15,SS_CENTERIMAGE
+    RTEXT           "Autoconfig data",IDC_STATIC,11,195,57,15,SS_CENTERIMAGE
+    CONTROL         "Edit Autoconfig data",IDC_FASTMEMAUTOCONFIGUSE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,276,196,103,10
 END
 
 IDD_CPU DIALOGEX 0, 0, 396, 317
@@ -421,16 +432,18 @@ BEGIN
     COMBOBOX        IDC_SOUNDFILTER,279,186,96,75,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
     GROUPBOX        "Floppy Drive Sound Emulation",IDC_STATIC,1,209,278,91
     CONTROL         "",IDC_SOUNDDRIVEVOLUME,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,20,227,107,19
-    EDITTEXT        IDC_SOUNDDRIVEVOLUME2,144,231,48,12,ES_CENTER | ES_READONLY
+    EDITTEXT        IDC_SOUNDDRIVEVOLUME2,145,231,48,12,ES_CENTER | ES_READONLY
     CONTROL         "",IDC_SOUNDDRIVEVOLUMEX,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,20,254,107,19
-    EDITTEXT        IDC_SOUNDDRIVEVOLUMEX2,144,258,48,12,ES_CENTER | ES_READONLY
-    COMBOBOX        IDC_SOUNDDRIVE,205,231,66,75,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
-    COMBOBOX        IDC_SOUNDDRIVESELECT,18,281,253,75,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+    EDITTEXT        IDC_SOUNDDRIVEVOLUMEX2,145,258,48,12,ES_CENTER | ES_READONLY
+    COMBOBOX        IDC_SOUNDDRIVE,205,281,66,75,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+    COMBOBOX        IDC_SOUNDDRIVESELECT,18,281,175,75,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
     GROUPBOX        "Drivers",IDC_STATIC,285,213,109,87
     CONTROL         "DirectSound",IDC_SOUND_DS,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,292,234,98,10
     CONTROL         "WASAPI",IDC_SOUND_WASAPI,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,292,248,98,10
     CONTROL         "OpenAL",IDC_SOUND_OPENAL,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,292,262,98,10
     CONTROL         "PortAudio",IDC_SOUND_PORTAUDIO,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,292,276,98,10
+    LTEXT           "Disk in drive",IDC_STATIC,208,231,60,15,SS_CENTERIMAGE
+    LTEXT           "Empty drive",IDC_STATIC,208,258,60,15,SS_CENTERIMAGE
 END
 
 IDD_LOADSAVE DIALOGEX 0, 0, 396, 318
@@ -555,7 +568,6 @@ BEGIN
     PUSHBUTTON      "Contributors",IDC_CONTRIBUTORS,132,100,80,15
     CONTROL         "",IDC_AMIGAHOME,"RICHEDIT",TCS_SCROLLOPPOSITE | TCS_RAGGEDRIGHT | TCS_MULTISELECT | WS_DISABLED,116,168,112,24
     CONTROL         "",IDC_WINUAEHOME,"RICHEDIT",TCS_SCROLLOPPOSITE | TCS_RAGGEDRIGHT | TCS_MULTISELECT | WS_DISABLED,231,168,112,24
-    CONTROL         "",IDC_THEROOTS,"RICHEDIT",TCS_SCROLLOPPOSITE | TCS_RAGGEDRIGHT | TCS_MULTISELECT | WS_DISABLED,117,225,112,24
     CONTROL         "",IDC_CAPS,"RICHEDIT",TCS_SCROLLOPPOSITE | TCS_RAGGEDRIGHT | TCS_MULTISELECT | WS_DISABLED,174,196,112,24
     CONTROL         "",IDC_ABIME,"RICHEDIT",TCS_SCROLLOPPOSITE | TCS_RAGGEDRIGHT | TCS_MULTISELECT | WS_DISABLED,60,196,112,24
     CONTROL         "",IDC_CLOANTOHOME,"RICHEDIT",TCS_SCROLLOPPOSITE | TCS_RAGGEDRIGHT | TCS_MULTISELECT | WS_DISABLED,2,168,112,24
@@ -1147,11 +1159,11 @@ BEGIN
     CONTROL         "Hardware vertical blank interrupt",IDC_RTG_VBINTERRUPT,
                     "Button",BS_AUTOCHECKBOX | WS_TABSTOP,25,106,157,10
     CONTROL         "Hardware sprite emulation",IDC_RTG_HWSPRITE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,207,106,148,10
-    CTEXT           "Color modes:",IDC_STATIC,295,9,83,10,SS_CENTERIMAGE
-    COMBOBOX        IDC_RTG_8BIT,296,23,82,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
-    COMBOBOX        IDC_RTG_16BIT,296,40,82,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
-    COMBOBOX        IDC_RTG_24BIT,296,58,82,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
-    COMBOBOX        IDC_RTG_32BIT,296,75,82,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
+    CTEXT           "Color modes:",IDC_STATIC,295,18,83,10,SS_CENTERIMAGE
+    COMBOBOX        IDC_RTG_8BIT,296,33,82,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
+    COMBOBOX        IDC_RTG_16BIT,296,50,82,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
+    COMBOBOX        IDC_RTG_24BIT,296,68,82,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
+    COMBOBOX        IDC_RTG_32BIT,296,85,82,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
     COMBOBOX        IDC_RTG_DISPLAYSELECT,11,125,371,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
     CTEXT           "Refresh rate:",IDC_STATIC,30,149,83,10,SS_CENTERIMAGE
     COMBOBOX        IDC_RTG_VBLANKRATE,29,162,84,150,CBS_DROPDOWN | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
@@ -1159,6 +1171,7 @@ BEGIN
     COMBOBOX        IDC_RTG_BUFFERCNT,153,162,84,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
     CTEXT           "Aspect ratio:",IDC_STATIC,282,149,83,10,SS_CENTERIMAGE
     COMBOBOX        IDC_RTG_SCALE_ASPECTRATIO,282,162,84,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
+    COMBOBOX        IDC_RTG_NUM,248,14,37,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
 END
 
 IDD_INPUTMAP DIALOGEX 0, 0, 421, 341
@@ -1243,56 +1256,50 @@ BEGIN
     EDITTEXT        IDC_DISKINFOBOX,5,4,481,292,ES_MULTILINE | ES_READONLY | WS_VSCROLL
 END
 
-IDD_EXPANSION2 DIALOGEX 0, 0, 396, 315
+IDD_EXPANSION2 DIALOGEX 0, 0, 396, 287
 STYLE DS_LOCALEDIT | DS_SETFONT | DS_3DLOOK | DS_CONTROL | WS_CHILD
 FONT 8, "MS Sans Serif", 0, 0, 0x1
 BEGIN
-    RTEXT           "Accelerator board memory:",IDC_STATIC,155,144,104,15,SS_CENTERIMAGE
-    CONTROL         "",IDC_CPUBOARDMEM,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,269,141,68,20
-    EDITTEXT        IDC_CPUBOARDRAM,343,146,40,12,ES_CENTER | ES_READONLY
-    COMBOBOX        IDC_CPUBOARD_TYPE,13,117,117,75,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
-    COMBOBOX        IDC_CPUBOARD_SUBTYPE,13,136,117,75,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+    RTEXT           "Accelerator board memory:",IDC_STATIC,155,145,104,15,SS_CENTERIMAGE
+    CONTROL         "",IDC_CPUBOARDMEM,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,269,143,68,20
+    EDITTEXT        IDC_CPUBOARDRAM,343,147,40,12,ES_CENTER | ES_READONLY
+    COMBOBOX        IDC_CPUBOARD_TYPE,13,118,117,75,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+    COMBOBOX        IDC_CPUBOARD_SUBTYPE,13,137,117,75,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
     GROUPBOX        "Expansion Board Settings",IDC_STATIC,1,6,394,88
     COMBOBOX        IDC_SCSIROMSELECTNUM,175,42,22,75,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
     COMBOBOX        IDC_SCSIROMSELECT,12,42,157,75,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
     CONTROL         "Autoboot disabled",IDC_SCSIROMFILEAUTOBOOT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,202,62,99,12
-    RTEXT           "SCSI controller ID:",IDC_STATIC,241,23,110,15,SS_CENTERIMAGE
+    RTEXT           "Controller ID:",IDC_STATIC,241,23,110,15,SS_CENTERIMAGE
     COMBOBOX        IDC_SCSIROMID,356,24,29,75,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
     COMBOBOX        IDC_SCSIROMFILE,202,42,171,75,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
     PUSHBUTTON      "...",IDC_SCSIROMCHOOSER,376,42,10,15
     COMBOBOX        IDC_SCSIROMSUBSELECT,12,59,157,75,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
-    LTEXT           "Accelerator board ROM file:",IDC_STATIC,203,104,170,15,SS_CENTERIMAGE
-    COMBOBOX        IDC_CPUBOARDROMFILE,202,119,169,75,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
+    LTEXT           "Accelerator board ROM file:",IDC_STATIC,203,105,170,15,SS_CENTERIMAGE
+    COMBOBOX        IDC_CPUBOARDROMFILE,202,120,169,75,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
     PUSHBUTTON      "...",IDC_CPUBOARDROMCHOOSER,376,119,10,15
-    GROUPBOX        "Accelerator Board Settings",IDC_STATIC,1,96,394,97
-    GROUPBOX        "Miscellaneous Expansions",IDC_STATIC,1,199,172,113
-    CONTROL         "Catweasel Z2 emulation [] Catweasel MK2 Zorro II card emulation. Physical Windows compatible Catweasel card and drivers required.",IDC_CATWEASEL,
-                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,218,147,11
-    CONTROL         "uaescsi.device",IDC_SCSIDEVICE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,231,147,11
-    CONTROL         "CD32 Full Motion Video cartridge",IDC_CS_CD32FMV,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,244,151,11
-    CONTROL         "Toccata Z2 sound card emulation",IDC_CS_TOCCATA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,257,151,11
-    CONTROL         "Toccata Paula/CD audio mix",IDC_CS_TOCCATAMIXER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,270,151,11
-    GROUPBOX        "Network",IDC_STATIC,181,199,213,113
+    GROUPBOX        "Accelerator Board Settings",IDC_STATIC,1,97,394,91
+    GROUPBOX        "Miscellaneous Expansions",IDC_STATIC,1,255,394,28
+    CONTROL         "uaescsi.device",IDC_SCSIDEVICE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,266,147,11
+    CONTROL         "CD32 Full Motion Video cartridge",IDC_CS_CD32FMV,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,193,266,151,11
+    GROUPBOX        "Network",IDC_STATIC,0,192,395,61
     CONTROL         "bsdsocket.library [] bsdsocket network library emulation.",IDC_SOCKETS,
-                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,202,217,187,11
+                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,204,187,11
     CONTROL         "uaenet.device [] Sana 2 compatible network device emulation.",IDC_SANA2,
-                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,202,231,187,11
+                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,193,204,187,11
     CONTROL         "A2065 Z2 [] A2065 Ethernet Zorro II card emulation.",IDC_A2065,
-                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,202,244,187,11
-    COMBOBOX        IDC_NETDEVICE,202,274,178,65,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
-    CONTROL         "Include host SCSI devices",IDC_CS_SCSIMODE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,202,296,147,11
+                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,218,187,11
+    COMBOBOX        IDC_NETDEVICE,193,232,178,65,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
     CONTROL         "Realtek 8029 PCI [] Realtek 8029 PCI NIC emulation",IDC_NE2000,
-                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,202,257,187,11
+                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,193,219,187,11
     CONTROL         "Enabled",IDC_SCSIROMSELECTED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,202,43,99,12
     COMBOBOX        IDC_SCSIROMSELECTCAT,12,23,157,75,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
-    CONTROL         "ES1370 PCI sound card",IDC_CS_ES1370,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,283,151,11
-    CONTROL         "FM801 PCI sound card",IDC_CS_FM801,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,296,151,11
     COMBOBOX        IDC_EXPANSIONBOARDITEMSELECTOR,12,76,157,75,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
     CONTROL         "",IDC_EXPANSIONBOARDCHECKBOX,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,202,76,99,12
     COMBOBOX        IDC_EXPANSIONBOARDSELECTOR,202,76,171,75,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
-    COMBOBOX        IDC_ACCELERATORBOARDITEMSELECTOR,12,168,157,75,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
-    CONTROL         "",IDC_ACCELERATORBOARDCHECKBOX,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,202,169,99,12
-    COMBOBOX        IDC_ACCELERATORBOARDSELECTOR,202,169,171,75,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
+    COMBOBOX        IDC_ACCELERATORBOARDITEMSELECTOR,12,169,157,75,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
+    CONTROL         "",IDC_ACCELERATORBOARDCHECKBOX,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,202,170,99,12
+    COMBOBOX        IDC_ACCELERATORBOARDSELECTOR,202,146,171,75,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
+    CONTROL         "NE2000 PCMCIA",IDC_NE2000PCMCIA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,233,187,11
 END
 
 
@@ -1302,8 +1309,8 @@ END
 //
 
 VS_VERSION_INFO VERSIONINFO
- FILEVERSION 3,3,0,0
- PRODUCTVERSION 3,3,0,0
+ FILEVERSION 3,3,1,0
+ PRODUCTVERSION 3,3,1,0
  FILEFLAGSMASK 0x3fL
 #ifdef _DEBUG
  FILEFLAGS 0x1L
@@ -1319,12 +1326,12 @@ BEGIN
         BLOCK "040904b0"
         BEGIN
             VALUE "FileDescription", "WinUAE"
-            VALUE "FileVersion", "3.3.0.0"
+            VALUE "FileVersion", "3.3.1.0"
             VALUE "InternalName", "WinUAE"
             VALUE "LegalCopyright", "© 1996-2016 under the GNU Public License (GPL)"
             VALUE "OriginalFilename", "WinUAE.exe"
             VALUE "ProductName", "WinUAE"
-            VALUE "ProductVersion", "3.3.0.0"
+            VALUE "ProductVersion", "3.3.1.0"
         END
     END
     BLOCK "VarFileInfo"
@@ -1454,6 +1461,10 @@ IDB_LCD160X43           BITMAP                  "lcd.bmp"
 #ifdef APSTUDIO_INVOKED
 GUIDELINES DESIGNINFO
 BEGIN
+    IDD_BOARDS, DIALOG
+    BEGIN
+    END
+
     IDD_KICKSTART, DIALOG
     BEGIN
         BOTTOMMARGIN, 258
@@ -1626,6 +1637,31 @@ END
 #endif    // APSTUDIO_INVOKED
 
 
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE 
+BEGIN
+    "resource.h\0"
+END
+
+2 TEXTINCLUDE 
+BEGIN
+    "\0"
+END
+
+3 TEXTINCLUDE 
+BEGIN
+    "\r\n"
+    "\0"
+END
+
+#endif    // APSTUDIO_INVOKED
+
+
 /////////////////////////////////////////////////////////////////////////////
 //
 // String Table
@@ -1660,6 +1696,7 @@ BEGIN
     IDS_GAMEPORTS           "Game ports"
     IDS_EXPANSION           "RTG board"
     IDS_EXPANSION2          "Expansions"
+    IDS_BOARD               "Hardware info"
 END
 
 STRINGTABLE
@@ -2011,7 +2048,7 @@ BEGIN
     IDS_WSTYLE_STANDARD     "Standard"
     IDS_WSTYLE_EXTENDED     "Extended"
     IDS_MISCLISTITEMS1      "Untrap = middle button\nShow GUI on startup\nUse CTRL-F11 to quit\nDon't show taskbar button\nDon't show notification icon\n"
-    IDS_MISCLISTITEMS2      "Always on top\nDisable screensaver\nSynchronize clock\nOne second reboot pause\nFaster RTG\nClipboard sharing\nAllow native code\n"
+    IDS_MISCLISTITEMS2      "Main window always on top\nGUI window always on top\nDisable screensaver\nSynchronize clock\nOne second reboot pause\nFaster RTG\nClipboard sharing\nAllow native code\n"
     IDS_MISCLISTITEMS3      "Native on-screen display\nRTG on-screen display\nCreate winuaelog.txt log\nLog illegal memory accesses\nBlank unused displays\nStart mouse uncaptured\nStart minimized\nMinimize when focus is lost\nBlack frame insertion\nMaster floppy write protection\nMaster harddrive write protection\nHide all UAE autoconfig boards\n"
     IDS_JOYMODE_WHEELMOUSE  "Wheel Mouse"
     IDS_NUMSG_KS68030PLUS   "The selected system ROM requires a 68030 or higher CPU."
@@ -2043,41 +2080,6 @@ END
 /////////////////////////////////////////////////////////////////////////////
 
 
-/////////////////////////////////////////////////////////////////////////////
-// Finnish (Finland) resources
-
-#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_FIN)
-LANGUAGE LANG_FINNISH, SUBLANG_DEFAULT
-#pragma code_page(1252)
-
-#ifdef APSTUDIO_INVOKED
-/////////////////////////////////////////////////////////////////////////////
-//
-// TEXTINCLUDE
-//
-
-1 TEXTINCLUDE 
-BEGIN
-    "resource.h\0"
-END
-
-2 TEXTINCLUDE 
-BEGIN
-    "\0"
-END
-
-3 TEXTINCLUDE 
-BEGIN
-    "\r\n"
-    "\0"
-END
-
-#endif    // APSTUDIO_INVOKED
-
-#endif    // Finnish (Finland) resources
-/////////////////////////////////////////////////////////////////////////////
-
-
 
 #ifndef APSTUDIO_INVOKED
 /////////////////////////////////////////////////////////////////////////////
index e69bbc3687453d8dece5f0e404a8d4a32ee3013b..eb4f326dce9f390748c0bae85661465822ed7b0d 100644 (file)
@@ -10,7 +10,6 @@
 
 #include "sysconfig.h"
 #include "sysdeps.h"
-#include "rp.h"
 #include "options.h"
 #include "uae.h"
 #include "inputdevice.h"
@@ -33,6 +32,7 @@
 #include "drawing.h"
 #include "resource.h"
 #include "gui.h"
+#include "rp.h"
 
 static int initialized;
 static RPGUESTINFO guestinfo;
@@ -658,7 +658,7 @@ static void get_screenmode (struct RPScreenMode *sm, struct uae_prefs *p, bool g
        if (full > 1)
                m |= RP_SCREENMODE_FULLSCREEN_SHARED;
 
-       sm->dwScreenMode = m  | (storeflags & (RP_SCREENMODE_SCALING_STRETCH | RP_SCREENMODE_SCALING_SUBPIXEL));
+       sm->dwScreenMode = m | (storeflags & (RP_SCREENMODE_SCALING_STRETCH | RP_SCREENMODE_SCALING_SUBPIXEL));
        sm->lTargetHeight = 0;
        sm->lTargetWidth = 0;
        if ((storeflags & RP_SCREENMODE_SCALEMASK) == RP_SCREENMODE_SCALE_MAX) {
@@ -1193,6 +1193,16 @@ static LRESULT CALLBACK RPHostMsgFunction (UINT uMessage, WPARAM wParam, LPARAM
        return lr;
 }
 
+void rp_keymap(TrapContext *ctx, uaecptr ptr, uae_u32 size)
+{
+       uae_u8 *p = xmalloc(uae_u8, size);
+       if (p && size) {
+               trap_get_bytes(ctx, p, ptr, size);
+               RPSendMessagex(RP_IPC_TO_HOST_KEYBOARDLAYOUT, 0, 0, p, size, &guestinfo, NULL);
+       }
+       xfree(p);
+}
+
 static int rp_hostversion (int *ver, int *rev, int *build)
 {
        LRESULT lr = 0;
@@ -1683,7 +1693,7 @@ static void rp_mouse (void)
        if (!cando ())
                return;
        if (mousemagic)
-               flags |= RP_MOUSECAPTURE_MAGICMOUSE;
+               flags |= RP_MOUSECAPTURE_INTEGRATED;
        if (mousecapture)
                flags |= RP_MOUSECAPTURE_CAPTURED;
        RPSendMessagex (RP_IPC_TO_HOST_MOUSECAPTURE, flags, 0, NULL, 0, &guestinfo, NULL);
index 385a3d43b51704d11ede51f0226071cb6ebf5a1d..9bdbc6d60c0373892aed67df6e45b00a4d0abda5 100644 (file)
@@ -18,6 +18,7 @@ extern void rp_vsync (void);
 extern HWND rp_getparent (void);
 extern void rp_rtg_switch (void);
 extern void rp_screenmode_changed (void);
+extern void rp_keymap(TrapContext*, uaecptr, uae_u32);
 
 extern TCHAR *rp_param;
 extern int rp_rpescapekey;
index c678024908fad8eba6cbdfaa25d0f5c0fc74d06f..80189a0e2d340ccc82374a734f6b10125568e70a 100644 (file)
@@ -99,16 +99,19 @@ struct sound_dp
        IAudioRenderClient *pRenderClient;
        ISimpleAudioVolume *pAudioVolume;
        IMMDeviceEnumerator *pEnumerator;
-#if 0
        IAudioClock *pAudioClock;
        UINT64 wasapiclock;
-#endif
        REFERENCE_TIME hnsRequestedDuration;
        UINT32 bufferFrameCount;
        UINT64 wasapiframes;
        int wasapiexclusive;
+       int wasapipull;
        int sndbuf;
        int wasapigoodsize;
+       HANDLE wasapievent;
+       uae_u8 *wasapibuffer;
+       int wasapibufferlen;
+       int wasapibuffermaxlen;
 
 #if USE_XAUDIO
        // xaudio2
@@ -145,7 +148,7 @@ static int have_sound;
 static int statuscnt;
 
 #define SND_MAX_BUFFER2 524288
-#define SND_MAX_BUFFER 8192
+#define SND_MAX_BUFFER 65536
 
 uae_u16 paula_sndbuffer[SND_MAX_BUFFER];
 uae_u16 *paula_sndbufpt;
@@ -164,6 +167,8 @@ static uae_u8 *extrasndbuf;
 static int extrasndbufsize;
 static int extrasndbuffered;
 
+static int sound_pull = 1;
+
 int setup_sound (void)
 {
        sound_available = 1;
@@ -347,8 +352,11 @@ static void pause_audio_wasapi (struct sound_data *sd)
        HRESULT hr;
 
        hr = s->pAudioClient->Stop ();
-       if (FAILED (hr))
+       if (FAILED (hr)) {
                write_log (_T("WASAPI: Stop() %08X\n"), hr);
+       }
+       if (s->wasapievent)
+               ResetEvent(s->wasapievent);
 }
 static void resume_audio_wasapi (struct sound_data *sd)
 {
@@ -357,17 +365,26 @@ static void resume_audio_wasapi (struct sound_data *sd)
        BYTE *pData;
        int framecnt;
 
+       if (s->wasapievent)
+               ResetEvent(s->wasapievent);
        hr = s->pAudioClient->Reset ();
-       if (FAILED (hr))
+       if (FAILED (hr)) {
                write_log (_T("WASAPI: Reset() %08X\n"), hr);
+       }
        framecnt = s->wasapigoodsize;
        hr = s->pRenderClient->GetBuffer (framecnt, &pData);
-       if (FAILED (hr))
+       if (FAILED (hr)) {
+               write_log(_T("WASAPI: Resume GetBuffer() %08X\n"), hr);
                return;
+       }
        hr = s->pRenderClient->ReleaseBuffer (framecnt, AUDCLNT_BUFFERFLAGS_SILENT);
+       if (FAILED(hr)) {
+               write_log(_T("WASAPI: Resume ReleaseBuffer() %08X\n"), hr);
+       }
        hr = s->pAudioClient->Start ();
-       if (FAILED (hr))
+       if (FAILED (hr)) {
                write_log (_T("WASAPI: Start() %08X\n"), hr);
+       }
        s->wasapiframes = 0;
        s->sndbuf = 0;
 }
@@ -1067,16 +1084,20 @@ static void close_audio_wasapi (struct sound_data *sd)
                s->pRenderClient->Release ();
        if (s->pAudioVolume)
                s->pAudioVolume->Release ();
-#if 0
        if (s->pAudioClock)
                s->pAudioClock->Release ();
-#endif
        if (s->pAudioClient)
                s->pAudioClient->Release ();
        if (s->pDevice)
                s->pDevice->Release ();
        if (s->pEnumerator)
                s->pEnumerator->Release ();
+       if (s->wasapievent) {
+               CloseHandle(s->wasapievent);
+               s->wasapievent = NULL;
+       }
+       xfree(s->wasapibuffer);
+       s->wasapibuffer = NULL;
 }
 
 static int open_audio_wasapi (struct sound_data *sd, int index, int exclusive)
@@ -1094,12 +1115,17 @@ static int open_audio_wasapi (struct sound_data *sd, int index, int exclusive)
 
        sd->devicetype = exclusive ? SOUND_DEVICE_WASAPI_EXCLUSIVE : SOUND_DEVICE_WASAPI;
        s->wasapiexclusive = exclusive;
+       s->wasapipull = sound_pull;
 
        if (s->wasapiexclusive)
                sharemode = AUDCLNT_SHAREMODE_EXCLUSIVE;
        else
                sharemode = AUDCLNT_SHAREMODE_SHARED;
 
+       if (s->wasapipull) {
+               s->wasapievent = CreateEvent(NULL, TRUE, FALSE, NULL);
+       }
+
        hr = CoCreateInstance (__uuidof(MMDeviceEnumerator), NULL,
                CLSCTX_ALL, __uuidof(IMMDeviceEnumerator),
                (void**)&s->pEnumerator);
@@ -1214,7 +1240,12 @@ static int open_audio_wasapi (struct sound_data *sd, int index, int exclusive)
                sd->freq = pwfx_saved->nSamplesPerSec;
        }
 
+       int tmp_sndbufsize = sd->sndbufsize;
+
        sd->samplesize = sd->channels * 16 / 8;
+       if (sd->sndbufsize > SND_MAX_BUFFER)
+               sd->sndbufsize = SND_MAX_BUFFER;
+
        s->snd_configsize = sd->sndbufsize * sd->samplesize;
 
        s->bufferFrameCount = (UINT32)( // frames =
@@ -1236,7 +1267,7 @@ static int open_audio_wasapi (struct sound_data *sd, int index, int exclusive)
                        );
        }
 
-       hr = s->pAudioClient->Initialize (sharemode, AUDCLNT_STREAMFLAGS_NOPERSIST,
+       hr = s->pAudioClient->Initialize (sharemode, AUDCLNT_STREAMFLAGS_NOPERSIST | (s->wasapipull ? AUDCLNT_STREAMFLAGS_EVENTCALLBACK : 0),
                s->hnsRequestedDuration, s->wasapiexclusive ? s->hnsRequestedDuration : 0, pwfx ? pwfx : &wavfmt.Format, NULL);
        if (hr == AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED) {
                hr = s->pAudioClient->GetBufferSize (&s->bufferFrameCount);
@@ -1259,7 +1290,7 @@ static int open_audio_wasapi (struct sound_data *sd, int index, int exclusive)
                        write_log (_T("WASAPI: Activate() %08X\n"), hr);
                        goto error;
                }
-               hr = s->pAudioClient->Initialize (sharemode, AUDCLNT_STREAMFLAGS_NOPERSIST,
+               hr = s->pAudioClient->Initialize (sharemode, AUDCLNT_STREAMFLAGS_NOPERSIST | (s->wasapipull ? AUDCLNT_STREAMFLAGS_EVENTCALLBACK : 0),
                        s->hnsRequestedDuration, s->wasapiexclusive ? s->hnsRequestedDuration : 0, pwfx ? pwfx : &wavfmt.Format, NULL);
        }
        if (FAILED (hr)) {
@@ -1267,6 +1298,14 @@ static int open_audio_wasapi (struct sound_data *sd, int index, int exclusive)
                goto error;
        }
 
+       if (s->wasapipull) {
+               hr = s->pAudioClient->SetEventHandle(s->wasapievent);
+               if (FAILED(hr)) {
+                       write_log(_T("WASAPI: SetEventHandle() %08X\n"), hr);
+                       goto error;
+               }
+       }
+
        hr = s->pAudioClient->GetBufferSize (&s->bufferFrameCount);
        if (FAILED (hr)) {
                write_log (_T("WASAPI: GetBufferSize() %08X\n"), hr);
@@ -1292,8 +1331,7 @@ static int open_audio_wasapi (struct sound_data *sd, int index, int exclusive)
                write_log (_T("WASAPI: GetService(ISimpleAudioVolume) %08X\n"), hr);
                goto error;
        }
-#if 0
-       hr = s->pAudioClient->GetService (IAudioClock, (void**)&s->pAudioClock);
+       hr = s->pAudioClient->GetService (__uuidof(IAudioClock), (void**)&s->pAudioClock);
        if (FAILED (hr)) {
                write_log (_T("WASAPI: GetService(IAudioClock) %08X\n"), hr);
        } else {
@@ -1302,16 +1340,31 @@ static int open_audio_wasapi (struct sound_data *sd, int index, int exclusive)
                        write_log (_T("WASAPI: GetFrequency() %08X\n"), hr);
                }
        }
-#endif
-       sd->sndbufsize = (s->bufferFrameCount / 8) * sd->samplesize;
-       v = s->bufferFrameCount * sd->samplesize;
-       v /= 2;
-       if (sd->sndbufsize > v)
-               sd->sndbufsize = v;
-       s->wasapigoodsize = s->bufferFrameCount / 2;
+       if (s->wasapipull) {
+               if (s->wasapiexclusive) {
+                       sd->sndbufsize = s->bufferFrameCount * sd->samplesize;
+                       s->wasapibuffermaxlen = sd->sndbufsize;
+               } else {
+                       sd->sndbufsize = s->bufferFrameCount * sd->samplesize / 2;
+                       s->wasapibuffermaxlen = sd->sndbufsize * 2;
+               }
+               s->wasapigoodsize = s->bufferFrameCount;
+               s->wasapibuffer = xcalloc(uae_u8, s->wasapibuffermaxlen);
+               s->wasapibufferlen = 0;
+       } else {
+               sd->sndbufsize = (s->bufferFrameCount / 8) * sd->samplesize;
+               v = s->bufferFrameCount * sd->samplesize;
+               v /= 2;
+               if (sd->sndbufsize > v)
+                       sd->sndbufsize = v;
+               s->wasapigoodsize = s->bufferFrameCount / 2;
+       }
 
-       write_log(_T("WASAPI: '%s'\nWASAPI: EX=%d CH=%d FREQ=%d BUF=%d (%d)\n"),
-               name, s->wasapiexclusive, sd->channels, sd->freq, sd->sndbufsize / sd->samplesize, s->bufferFrameCount);
+       write_log(_T("WASAPI: '%s'\nWASAPI: %s %s CH=%d FREQ=%d BUF=%d (%d)\n"),
+               name,
+               s->wasapiexclusive ? _T("Exclusive") : _T("Shared"),
+               s->wasapipull ? _T("Pull") : _T("Push"),
+               sd->channels, sd->freq, sd->sndbufsize / sd->samplesize, s->bufferFrameCount);
 
        CoTaskMemFree (pwfx);
        CoTaskMemFree (pwfx_saved);
@@ -1599,6 +1652,8 @@ static int open_sound (void)
 
        have_sound = 1;
        sound_available = 1;
+       gui_data.sndbuf_avail = !audio_is_pull();
+
        paula_sndbufsize = sdp->sndbufsize;
        paula_sndbufpt = paula_sndbuffer;
        driveclick_init ();
@@ -1611,6 +1666,7 @@ void close_sound (void)
        config_changed = 1;
        gui_data.sndbuf = 0;
        gui_data.sndbuf_status = 3;
+       gui_data.sndbuf_avail = false;
        if (! have_sound)
                return;
        close_sound_device (sdp);
@@ -1656,6 +1712,7 @@ int init_sound (void)
        bool started = false;
        gui_data.sndbuf_status = 3;
        gui_data.sndbuf = 0;
+       gui_data.sndbuf_avail = false;
        if (!sound_available)
                return 0;
        if (currprefs.produce_sound <= 1)
@@ -1974,7 +2031,7 @@ static void finish_sound_buffer_xaudio2 (struct sound_data *sd, uae_u16 *sndbuff
 }
 #endif
 
-static void finish_sound_buffer_wasapi (struct sound_data *sd, uae_u16 *sndbuffer)
+static void finish_sound_buffer_wasapi_push(struct sound_data *sd, uae_u16 *sndbuffer)
 {
        struct sound_dp *s = sd->data;
        HRESULT hr;
@@ -1983,6 +2040,7 @@ static void finish_sound_buffer_wasapi (struct sound_data *sd, uae_u16 *sndbuffe
        int avail;
        int stuck = 2000;
        int oldpadding = 0;
+       bool silence = false;
 
        for (;;) {
                hr = s->pAudioClient->GetCurrentPadding (&numFramesPadding);
@@ -2015,12 +2073,84 @@ static void finish_sound_buffer_wasapi (struct sound_data *sd, uae_u16 *sndbuffe
 
        hr = s->pRenderClient->GetBuffer (sd->sndbufframes, &pData);
        if (SUCCEEDED (hr)) {
-               memcpy (pData, sndbuffer, sd->sndbufsize);
+               if (silence)
+                       memset(pData, 0, sd->sndbufsize);
+               else
+                       memcpy(pData, sndbuffer, sd->sndbufsize);
                s->pRenderClient->ReleaseBuffer (sd->sndbufframes, 0);
        }
 
 }
 
+static bool finish_sound_buffer_wasapi_pull_do(struct sound_data *sd)
+{
+       struct sound_dp *s = sd->data;
+       HRESULT hr;
+       BYTE *pData;
+
+       if (s->wasapibufferlen <= 0)
+               return false;
+
+       int frames = s->wasapibufferlen / sd->samplesize;
+       int avail = frames;
+
+       if (!s->wasapiexclusive) {
+               UINT32 numFramesPadding;
+               hr = s->pAudioClient->GetCurrentPadding(&numFramesPadding);
+               if (FAILED(hr)) {
+                       write_log(_T("WASAPI: GetCurrentPadding() %08X\n"), hr);
+                       return false;
+               }
+               avail = s->bufferFrameCount - numFramesPadding;
+               if (!avail)
+                       return false;
+               if (avail > frames)
+                       avail = frames;
+       }
+
+       ResetEvent(s->wasapievent);
+
+       hr = s->pRenderClient->GetBuffer(avail, &pData);
+       if (SUCCEEDED(hr)) {
+               memcpy(pData, s->wasapibuffer, avail * sd->samplesize);
+               hr = s->pRenderClient->ReleaseBuffer(avail, 0);
+               if (FAILED(hr)) {
+                       write_log(_T("WASAPI: ReleaseBuffer() %08X\n"), hr);
+               }
+       } else {
+               write_log(_T("WASAPI: GetBuffer() %08X\n"), hr);
+       }
+       
+       if (avail < frames) {
+               memmove(s->wasapibuffer, s->wasapibuffer + avail * sd->samplesize, s->wasapibufferlen - (avail  * sd->samplesize));
+       }
+       s->wasapibufferlen -= avail * sd->samplesize;
+
+       return true;
+}
+
+static void finish_sound_buffer_wasapi_pull(struct sound_data *sd, uae_u16 *sndbuffer)
+{
+       struct sound_dp *s = sd->data;
+
+       if (s->wasapibufferlen + sd->sndbufsize > s->wasapibuffermaxlen) {
+               write_log(_T("wasapi pull overflow! %d %d %d\n"), s->wasapibufferlen, sd->sndbufsize, s->wasapibuffermaxlen);
+               s->wasapibufferlen = 0;
+       }
+       memcpy(s->wasapibuffer + s->wasapibufferlen, sndbuffer, sd->sndbufsize);
+       s->wasapibufferlen += sd->sndbufsize;
+}
+
+static void finish_sound_buffer_wasapi(struct sound_data *sd, uae_u16 *sndbuffer)
+{
+       struct sound_dp *s = sd->data;
+       if (s->wasapipull)
+               finish_sound_buffer_wasapi_pull(sd, sndbuffer);
+       else
+               finish_sound_buffer_wasapi_push(sd, sndbuffer);
+}
+
+
 static void finish_sound_buffer_ds (struct sound_data *sd, uae_u16 *sndbuffer)
 {
        struct sound_dp *s = sd->data;
@@ -2229,7 +2359,16 @@ static void channelswap6 (uae_s16 *sndbuffer, int len)
        }
 }
 
-void send_sound (struct sound_data *sd, uae_u16 *sndbuffer)
+static bool send_sound_do(struct sound_data *sd)
+{
+       int type = sd->devicetype;
+       if (type == SOUND_DEVICE_WASAPI || type == SOUND_DEVICE_WASAPI_EXCLUSIVE) {
+               return finish_sound_buffer_wasapi_pull_do(sd);
+       }
+       return false;
+}
+
+static void send_sound (struct sound_data *sd, uae_u16 *sndbuffer)
 {
        int type = sd->devicetype;
        if (savestate_state)
@@ -2256,6 +2395,92 @@ void send_sound (struct sound_data *sd, uae_u16 *sndbuffer)
 #endif
 }
 
+HANDLE get_sound_event(void)
+{
+       int type = sdp->devicetype;
+       if (sdp->paused)
+               return 0;
+       if (type == SOUND_DEVICE_WASAPI || type == SOUND_DEVICE_WASAPI_EXCLUSIVE) {
+               struct sound_dp *s = sdp->data;
+               if (s && s->wasapipull) {
+                       return s->wasapievent;
+               }
+       }
+       return 0;
+}
+
+bool audio_is_event_frame_possible(int ms)
+{
+       int type = sdp->devicetype;
+       if (sdp->paused)
+               return false;
+       if (type == SOUND_DEVICE_WASAPI || type == SOUND_DEVICE_WASAPI_EXCLUSIVE) {
+               struct sound_dp *s = sdp->data;
+               int bufsize = (uae_u8*)paula_sndbufpt - (uae_u8*)paula_sndbuffer;
+               bufsize /= sdp->samplesize;
+               int todo = s->bufferFrameCount - bufsize;
+               int samplesperframe = sdp->obtainedfreq / vblank_hz;
+               return samplesperframe >= todo - samplesperframe;
+       }
+       return false;
+}
+
+bool audio_is_pull(void)
+{
+       int type = sdp->devicetype;
+       if (type == SOUND_DEVICE_WASAPI || type == SOUND_DEVICE_WASAPI_EXCLUSIVE) {
+               struct sound_dp *s = sdp->data;
+               return s && s->wasapipull;
+       }
+       return false;
+}
+
+int audio_pull_buffer(void)
+{
+       int cnt = 0;
+       int type = sdp->devicetype;
+       
+       if (sdp->paused)
+               return 0;
+       if (type == SOUND_DEVICE_WASAPI || type == SOUND_DEVICE_WASAPI_EXCLUSIVE) {
+               struct sound_dp *s = sdp->data;
+               if (s->wasapibufferlen > 0) {
+                       cnt++;
+                       int size = (uae_u8*)paula_sndbufpt - (uae_u8*)paula_sndbuffer;
+                       if (size > sdp->sndbufsize * 2 / 3)
+                               cnt++;
+               }
+       }
+       return cnt;
+}
+
+bool audio_is_pull_event(void)
+{
+       int type = sdp->devicetype;
+       if (sdp->paused)
+               return false;
+       if (type == SOUND_DEVICE_WASAPI || type == SOUND_DEVICE_WASAPI_EXCLUSIVE) {
+               struct sound_dp *s = sdp->data;
+               if (s->wasapipull) {
+                       return WaitForSingleObject(s->wasapievent, 0) == WAIT_OBJECT_0;
+               }
+       }
+       return false;
+}
+
+bool audio_finish_pull(void)
+{
+       int type = sdp->devicetype;
+       if (sdp->paused)
+               return false;
+       if (type != SOUND_DEVICE_WASAPI && type != SOUND_DEVICE_WASAPI_EXCLUSIVE)
+               return false;
+       if (audio_pull_buffer() && audio_is_pull_event()) {
+               return send_sound_do(sdp);
+       }
+       return false;
+}
+
 void finish_sound_buffer (void)
 {
        static unsigned long tframe;
@@ -2585,13 +2810,14 @@ int enumerate_sound_devices (void)
 {
        if (!num_sound_devices) {
                HMODULE l = NULL;
-               write_log (_T("Enumerating DirectSound devices..\n"));
+               if (os_vista && (sounddrivermask & SOUNDDRIVER_WASAPI)) {
+                       wasapi_enum(sound_devices);
+               }
                if ((1 || force_directsound || !os_vista) && (sounddrivermask & SOUNDDRIVER_DS)) {
+                       write_log(_T("Enumerating DirectSound devices..\n"));
                        DirectSoundEnumerate ((LPDSENUMCALLBACK)DSEnumProc, sound_devices);
                }
                DirectSoundCaptureEnumerate ((LPDSENUMCALLBACK)DSEnumProc, record_devices);
-               if (os_vista && (sounddrivermask & SOUNDDRIVER_WASAPI))
-                       wasapi_enum (sound_devices);
 #if USE_XAUDIO
                if (sounddrivermask & SOUNDDRIVE_XAUDIO2)
                        xaudioenumerate (sound_devices);
index 4f3cc8ae5902c65ed440bc5fb3aaf268015c1d60..c2051baf5dc3cdf6f1c2b07ffa697909d78ffd1c 100644 (file)
@@ -50,7 +50,6 @@ struct sound_data
 };
 
 
-void send_sound (struct sound_data *sd, uae_u16 *sndbuffer);
 int open_sound_device (struct sound_data *sd, int index, int exclusive, int bufsize, int freq, int channels);
 void close_sound_device (struct sound_data *sd);
 void pause_sound_device (struct sound_data *sd);
@@ -58,6 +57,7 @@ void resume_sound_device (struct sound_data *sd);
 void set_volume_sound_device (struct sound_data *sd, int volume, int mute);
 int get_offset_sound_device (struct sound_data *sd);
 int blocking_sound_device (struct sound_data *sd);
+bool is_sound_buffer(void);
 
 #if SOUNDSTUFF > 0
 extern int outputsample, doublesample;
index 6b5638f703a1b9b5581e6395f33db68ac89ad0a0..c9187e9bc8418a72f5aa28d5fb0bbe66e50f808b 100644 (file)
@@ -39,7 +39,6 @@ void deletestatusline(void)
        statusline_hdc = NULL;
        statusline_font = NULL;
        statusline_palette = NULL;
-       statusline_clear();
 }
 
 bool createstatusline(void)
index 0e768b17cd65529be5a378f9ffb0299b5e131df5..5f3ef88073b1f362e80f55c8c1af65ee9eb3f10e 100644 (file)
@@ -19,7 +19,7 @@
 
 #include "sysconfig.h"
 
-#define USETHREADCHARACTERICS 0
+#define USETHREADCHARACTERICS 1
 #define _WIN32_WINNT 0x700 /* XButtons + MOUSEHWHEEL=XP, Jump List=Win7 */
 
 #include <windows.h>
@@ -114,7 +114,7 @@ int log_vsync, debug_vsync_min_delay, debug_vsync_forced_delay;
 int uaelib_debug;
 int pissoff_value = 15000 * CYCLE_UNIT;
 unsigned int fpucontrol;
-int extraframewait;
+int extraframewait, extraframewait2;
 
 extern FILE *debugfile;
 extern int console_logging;
@@ -270,15 +270,34 @@ void sleep_cpu_wakeup(void)
        }
 }
 
-static void sleep_millis2 (int ms, bool main)
+HANDLE get_sound_event(void);
+
+static int sleep_millis2 (int ms, bool main)
 {
        UINT TimerEvent;
        int start = 0;
        int cnt;
+       HANDLE sound_event = get_sound_event();
+       bool wasneg = ms < 0;
+       bool pullcheck = false;
+       int ret = 0;
 
+       if (ms < 0)
+               ms = -ms;
        if (main) {
+               if (sound_event) {
+                       bool pullcheck = audio_is_event_frame_possible(ms);
+                       if (pullcheck) {
+                               if (WaitForSingleObject(sound_event, 0) == WAIT_OBJECT_0) {
+                                       if (wasneg) {
+                                               write_log(_T("efw %d imm abort\n"), ms);
+                                       }
+                                       return -1;
+                               }
+                       }
+               }
                if (WaitForSingleObject(cpu_wakeup_event, 0) == WAIT_OBJECT_0) {
-                       return;
+                       return 0;
                }
                start = read_processor_time ();
        }
@@ -296,10 +315,23 @@ static void sleep_millis2 (int ms, bool main)
        LeaveCriticalSection (&cs_time);
        TimerEvent = timeSetEvent (ms, 0, (LPTIMECALLBACK)timehandle[cnt], 0, TIME_ONESHOT | TIME_CALLBACK_EVENT_SET);
        if (main) {
-               HANDLE evt[2];
-               evt[0] = timehandle[cnt];
-               evt[1] = cpu_wakeup_event;
-               DWORD status = WaitForMultipleObjects(2, evt, FALSE, ms);
+               int c = 0;
+               HANDLE evt[3];
+               evt[c++] = timehandle[cnt];
+               evt[c++] = cpu_wakeup_event;
+               if (sound_event && pullcheck) {
+                       evt[c++] = sound_event;
+               }
+               DWORD status = WaitForMultipleObjects(c, evt, FALSE, ms);
+               if (status == WAIT_OBJECT_0 + 2)
+                       ret = -1;
+               if (wasneg) {
+                       if (status == WAIT_OBJECT_0 + 2) {
+                               write_log(_T("efw %d delayed abort\n"), ms);
+                       } else if (status == WAIT_TIMEOUT) {
+                               write_log(_T("efw %d full wait\n"), ms);
+                       }
+               }
                cpu_wakeup_event_triggered = false;
        } else {
                WaitForSingleObject(timehandle[cnt], ms);
@@ -309,26 +341,28 @@ static void sleep_millis2 (int ms, bool main)
        timehandleinuse[cnt] = false;
        if (main)
                idletime += read_processor_time () - start;
+       return ret;
 }
 
-void sleep_millis_main (int ms)
+int sleep_millis_main (int ms)
 {
-       sleep_millis2 (ms, true);
+       return sleep_millis2 (ms, true);
 }
-void sleep_millis (int ms)
+int sleep_millis (int ms)
 {
-       sleep_millis2 (ms, false);
+       return sleep_millis2 (ms, false);
 }
 
-void sleep_millis_amiga(int ms)
+int sleep_millis_amiga(int ms)
 {
 #ifdef WITH_THREADED_CPU
        cpu_semaphore_release();
 #endif
-       sleep_millis_main(ms);
+       int ret = sleep_millis_main(ms);
 #ifdef WITH_THREADED_CPU
        cpu_semaphore_get();
 #endif
+       return ret;
 }
 
 static int windowmouse_max_w;
@@ -772,9 +806,15 @@ static void winuae_active (HWND hWnd, int minimized)
        clipboard_active (hAmigaWnd, 1);
 #if USETHREADCHARACTERICS
        if (os_vista && AVTask == NULL) {
+               typedef HANDLE(WINAPI* AVSETMMTHREADCHARACTERISTICS)(LPCTSTR, LPDWORD);
                DWORD taskIndex = 0;
-               if (!(AVTask = AvSetMmThreadCharacteristics (TEXT("Pro Audio"), &taskIndex)))
-                       write_log (_T("AvSetMmThreadCharacteristics failed: %d\n"), GetLastError ());
+               AVSETMMTHREADCHARACTERISTICS pAvSetMmThreadCharacteristics =
+                       (AVSETMMTHREADCHARACTERISTICS)GetProcAddress(GetModuleHandle(_T("Avrt.dll")), "AvSetMmThreadCharacteristicsW");
+               if (pAvSetMmThreadCharacteristics) {
+                       if (!(AVTask = pAvSetMmThreadCharacteristics(TEXT("Pro Audio"), &taskIndex))) {
+                               write_log (_T("AvSetMmThreadCharacteristics failed: %d\n"), GetLastError ());
+                       }
+               }
        }
 #endif
 }
@@ -786,9 +826,14 @@ static void winuae_inactive (HWND hWnd, int minimized)
 
        //write_log (_T("winuae_inactive(%d)\n"), minimized);
 #if USETHREADCHARACTERICS
-       if (AVTask)
-               AvRevertMmThreadCharacteristics (AVTask);
-       AVTask = NULL;
+       if (AVTask) {
+               typedef BOOL(WINAPI* AVREVERTMMTHREADCHARACTERISTICS)(HANDLE);
+               AVREVERTMMTHREADCHARACTERISTICS pAvRevertMmThreadCharacteristics =
+                       (AVREVERTMMTHREADCHARACTERISTICS)GetProcAddress(GetModuleHandle(_T("Avrt.dll")), "AvRevertMmThreadCharacteristics");
+               if (pAvRevertMmThreadCharacteristics)
+                       pAvRevertMmThreadCharacteristics(AVTask);
+               AVTask = NULL;
+       }
 #endif
        if (!currprefs.win32_powersavedisabled)
                SetThreadExecutionState (ES_CONTINUOUS);
@@ -2427,6 +2472,8 @@ bool handle_events (void)
                        manual_painting_needed++;
                        gui_fps (0, 0, 0);
                        gui_led (LED_SND, 0, -1);
+                       // we got just paused, report it to caller.
+                       return 1;
                }
                MsgWaitForMultipleObjects (0, NULL, FALSE, 100, QS_ALLINPUT);
                while (PeekMessage (&msg, 0, 0, 0, PM_REMOVE)) {
@@ -3517,7 +3564,8 @@ void target_default_options (struct uae_prefs *p, int type)
                p->win32_iconified_priority = 3;
                p->win32_notaskbarbutton = false;
                p->win32_nonotificationicon = false;
-               p->win32_alwaysontop = false;
+               p->win32_main_alwaysontop = false;
+               p->win32_gui_alwaysontop = false;
                p->win32_guikey = -1;
                p->win32_automount_removable = 0;
                p->win32_automount_drives = 0;
@@ -3661,7 +3709,8 @@ void target_save_options (struct zfile *f, struct uae_prefs *p)
        cfgfile_target_dwrite (f, _T("cpu_idle"), _T("%d"), p->cpu_idle);
        cfgfile_target_dwrite_bool (f, _T("notaskbarbutton"), p->win32_notaskbarbutton);
        cfgfile_target_dwrite_bool (f, _T("nonotificationicon"), p->win32_nonotificationicon);
-       cfgfile_target_dwrite_bool (f, _T("always_on_top"), p->win32_alwaysontop);
+       cfgfile_target_dwrite_bool (f, _T("always_on_top"), p->win32_main_alwaysontop);
+       cfgfile_target_dwrite_bool (f, _T("gui_always_on_top"), p->win32_gui_alwaysontop);
        cfgfile_target_dwrite_bool (f, _T("no_recyclebin"), p->win32_norecyclebin);
        if (p->win32_guikey >= 0)
                cfgfile_target_dwrite (f, _T("guikey"), _T("0x%x"), p->win32_guikey);
@@ -3676,7 +3725,8 @@ void target_save_options (struct zfile *f, struct uae_prefs *p)
        cfgfile_target_dwrite_bool(f, _T("filesystem_mangle_reserved_names"), p->win32_filesystem_mangle_reserved_names);
        cfgfile_target_dwrite_bool(f, _T("right_control_is_right_win"), p->right_control_is_right_win_key);
 
-       cfgfile_target_dwrite (f, _T("extraframewait"), _T("%d"), extraframewait);
+       cfgfile_target_dwrite(f, _T("extraframewait"), _T("%d"), extraframewait);
+       cfgfile_target_dwrite(f, _T("extraframewait_us"), _T("%d"), extraframewait2);
        cfgfile_target_dwrite (f, _T("framelatency"), _T("%d"), forcedframelatency);
        if (scsiromselected > 0)
                cfgfile_target_write(f, _T("expansion_gui_page"), expansionroms[scsiromselected].name);
@@ -3715,16 +3765,22 @@ static int fetchpri (int pri, int defpri)
        return defpri;
 }
 
-TCHAR *target_expand_environment (const TCHAR *path)
+TCHAR *target_expand_environment (const TCHAR *path, TCHAR *out, int maxlen)
 {
        if (!path)
                return NULL;
-       int len = ExpandEnvironmentStrings (path, NULL, 0);
-       if (len <= 0)
-               return my_strdup (path);
-       TCHAR *s = xmalloc (TCHAR, len + 1);
-       ExpandEnvironmentStrings (path, s, len);
-       return s;
+       if (out == NULL) {
+               int len = ExpandEnvironmentStrings (path, NULL, 0);
+               if (len <= 0)
+                       return my_strdup (path);
+               TCHAR *s = xmalloc (TCHAR, len + 1);
+               ExpandEnvironmentStrings (path, s, len);
+               return s;
+       } else {
+               if (ExpandEnvironmentStrings(path, out, maxlen) <= 0)
+                       _tcscpy(out, path);
+               return out;
+       }
 }
 
 static const TCHAR *obsolete[] = {
@@ -3769,7 +3825,8 @@ int target_parse_option (struct uae_prefs *p, const TCHAR *option, const TCHAR *
                || cfgfile_intval(option, value, _T("samplersoundcard"), &p->win32_samplersoundcard, 1)
                || cfgfile_yesno(option, value, _T("notaskbarbutton"), &p->win32_notaskbarbutton)
                || cfgfile_yesno(option, value, _T("nonotificationicon"), &p->win32_nonotificationicon)
-               || cfgfile_yesno(option, value, _T("always_on_top"), &p->win32_alwaysontop)
+               || cfgfile_yesno(option, value, _T("always_on_top"), &p->win32_main_alwaysontop)
+               || cfgfile_yesno(option, value, _T("gui_always_on_top"), &p->win32_gui_alwaysontop)
                || cfgfile_yesno(option, value, _T("powersavedisabled"), &p->win32_powersavedisabled)
                || cfgfile_string(option, value, _T("exec_before"), p->win32_commandpathstart, sizeof p->win32_commandpathstart / sizeof (TCHAR))
                || cfgfile_string(option, value, _T("exec_after"), p->win32_commandpathend, sizeof p->win32_commandpathend / sizeof (TCHAR))
@@ -3782,6 +3839,7 @@ int target_parse_option (struct uae_prefs *p, const TCHAR *option, const TCHAR *
                || cfgfile_yesno(option, value, _T("filesystem_mangle_reserved_names"), &p->win32_filesystem_mangle_reserved_names)
                || cfgfile_yesno(option, value, _T("right_control_is_right_win"), &p->right_control_is_right_win_key)
                || cfgfile_intval(option, value, _T("extraframewait"), &extraframewait, 1)
+               || cfgfile_intval(option, value, _T("extraframewait_us"), &extraframewait2, 1)
                || cfgfile_intval(option, value, _T("framelatency"), &forcedframelatency, 1)
                || cfgfile_intval(option, value, _T("cpu_idle"), &p->cpu_idle, 1))
                return 1;
@@ -5365,6 +5423,8 @@ extern int log_blitter;
 extern int slirp_debug;
 extern int fakemodewaitms;
 extern float sound_sync_multiplier;
+extern int log_cd32;
+extern int scanline_adjust;
 
 extern DWORD_PTR cpu_affinity, cpu_paffinity;
 static DWORD_PTR original_affinity = -1;
@@ -5675,6 +5735,14 @@ static int parseargs (const TCHAR *argx, const TCHAR *np, const TCHAR *np2)
                createbootlog = false;
                return 1;
        }
+       if (!_tcscmp(arg, _T("cd32log"))) {
+               log_cd32 = 1;
+               return 1;
+       }
+       if (!_tcscmp(arg, _T("cd32log2"))) {
+               log_cd32 = 2;
+               return 1;
+       }
 
        if (!np)
                return 0;
@@ -5685,6 +5753,11 @@ static int parseargs (const TCHAR *argx, const TCHAR *np, const TCHAR *np2)
                return 2;
        }
 #endif
+
+       if (!_tcscmp(arg, _T("scanlineadjust"))) {
+               scanline_adjust = getval(np);
+               return 2;
+       }
        if (!_tcscmp (arg, _T("vsync_modechangetimeout"))) {
                vsync_modechangetimeout = getval (np);
                return 2;
@@ -5790,8 +5863,12 @@ static int parseargs (const TCHAR *argx, const TCHAR *np, const TCHAR *np2)
                inputrecord_debug = getval (np);
                return 2;
        }
-       if (!_tcscmp (arg, _T("extraframewait"))) {
-               extraframewait = getval (np);
+       if (!_tcscmp(arg, _T("extraframewait"))) {
+               extraframewait = getval(np);
+               return 2;
+       }
+       if (!_tcscmp(arg, _T("extraframewait_us"))) {
+               extraframewait2 = getval(np);
                return 2;
        }
        if (!_tcscmp (arg, _T("framelatency"))) {
@@ -6856,7 +6933,7 @@ void *uaenative_get_uaevar (void)
 #ifdef _WIN32
     uaevar.amigawnd = hAmigaWnd;
 #endif
-    uaevar.z3offset = (uae_u32)get_real_address (z3fastmem_bank.start) - z3fastmem_bank.start;
+    uaevar.z3offset = (uae_u32)get_real_address (z3fastmem_bank[0].start) - z3fastmem_bank[0].start;
     return &uaevar;
 }
 
index 53168a6892fdeb1fd6217a4af48542e5d4c88595..c472c211c421c19ef5382e96c0b4cdb70aa0efb8 100644 (file)
 #define GETBDM(x) (((x) - ((x / 10000) * 10000)) / 100)
 #define GETBDD(x) ((x) % 100)
 
-#define WINUAEPUBLICBETA 0
+#define WINUAEPUBLICBETA 1
 #define LANG_DLL 1
 #define LANG_DLL_FULL_VERSION_MATCH 1
 
 #if WINUAEPUBLICBETA
-#define WINUAEBETA _T("")
+#define WINUAEBETA _T("0")
 #else
 #define WINUAEBETA _T("")
 #endif
 
-#define WINUAEDATE MAKEBD(2016, 6, 6)
+#define WINUAEDATE MAKEBD(2016, 8, 4)
 
 //#define WINUAEEXTRA _T("AmiKit Preview")
 //#define WINUAEEXTRA _T("Amiga Forever Edition")
@@ -112,9 +112,9 @@ extern bool winuaelog_temporary_enable;
 enum pathtype { PATH_TYPE_DEFAULT, PATH_TYPE_WINUAE, PATH_TYPE_NEWWINUAE, PATH_TYPE_NEWAF, PATH_TYPE_AMIGAFOREVERDATA, PATH_TYPE_END };
 void setpathmode (pathtype pt);
 
-extern void sleep_millis (int ms);
-extern void sleep_millis_main (int ms);
-extern void sleep_millis_amiga (int ms);
+extern int sleep_millis (int ms);
+extern int sleep_millis_main (int ms);
+extern int sleep_millis_amiga (int ms);
 extern void wait_keyrelease (void);
 extern void keyboard_settrans (void);
 
index 0a5df00a855e772c7b5c9f53b70892b692723f40..5b6d5bdc656024db538b7a348bbd8674d256b17d 100644 (file)
@@ -2047,7 +2047,8 @@ int check_prefs_changed_gfx (void)
        c |= currprefs.gfx_apmode[APMODE_NATIVE].gfx_interlaced != changed_prefs.gfx_apmode[APMODE_NATIVE].gfx_interlaced ? (2 | 8) : 0;
        c |= currprefs.gfx_apmode[APMODE_RTG].gfx_backbuffers != changed_prefs.gfx_apmode[APMODE_RTG].gfx_backbuffers ? (2 | 8) : 0;
 
-       c |= currprefs.win32_alwaysontop != changed_prefs.win32_alwaysontop ? 32 : 0;
+       c |= currprefs.win32_main_alwaysontop != changed_prefs.win32_main_alwaysontop ? 32 : 0;
+       c |= currprefs.win32_gui_alwaysontop != changed_prefs.win32_gui_alwaysontop ? 32 : 0;
        c |= currprefs.win32_notaskbarbutton != changed_prefs.win32_notaskbarbutton ? 32 : 0;
        c |= currprefs.win32_nonotificationicon != changed_prefs.win32_nonotificationicon ? 32 : 0;
        c |= currprefs.win32_borderless != changed_prefs.win32_borderless ? 32 : 0;
@@ -2138,7 +2139,8 @@ int check_prefs_changed_gfx (void)
                currprefs.gfx_apmode[APMODE_NATIVE].gfx_interlaced = changed_prefs.gfx_apmode[APMODE_NATIVE].gfx_interlaced;
                currprefs.gfx_apmode[APMODE_RTG].gfx_backbuffers = changed_prefs.gfx_apmode[APMODE_RTG].gfx_backbuffers;
 
-               currprefs.win32_alwaysontop = changed_prefs.win32_alwaysontop;
+               currprefs.win32_main_alwaysontop = changed_prefs.win32_main_alwaysontop;
+               currprefs.win32_gui_alwaysontop = changed_prefs.win32_gui_alwaysontop;
                currprefs.win32_nonotificationicon = changed_prefs.win32_nonotificationicon;
                currprefs.win32_notaskbarbutton = changed_prefs.win32_notaskbarbutton;
                currprefs.win32_borderless = changed_prefs.win32_borderless;
@@ -2889,9 +2891,10 @@ static void createstatuswindow (void)
        RECT rc;
        HLOCAL hloc;
        LPINT lpParts;
-       int drive_width, hd_width, cd_width, power_width, fps_width, idle_width, snd_width, joy_width;
+       int drive_width, hd_width, cd_width, power_width;
+       int fps_width, idle_width, snd_width, joy_width, net_width;
        int joys = currprefs.win32_statusbar > 1 ? 2 : 0;
-       int num_parts = 11 + joys + 1;
+       int num_parts = 12 + joys + 1;
        double scaleX, scaleY;
        WINDOWINFO wi;
        int extra;
@@ -2926,6 +2929,7 @@ static void createstatuswindow (void)
        power_width = (int)(42 * scaleX);
        fps_width = (int)(64 * scaleX);
        idle_width = (int)(64 * scaleX);
+       net_width = (int)(24 * scaleX);
        if (is_ppc_cpu(&currprefs))
                idle_width += (int)(68 * scaleX);
        if (is_x86_cpu(&currprefs))
@@ -2943,7 +2947,7 @@ static void createstatuswindow (void)
                i++;
                window_led_msg_start = i;
                /* Calculate the right edge coordinate for each part, and copy the coords to the array.  */
-               int startx = rc.right - (drive_width * 4) - power_width - idle_width - fps_width - cd_width - hd_width - snd_width - joys * joy_width - extra;
+               int startx = rc.right - (drive_width * 4) - power_width - idle_width - fps_width - cd_width - hd_width - snd_width - net_width - joys * joy_width - extra;
                for (j = 0; j < joys; j++) {
                        lpParts[i] = startx;
                        i++;
@@ -2971,9 +2975,12 @@ static void createstatuswindow (void)
                // cd
                lpParts[i] = lpParts[i - 1] + hd_width;
                i++;
-               // df0
+               // net
                lpParts[i] = lpParts[i - 1] + cd_width;
                i++;
+               // df0
+               lpParts[i] = lpParts[i - 1] + net_width;
+               i++;
                // df1
                lpParts[i] = lpParts[i - 1] + drive_width;
                i++;
@@ -2992,8 +2999,8 @@ static void createstatuswindow (void)
                window_led_joys_end = lpParts[window_led_joy_start - joys + 1];
                window_led_hd = lpParts[i1];
                window_led_hd_end = lpParts[i1 + 1];
-               window_led_drives = lpParts[i1 + 2];
-               window_led_drives_end = lpParts[i1 + 6];
+               window_led_drives = lpParts[i1 + 3];
+               window_led_drives_end = lpParts[i1 + 3 + 4];
 
                /* Create the parts */
                SendMessage (hStatusWnd, SB_SETPARTS, (WPARAM)num_parts, (LPARAM)lpParts);
@@ -3111,6 +3118,7 @@ double getcurrentvblankrate (void)
 }
 
 static int maxscanline, minscanline, prevvblankpos;
+int scanline_adjust;
 
 static bool getvblankpos (int *vp, bool updateprev)
 {
@@ -3138,6 +3146,13 @@ static bool getvblankpos (int *vp, bool updateprev)
                if (sl < minscanline || minscanline < 0)
                        minscanline = sl;
        }
+       if (maxscanline > minscanline) {
+               sl += scanline_adjust;
+               while (sl < 0)
+                       sl += maxscanline;
+               while (sl > maxscanline)
+                       sl -= maxscanline;
+       }
        *vp = sl;
        return true;
 }
@@ -4187,7 +4202,7 @@ static int create_windows_2 (void)
                        currentmode->native_width = rc.right - rc.left;
                        currentmode->native_height = rc.bottom - rc.top;
                }
-               flags |= (currprefs.win32_alwaysontop ? WS_EX_TOPMOST : 0);
+               flags |= (currprefs.win32_main_alwaysontop ? WS_EX_TOPMOST : 0);
 
                if (!borderless) {
                        RECT rc2;
@@ -4232,14 +4247,14 @@ static int create_windows_2 (void)
 
        if (rp_isactive () && !dxfs && !d3dfs && !fsw) {
                HWND parent = rp_getparent ();
-               hAmigaWnd = CreateWindowEx (dxfs || d3dfs ? WS_EX_ACCEPTFILES | WS_EX_TOPMOST : WS_EX_ACCEPTFILES | WS_EX_TOOLWINDOW | (currprefs.win32_alwaysontop ? WS_EX_TOPMOST : 0),
+               hAmigaWnd = CreateWindowEx (dxfs || d3dfs ? WS_EX_ACCEPTFILES | WS_EX_TOPMOST : WS_EX_ACCEPTFILES | WS_EX_TOOLWINDOW | (currprefs.win32_main_alwaysontop ? WS_EX_TOPMOST : 0),
                        _T("AmigaPowah"), _T("WinUAE"),
                        WS_POPUP,
                        0, 0, w, h,
                        parent, NULL, hInst, NULL);
        } else {
                hAmigaWnd = CreateWindowEx (
-                       ((dxfs || d3dfs || currprefs.win32_alwaysontop) ? WS_EX_TOPMOST : WS_EX_ACCEPTFILES) | exstyle,
+                       ((dxfs || d3dfs || currprefs.win32_main_alwaysontop) ? WS_EX_TOPMOST : WS_EX_ACCEPTFILES) | exstyle,
                        _T("AmigaPowah"), _T("WinUAE"),
                        ((dxfs || d3dfs || currprefs.headless) ? WS_POPUP : (WS_CLIPCHILDREN | WS_CLIPSIBLINGS | (hMainWnd ? WS_VISIBLE | WS_CHILD : WS_VISIBLE | WS_POPUP | WS_SYSMENU | WS_MINIMIZEBOX))),
                        x, y, w, h,
@@ -4631,29 +4646,61 @@ void updatewinfsmode (struct uae_prefs *p)
        set_config_changed ();
 }
 
+int rtg_index = -1;
+
 bool toggle_rtg (int mode)
 {
-       if (mode == 0) {
-               if (!picasso_on)
-                       return false;
-       } else if (mode > 0) {
-               if (picasso_on)
-                       return false;
-       }
-       if (currprefs.rtgboards[0].rtgmem_type >= GFXBOARD_HARDWARE) {
-               return gfxboard_toggle (mode);
-       } else {
-               // can always switch from RTG to custom
-               if (picasso_requested_on && picasso_on) {
-                       picasso_requested_on = false;
-                       return true;
+       int old_index = rtg_index;
+
+       if (mode < -1 && rtg_index >= 0)
+               return true;
+
+       for (;;) {
+               rtg_index++;
+               if (rtg_index >= MAX_RTG_BOARDS) {
+                       rtg_index = -1;
                }
-               if (picasso_on)
+               if (rtg_index < 0) {
+                       if (picasso_on) {
+                               gfxboard_rtg_disable(old_index);
+                               picasso_requested_on = false;
+                               statusline_add_message(_T("Chipset display"));
+                               return false;
+                       }
                        return false;
-               // can only switch from custom to RTG if there is some mode active
-               if (picasso_is_active ()) {
-                       picasso_requested_on = true;
-                       return true;
+               }
+               struct rtgboardconfig *r = &currprefs.rtgboards[rtg_index];
+               if (r->rtgmem_size > 0) {
+                       if (r->rtgmem_type >= GFXBOARD_HARDWARE) {
+                               int idx = gfxboard_toggle(rtg_index, mode >= -1);
+                               if (idx >= 0) {
+                                       rtg_index = idx;
+                                       return true;
+                               }
+                               if (idx < -1) {
+                                       rtg_index = -1;
+                                       return false;
+                               }
+                       } else {
+                               gfxboard_toggle(-1, -1);
+                               if (mode < -1)
+                                       return true;
+                               gfxboard_rtg_disable(old_index);
+                               picasso_enablescreen(1);
+                               // can always switch from RTG to custom
+                               if (picasso_requested_on && picasso_on) {
+                                       picasso_requested_on = false;
+                                       return true;
+                               }
+                               if (picasso_on)
+                                       return false;
+                               // can only switch from custom to RTG if there is some mode active
+                               if (picasso_is_active ()) {
+                                       picasso_requested_on = true;
+                                       statusline_add_message(_T("RTG %d: %s"), rtg_index + 1, _T("UAEGFX"));
+                                       return true;
+                               }
+                       }
                }
        }
        return false;
index d8e13e86b3bba809931b3064c5f768b99b25e6d9..4756859356f858f5a7bb950be2feb2ae3298d860 100644 (file)
@@ -220,7 +220,8 @@ static int C_PAGES;
 static int LOADSAVE_ID = -1, MEMORY_ID = -1, KICKSTART_ID = -1, CPU_ID = -1,
        DISPLAY_ID = -1, HW3D_ID = -1, CHIPSET_ID = -1, CHIPSET2_ID = -1, SOUND_ID = -1, FLOPPY_ID = -1, DISK_ID = -1,
        HARDDISK_ID = -1, IOPORTS_ID = -1, GAMEPORTS_ID = -1, INPUT_ID = -1, MISC1_ID = -1, MISC2_ID = -1,
-       AVIOUTPUT_ID = -1, PATHS_ID = -1, QUICKSTART_ID = -1, ABOUT_ID = -1, EXPANSION_ID = -1, EXPANSION2_ID = -1, FRONTEND_ID = -1;
+       AVIOUTPUT_ID = -1, PATHS_ID = -1, QUICKSTART_ID = -1, ABOUT_ID = -1, EXPANSION_ID = -1, EXPANSION2_ID = -1,
+       BOARD_ID = -1, FRONTEND_ID = -1;
 static const int INPUTMAP_ID = MAX_C_PAGES - 1;
 static HWND pages[MAX_C_PAGES];
 #define MAX_IMAGETOOLTIPS 10
@@ -1339,7 +1340,7 @@ static const unsigned long memsizes[] = {
 static const int msi_chip[] = { 3, 4, 5, 16, 6, 7, 8 };
 static const int msi_bogo[] = { 0, 4, 5, 16, 17 };
 static const int msi_fast[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
-static const int msi_z3fast[] = { 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 19, 14, 20, 15, 21, 18, 22, 23 };
+static const int msi_z3fast[] = { 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
 static const int msi_z3chip[] = { 0, 9, 10, 11, 12, 13, 19, 14, 20, 15 };
 static const int msi_gfx[] = { 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
 static const int msi_cpuboard[] = { 0, 5, 6, 7, 8, 9, 10, 11, 12, 13 };
@@ -1351,7 +1352,7 @@ static const int msi_cpuboard[] = { 0, 5, 6, 7, 8, 9, 10, 11, 12, 13 };
 #define MIN_SLOW_MEM 0
 #define MAX_SLOW_MEM 4
 #define MIN_Z3_MEM 0
-#define MAX_Z3_MEM ((max_z3fastmem >> 20) < 512 ? 12 : ((max_z3fastmem >> 20) < 1024 ? 13 : ((max_z3fastmem >> 20) < 2048) ? 14 : 14))
+#define MAX_Z3_MEM 11
 #define MAX_Z3_CHIPMEM 9
 #define MIN_P96_MEM 0
 #define MAX_P96_MEM_Z3 ((max_z3fastmem >> 20) < 512 ? 8 : ((max_z3fastmem >> 20) < 1024 ? 9 : ((max_z3fastmem >> 20) < 2048) ? 10 : 11))
@@ -1362,6 +1363,7 @@ static const int msi_cpuboard[] = { 0, 5, 6, 7, 8, 9, 10, 11, 12, 13 };
 #define MIN_CB_MEM 0
 #define MAX_CB_MEM_Z2 4
 #define MAX_CB_MEM_16M 5
+#define MAX_CB_MEM_64M 7
 #define MAX_CB_MEM_128M 8
 #define MAX_CB_MEM_256M 9
 
@@ -3799,9 +3801,10 @@ static void set_lventry_input (HWND list, int index)
        } else {
                _tcscpy (af, _T("-"));
        }
-       if (flags & IDEV_MAPPED_TOGGLE)
+       if (flags & IDEV_MAPPED_TOGGLE) {
                WIN32GUI_LoadUIString (IDS_YES, toggle, sizeof toggle / sizeof (TCHAR));
-       else if (flags & IDEV_MAPPED_AUTOFIRE_POSSIBLE)
+       inputdevice_get_mapping(input_selected_device, index, &flags, &port, name, custom, input_selected_sub_num);
+       } else if (flags & IDEV_MAPPED_AUTOFIRE_POSSIBLE)
                WIN32GUI_LoadUIString (IDS_NO, toggle, sizeof toggle / sizeof (TCHAR));
        else
                _tcscpy (toggle, _T("-"));
@@ -3816,7 +3819,11 @@ static void set_lventry_input (HWND list, int index)
        if (flags & IDEV_MAPPED_SET_ONOFF) {
                _tcscat (name, _T(" ("));
                TCHAR val[32];
-               if (flags & IDEV_MAPPED_SET_ONOFF_VAL) {
+               if ((flags & (IDEV_MAPPED_SET_ONOFF_VAL1 | IDEV_MAPPED_SET_ONOFF_VAL2)) == (IDEV_MAPPED_SET_ONOFF_VAL1 | IDEV_MAPPED_SET_ONOFF_VAL2)) {
+                       _tcscpy(val, _T("onoff"));
+               } else if (flags & IDEV_MAPPED_SET_ONOFF_VAL2) {
+                       _tcscpy(val, _T("press"));
+               } else if (flags & IDEV_MAPPED_SET_ONOFF_VAL1) {
                        WIN32GUI_LoadUIString (IDS_ON, val, sizeof val / sizeof (TCHAR));
                } else {
                        WIN32GUI_LoadUIString (IDS_OFF, val, sizeof val / sizeof (TCHAR));
@@ -3936,6 +3943,7 @@ static int inputmap_handle (HWND list, int currentdevnum, int currentwidgetnum,
                                                                                if (cntitem - 1 == deleteindex) {
                                                                                        inputdevice_set_mapping (devnum, j, NULL, NULL, 0, 0, sub);
                                                                                        deleteindex = -1;
+                                                                                       found = true;
                                                                                        continue;
                                                                                }
                                                                                if (list) {
@@ -4011,6 +4019,7 @@ static int clicked_entry = -1;
 #define MISC1_COLUMNS 1
 #define MAX_COLUMN_HEADING_WIDTH 20
 #define CD_COLUMNS 3
+#define BOARD_COLUMNS 5
 
 #define LV_LOADSAVE 1
 #define LV_HARDDISK 2
@@ -4020,7 +4029,8 @@ static int clicked_entry = -1;
 #define LV_INPUTMAP 6
 #define LV_MISC1 7
 #define LV_CD 8
-#define LV_MAX 9
+#define LV_BOARD 9
+#define LV_MAX 10
 
 static int lv_oldidx[LV_MAX];
 static int lv_old_type = -1;
@@ -4043,7 +4053,8 @@ static const struct miscentry misclist[] = {
        { 0, 1, _T("Use CTRL-F11 to quit"), &workprefs.win32_ctrl_F11_is_quit },
        { 0, 1, _T("Don't show taskbar button"), &workprefs.win32_notaskbarbutton },
        { 0, 1, _T("Don't show notification icon"), &workprefs.win32_nonotificationicon },
-       { 0, 1, _T("Always on top"), &workprefs.win32_alwaysontop },
+       { 0, 1, _T("Emulator window always on top"), &workprefs.win32_main_alwaysontop },
+       { 0, 1, _T("GUI window always on top"), &workprefs.win32_gui_alwaysontop },
        { 0, 1, _T("Disable screensaver"), &workprefs.win32_powersavedisabled },
        { 0, 0, _T("Synchronize clock"), &workprefs.tod_hack },
        { 0, 1, _T("One second reboot pause"), &workprefs.reset_delay },
@@ -4114,7 +4125,17 @@ void InitializeListView (HWND hDlg)
                cachedlist = NULL;
        }
 
-       if (hDlg == pages[HARDDISK_ID]) {
+       if (hDlg == pages[BOARD_ID]) {
+               listview_num_columns = BOARD_COLUMNS;;
+               lv_type = LV_BOARD;
+               _tcscpy(column_heading[0], _T("Type"));
+               _tcscpy(column_heading[1], _T("Name"));
+               _tcscpy(column_heading[2], _T("Start"));
+               _tcscpy(column_heading[3], _T("Size"));
+               _tcscpy(column_heading[4], _T("ID"));
+               list = GetDlgItem(hDlg, IDC_BOARDLIST);
+
+       } else if (hDlg == pages[HARDDISK_ID]) {
 
                listview_num_columns = HARDDISK_COLUMNS;
                lv_type = LV_HARDDISK;
@@ -4209,7 +4230,65 @@ void InitializeListView (HWND hDlg)
                }
        }
 
-       if (lv_type == LV_MISC2) {
+       if (lv_type == LV_BOARD) {
+
+               listview_column_width[0] = 20;
+               listview_column_width[1] = 200;
+               listview_column_width[2] = 90;
+               listview_column_width[3] = 90;
+               listview_column_width[4] = 90;
+               i = 0;
+               if (full_property_sheet)
+                       expansion_generate_autoconfig_info(&workprefs);
+               struct autoconfig_info *acip = NULL;
+               for (;;) {
+                       TCHAR tmp[200];
+                       struct autoconfig_info *aci = expansion_get_autoconfig_data(full_property_sheet ? &workprefs : &currprefs, i);
+                       if (!aci)
+                               break;
+                       lvstruct.mask = LVIF_TEXT | LVIF_PARAM;
+                       if (aci->zorro >= 1 && aci->zorro <= 3)
+                               _stprintf(tmp, _T("Z%d"), aci->zorro);
+                       else
+                               _tcscpy(tmp, _T("-"));
+                       lvstruct.pszText = tmp;
+                       lvstruct.lParam = 0;
+                       lvstruct.iItem = i;
+                       lvstruct.iSubItem = 0;
+                       result = ListView_InsertItem(list, &lvstruct);
+                       tmp[0] = 0;
+                       TCHAR *s = tmp + _tcslen(tmp);
+                       if (aci->parent_of_previous) {
+                               if (acip && (acip->parent_name || acip->parent_address_space || acip->parent_romtype))
+                                       _tcscat(s, _T(" -- "));
+                               else
+                                       _tcscat(s, _T(" - "));
+                       }
+                       if ((aci->parent_address_space || aci->parent_romtype) && !aci->parent_of_previous)
+                               _tcscat(s, _T("? "));
+                       _tcscat(s, aci->name);
+                       ListView_SetItemText(list, result, 1, tmp);
+                       if (aci->start != 0xffffffff)
+                               _stprintf(tmp, _T("0x%08x"), aci->start);
+                       else
+                               _tcscpy(tmp, _T("-"));
+                       ListView_SetItemText(list, result, 2, tmp);
+                       if (aci->size != 0)
+                               _stprintf(tmp, _T("0x%08x"), aci->size);
+                       else
+                               _tcscpy(tmp, _T("-"));
+                       ListView_SetItemText(list, result, 3, tmp);
+                       if (aci->autoconfig_bytes[0] != 0xff)
+                               _stprintf(tmp, _T("0x%04x/0x%02x"),
+                                       (aci->autoconfig_bytes[4] << 8) | aci->autoconfig_bytes[5], aci->autoconfig_bytes[1]);
+                       else
+                               _tcscpy(tmp, _T("-"));
+                       ListView_SetItemText(list, result, 4, tmp);
+                       i++;
+                       acip = aci;
+               }
+
+       } else if (lv_type == LV_MISC2) {
 
                listview_column_width[0] = 180;
                listview_column_width[1] = 10;
@@ -4222,6 +4301,7 @@ void InitializeListView (HWND hDlg)
                        result = ListView_InsertItem (list, &lvstruct);
                        ListView_SetItemText (list, result, 1, exts[i].enabled ? _T("*") : _T(""));
                }
+
        } else if (lv_type == LV_INPUT) {
 
                for (i = 0; input_total_devices && i < inputdevice_get_widget_num (input_selected_device); i++) {
@@ -4373,7 +4453,7 @@ void InitializeListView (HWND hDlg)
 
        } else if (lv_type == LV_HARDDISK) {
 #ifdef FILESYS
-               listview_column_width[1] = 60;
+               listview_column_width[1] = 80;
                for (i = 0; i < workprefs.mountitems; i++)
                {
                        struct uaedev_config_data *uci = &workprefs.mountconfig[i];
@@ -4453,16 +4533,18 @@ void InitializeListView (HWND hDlg)
                                }
                                harddisktype (volname_str, ci);
                                _tcscpy (bootpri_str, _T("n/a"));
-                       } else if (ctype == HD_CONTROLLER_TYPE_PCMCIA_SRAM) {
-                               _tcscpy (blocksize_str, _T("n/a"));
-                               _tcscpy(devname_str, _T("PCMCIA SRAM:0"));
-                               _tcscpy (volname_str, _T("PCMCIA"));
-                               _tcscpy (bootpri_str, _T("n/a"));
-                       } else if (ctype == HD_CONTROLLER_TYPE_PCMCIA_IDE) {
-                               _tcscpy (blocksize_str, _T("n/a"));
-                               _tcscpy(devname_str, _T("PCMCIA IDE:0"));
-                               _tcscpy (volname_str, _T("PCMCIA"));
-                               _tcscpy (bootpri_str, _T("n/a"));
+                       } else if (ctype == HD_CONTROLLER_TYPE_PCMCIA) {
+                               if (ci->controller_type_unit == 0) {
+                                       _tcscpy (blocksize_str, _T("n/a"));
+                                       _tcscpy(devname_str, _T("PCMCIA SRAM"));
+                                       _tcscpy (volname_str, _T("PCMCIA"));
+                                       _tcscpy (bootpri_str, _T("n/a"));
+                               } else {
+                                       _tcscpy (blocksize_str, _T("n/a"));
+                                       _tcscpy(devname_str, _T("PCMCIA IDE"));
+                                       _tcscpy (volname_str, _T("PCMCIA"));
+                                       _tcscpy (bootpri_str, _T("n/a"));
+                               }
                        } else if (type == FILESYS_HARDFILE) {
                                _stprintf (blocksize_str, _T("%d"), ci->blocksize);
                                _tcscpy (devname_str, ci->devname);
@@ -5219,7 +5301,7 @@ static urlinfo urls[] =
 //     {IDC_UAEHOME, FALSE, _T("UAE Home Page"), _T("http://www.amigaemulator.org/")},
        {IDC_WINUAEHOME, FALSE, _T("WinUAE Home Page"), _T("http://www.winuae.net/")},
 //     {IDC_AIABHOME, FALSE, _T("AIAB"), _T("http://www.amigainabox.co.uk/")},
-       {IDC_THEROOTS, FALSE, _T("Back To The Roots"), _T("http://back2roots.abime.net/")},
+//     {IDC_THEROOTS, FALSE, _T("Back To The Roots"), _T("http://back2roots.abime.net/")},
        {IDC_ABIME, FALSE, _T("abime.net"), _T("http://www.abime.net/")},
        {IDC_CAPS, FALSE, _T("SPS"), _T("http://www.softpres.org/")},
        {IDC_AMIGASYS, FALSE, _T("AmigaSYS"), _T("http://www.amigasys.com/")},
@@ -7136,6 +7218,16 @@ static void values_from_displaydlg (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l
                                ew (hDlg, IDC_RATE2TEXT, cr->locked != 0);
                        } else {
                                cr->locked = ischecked (hDlg, IDC_RATE2ENABLE) != 0;
+                               if (cr->locked) {
+                                       cr->inuse = true;
+                               } else {
+                                       // deactivate if plain uncustomized PAL or NTSC
+                                       if (!cr->commands[0] && !cr->filterprofile[0] && cr->resolution == 7 &&
+                                               cr->horiz < 0 && cr->vert < 0 && cr->lace < 0 && cr->vsync < 0 && cr->framelength < 0 &&
+                                               (cr == &workprefs.cr[CHIPSET_REFRESH_PAL] || cr == &workprefs.cr[CHIPSET_REFRESH_NTSC])) {
+                                               cr->inuse = false;
+                                       }
+                               }
                        }
                        break;
                }
@@ -7714,6 +7806,8 @@ static void values_from_chipsetdlg2 (HWND hDlg, UINT msg, WPARAM wParam, LPARAM
        workprefs.cs_bytecustomwritebug = ischecked(hDlg, IDC_CS_BYTECUSTOMWRITEBUG);
        workprefs.cs_color_burst = ischecked(hDlg, IDC_CS_COMPOSITECOLOR);
 
+       cfgfile_compatibility_romtype(&workprefs);
+
        if (workprefs.cs_rtc) {
                txt[0] = 0;
                SendDlgItemMessage (hDlg, IDC_CS_RTCADJUST, WM_GETTEXT, (WPARAM)sizeof (txt) / sizeof (TCHAR), (LPARAM)txt);
@@ -7827,16 +7921,15 @@ static INT_PTR CALLBACK ChipsetDlgProc2 (HWND hDlg, UINT msg, WPARAM wParam, LPA
        return FALSE;
 }
 
+static int fastram_select;
+static uae_u32 *fastram_select_pointer;
+static const int *fastram_select_msi;
+static struct ramboard *fastram_select_ramboard;
+
+
 static void enable_for_memorydlg (HWND hDlg)
 {
-       int fast = true;
-       int z3 = true;
-       int mbram2 = z3;
-
-       if (cpuboard_memorytype(&workprefs) == BOARD_MEMORY_HIGHMEM)
-               mbram2 = false;
-       if (cpuboard_memorytype(&workprefs) == BOARD_MEMORY_Z2)
-               fast = false;
+       int z3 = workprefs.address_space_24 == false;
 
 #ifndef AUTOCONFIG
        z3 = FALSE;
@@ -7849,39 +7942,224 @@ static void enable_for_memorydlg (HWND hDlg)
        ew (hDlg, IDC_Z3CHIPMEM, z3);
        ew (hDlg, IDC_FASTMEM, true);
        ew (hDlg, IDC_FASTRAM, true);
-       ew (hDlg, IDC_FASTMEM2, fast);
-       ew (hDlg, IDC_FASTRAM2, fast);
-       ew (hDlg, IDC_FASTMEMAUTOCONFIG, fast);
        ew (hDlg, IDC_Z3MAPPING, z3);
-       ew (hDlg, IDC_FASTTEXT, fast);
-       ew (hDlg, IDC_GFXCARDTEXT, z3);
-       ew (hDlg, IDC_MBRAM1, z3);
-       ew (hDlg, IDC_MBMEM1, z3);
-       ew (hDlg, IDC_MBRAM2, mbram2);
-       ew (hDlg, IDC_MBMEM2, mbram2);
+       ew (hDlg, IDC_FASTTEXT, true);
+
+       bool isfast = fastram_select < 2 * MAX_RAM_BOARDS;
+       ew(hDlg, IDC_AUTOCONFIG_MANUFACTURER, isfast);
+       ew(hDlg, IDC_AUTOCONFIG_PRODUCT, isfast);
+       ew(hDlg, IDC_AUTOCONFIG_DATA, fastram_select_ramboard && fastram_select_ramboard->autoconfig_inuse);
+       ew(hDlg, IDC_FASTMEMAUTOCONFIGUSE, isfast);
+       ew(hDlg, IDC_MEMORYRAM, true);
+       ew(hDlg, IDC_MEMORYMEM, true);
+}
+
+static void setfastram_selectmenu(HWND hDlg, int mode)
+{
+       int min;
+       int max;
+       const int *msi;
+       TCHAR tmp[200];
+
+       fastram_select_ramboard = NULL;
+       if (fastram_select < MAX_RAM_BOARDS) {
+               msi = msi_fast;
+               min = MIN_FAST_MEM;
+               max = MAX_FAST_MEM;
+               fastram_select_ramboard = &workprefs.fastmem[fastram_select];
+               fastram_select_pointer = &fastram_select_ramboard->size;
+       } else if (fastram_select >= MAX_RAM_BOARDS && fastram_select < MAX_RAM_BOARDS * 2) {
+               msi = msi_z3fast;
+               min = MIN_Z3_MEM;
+               max = MAX_Z3_MEM;
+               fastram_select_ramboard = &workprefs.z3fastmem[fastram_select - MAX_RAM_BOARDS];
+               fastram_select_pointer = &fastram_select_ramboard->size;
+       } else if (fastram_select == 2 * MAX_RAM_BOARDS) {
+               min = 0;
+               max = MAX_CB_MEM_128M;
+               msi = msi_cpuboard;
+               fastram_select_pointer = &workprefs.mbresmem_high_size;
+       } else if (fastram_select == 2 * MAX_RAM_BOARDS + 1) {
+               min = 0;
+               max = MAX_CB_MEM_64M;
+               msi = msi_cpuboard;
+               fastram_select_pointer = &workprefs.mbresmem_low_size;
+       } else {
+               return;
+       }
+
+       fastram_select_msi = msi;
+       uae_u32 v = *fastram_select_pointer;
+       int mem_size = 0;
+       if (msi == msi_fast) {
+               switch (v)
+               {
+               case 0x00000000: mem_size = 0; break;
+               case 0x00010000: mem_size = 1; break;
+               case 0x00020000: mem_size = 2; break;
+               case 0x00040000: mem_size = 3; break;
+               case 0x00080000: mem_size = 4; break;
+               case 0x00100000: mem_size = 5; break;
+               case 0x00200000: mem_size = 6; break;
+               case 0x00400000: mem_size = 7; break;
+               case 0x00800000: mem_size = 8; break;
+               case 0x01000000: mem_size = 9; break;
+               }
+       } else {
+               if (v < 0x00100000)
+                       mem_size = 0;
+               else if (v < 0x00200000)
+                       mem_size = 1;
+               else if (v < 0x00400000)
+                       mem_size = 2;
+               else if (v < 0x00800000)
+                       mem_size = 3;
+               else if (v < 0x01000000)
+                       mem_size = 4;
+               else if (v < 0x02000000)
+                       mem_size = 5;
+               else if (v < 0x04000000)
+                       mem_size = 6;
+               else if (v < 0x08000000)
+                       mem_size = 7;
+               else if (v < 0x10000000)
+                       mem_size = 8;
+               else if (v < 0x20000000)
+                       mem_size = 9;
+               else if (v < 0x40000000)
+                       mem_size = 10;
+               else // 1GB
+                       mem_size = 11;
+       }
+       SendDlgItemMessage(hDlg, IDC_MEMORYMEM, TBM_SETRANGE, TRUE, MAKELONG(min, max));
+       SendDlgItemMessage(hDlg, IDC_MEMORYMEM, TBM_SETPOS, TRUE, mem_size);
+       SetDlgItemText(hDlg, IDC_MEMORYRAM, memsize_names[msi[mem_size]]);
+
+       expansion_generate_autoconfig_info(&workprefs);
+       struct ramboard *rb = fastram_select_ramboard;
+       if (rb) {
+               struct autoconfig_info *aci = expansion_get_autoconfig_info(&workprefs, fastram_select < MAX_RAM_BOARDS ? ROMTYPE_RAMZ2 : ROMTYPE_RAMZ3, fastram_select % MAX_RAM_BOARDS);
+               if (!rb->autoconfig_inuse) {
+                       if (aci) {
+                               memcpy(rb->autoconfig, aci->autoconfig_bytes, sizeof rb->autoconfig);
+                       }
+                       if (rb->manufacturer) {
+                               rb->autoconfig[1] = rb->product;
+                               rb->autoconfig[4] = (rb->manufacturer >> 8) & 0xff;
+                               rb->autoconfig[5] = rb->manufacturer & 0xff;
+                       } else {
+                               memset(rb->autoconfig, 0, sizeof rb->autoconfig);
+                               aci = expansion_get_autoconfig_info(&workprefs, fastram_select < MAX_RAM_BOARDS ? ROMTYPE_RAMZ2 : ROMTYPE_RAMZ3, fastram_select % MAX_RAM_BOARDS);
+                               if (aci) {
+                                       memcpy(rb->autoconfig, aci->autoconfig_bytes, sizeof rb->autoconfig);
+                               }
+                       }
+               }
+               if (mode == 1 && rb->autoconfig_inuse) {
+                       rb->autoconfig[1] = rb->product;
+                       rb->autoconfig[4] = (rb->manufacturer >> 8) & 0xff;
+                       rb->autoconfig[5] = rb->manufacturer & 0xff;
+               }
+               if (mode != 2) {
+                       tmp[0] = 0;
+                       TCHAR *p = tmp;
+                       for (int i = 0; i < 12; i++) {
+                               if (i > 0)
+                                       _tcscat(p, _T("."));
+                               _stprintf(p + _tcslen(p), _T("%02x"), rb->autoconfig[i]);
+                       }
+                       SetDlgItemText(hDlg, IDC_AUTOCONFIG_DATA, tmp);
+               }
+               if (rb->autoconfig_inuse) {
+                       rb->product = rb->autoconfig[1];
+                       rb->manufacturer = (rb->autoconfig[4] << 8) | rb->autoconfig[5];
+               }
+               if (mode != 1) {
+                       if (rb->manufacturer) {
+                               _stprintf(tmp, _T("%d"), rb->manufacturer);
+                               SetDlgItemText(hDlg, IDC_AUTOCONFIG_MANUFACTURER, tmp);
+                               _stprintf(tmp, _T("%d"), rb->product);
+                               SetDlgItemText(hDlg, IDC_AUTOCONFIG_PRODUCT, tmp);
+                       } else {
+                               rb->product = 0;
+                               SetDlgItemText(hDlg, IDC_AUTOCONFIG_MANUFACTURER, _T(""));
+                               SetDlgItemText(hDlg, IDC_AUTOCONFIG_PRODUCT, _T(""));
+                       }
+               }
+       } else {
+               SetDlgItemText(hDlg, IDC_AUTOCONFIG_MANUFACTURER, _T(""));
+               SetDlgItemText(hDlg, IDC_AUTOCONFIG_PRODUCT, _T(""));
+       }
+
+       SendDlgItemMessage(hDlg, IDC_MEMORYSELECT, CB_RESETCONTENT, 0, 0);
+       for (int i = 0; i < MAX_RAM_BOARDS; i++) {
+               struct autoconfig_info *aci = expansion_get_autoconfig_info(&workprefs, ROMTYPE_RAMZ2, i);
+               _stprintf(tmp, _T("Z2 Fast Ram #%d"), i + 1);
+               if (workprefs.fastmem[i].size)
+                       _stprintf(tmp + _tcslen(tmp), _T(" [%dk]"), workprefs.fastmem[i].size / 1024);
+               if (aci && aci->cst) {
+                       _stprintf(tmp + _tcslen(tmp), _T(" (%s)"), aci->cst->name);
+               } else if (aci && aci->ert) {
+                       _stprintf(tmp + _tcslen(tmp), _T(" (%s)"), aci->ert->friendlyname);
+               }
+               SendDlgItemMessage(hDlg, IDC_MEMORYSELECT, CB_ADDSTRING, 0, (LPARAM)tmp);
+       }
+       if (!workprefs.address_space_24) {
+               for (int i = 0; i < MAX_RAM_BOARDS; i++) {
+                       struct autoconfig_info *aci = expansion_get_autoconfig_info(&workprefs, ROMTYPE_RAMZ3, i);
+                       _stprintf(tmp, _T("Z3 Fast Ram #%d"), i + 1);
+                       if (workprefs.z3fastmem[i].size)
+                               _stprintf(tmp + _tcslen(tmp), _T(" [%dM]"), workprefs.z3fastmem[i].size / (1024 * 1024));
+                       if (aci && aci->cst) {
+                               _stprintf(tmp + _tcslen(tmp), _T(" (%s)"), aci->cst->name);
+                       } else if (aci && aci->ert) {
+                               _stprintf(tmp + _tcslen(tmp), _T(" (%s)"), aci->ert->friendlyname);
+                       }
+                       SendDlgItemMessage(hDlg, IDC_MEMORYSELECT, CB_ADDSTRING, 0, (LPARAM)tmp);
+               }
+               _tcscpy(tmp, _T("Motherboard Fast RAM"));
+               if (workprefs.mbresmem_high_size)
+                       _stprintf(tmp + _tcslen(tmp), _T(" [%dM]"), workprefs.mbresmem_high_size / (1024 * 1024));
+               SendDlgItemMessage(hDlg, IDC_MEMORYSELECT, CB_ADDSTRING, 0, (LPARAM)tmp);
+               _tcscpy(tmp, _T("Processor Slot Fast RAM"));
+               if (workprefs.mbresmem_low_size)
+                       _stprintf(tmp + _tcslen(tmp), _T(" [%dM]"), workprefs.mbresmem_low_size / (1024 * 1024));
+               SendDlgItemMessage(hDlg, IDC_MEMORYSELECT, CB_ADDSTRING, 0, (LPARAM)tmp);
+       } else {
+               if (fastram_select >= MAX_RAM_BOARDS)
+                       fastram_select = 0;
+       }
+       SendDlgItemMessage(hDlg, IDC_MEMORYSELECT, CB_SETCURSEL, fastram_select, 0);
+
+       enable_for_memorydlg(hDlg);
 }
 
 extern uae_u32 natmem_reserved_size;
 static void setmax32bitram (HWND hDlg)
 {
        TCHAR tmp[256];
-       uae_u32 size, rtgz3size, z3size_uae = 0, z3size_real = 0;
-       uae_u32 sizealign = 16 * 1024 * 1024 - 1;
-
-       rtgz3size = gfxboard_get_configtype(&workprefs.rtgboards[0]) == 3 ? workprefs.rtgboards[0].rtgmem_size : 0;
-       size = ((workprefs.z3fastmem_size + sizealign) & ~sizealign) + ((workprefs.z3fastmem2_size + sizealign) & ~sizealign) +
-               ((rtgz3size + sizealign) & ~sizealign);
-       if (cfgfile_board_enabled(&currprefs, ROMTYPE_A4091, 0))
-               size += 2 * 16 * 1024 * 1024;
-       if (changed_prefs.mbresmem_high_size >= 128 * 1024 * 1024 && (size || workprefs.z3chipmem_size))
-               size += (changed_prefs.mbresmem_high_size - 128 * 1024 * 1024) + 16 * 1024 * 1024;
-       if (natmem_reserved_size > 0x40000000)
-               z3size_real = natmem_reserved_size - 0x40000000;
-       if (natmem_reserved_size > 0x10000000)
-               z3size_uae = natmem_reserved_size - 0x10000000;
-       size += ((workprefs.z3chipmem_size + sizealign) & ~sizealign);
-       _stprintf (tmp, L"Configured 32-bit RAM: %dM, reserved: %dM, Z3 available: %dM (UAE), %dM (Real)",
-               size / (1024 * 1024), (natmem_reserved_size - 256 * 1024 * 1024) / (1024 * 1024), z3size_uae / (1024 * 1024), z3size_real / (1024 * 1024));
+       uae_u32 size32 = 0, z3size_uae = 0, z3size_real = 0;
+
+       z3size_uae = natmem_reserved_size >= expamem_z3_pointer_uae ? natmem_reserved_size - expamem_z3_pointer_uae : 0;
+       z3size_real = natmem_reserved_size >= expamem_z3_pointer_real ? natmem_reserved_size - expamem_z3_pointer_real : 0;
+
+       uae_u32 first = 0;
+       int idx = 0;
+       for (;;) {
+               struct autoconfig_info *aci = expansion_get_autoconfig_data(&workprefs, idx);
+               if (!aci)
+                       break;
+               if (aci->start >= 0x10000000 && !first)
+                       first = aci->start;
+               if (aci->start >= 0x10000000 && aci->start + aci->size > size32)
+                       size32 = aci->start + aci->size;
+               idx++;
+       }
+       if (size32 >= first)
+               size32 -= first;
+
+       _stprintf (tmp, L"Configured 32-bit address space: %dM, reserved: %dM, Z3 available: %dM (UAE), %dM (Real)",
+               size32 / (1024 * 1024), (natmem_reserved_size - 256 * 1024 * 1024) / (1024 * 1024), z3size_uae / (1024 * 1024), z3size_real / (1024 * 1024));
        SetDlgItemText (hDlg, IDC_MAX32RAM, tmp);
 }
 
@@ -7891,7 +8169,7 @@ static void setcpuboardmemsize(HWND hDlg)
                workprefs.cpuboardmem1_size = cpuboard_maxmemory(&workprefs);
 
        if (cpuboard_memorytype(&workprefs) == BOARD_MEMORY_Z2) {
-               workprefs.fastmem2_size = workprefs.cpuboardmem1_size;
+               workprefs.fastmem[0].size = workprefs.cpuboardmem1_size;
        }
        if (cpuboard_memorytype(&workprefs) == BOARD_MEMORY_25BITMEM) {
                workprefs.mem25bit_size = workprefs.cpuboardmem1_size;
@@ -7972,7 +8250,7 @@ static void values_to_memorydlg (HWND hDlg)
 
 
        mem_size = 0;
-       switch (workprefs.fastmem_size) {
+       switch (workprefs.fastmem[0].size) {
        case 0x00000000: mem_size = 0; break;
        case 0x00010000: mem_size = 1; break;
        case 0x00020000: mem_size = 2; break;
@@ -7987,22 +8265,6 @@ static void values_to_memorydlg (HWND hDlg)
        SendDlgItemMessage (hDlg, IDC_FASTMEM, TBM_SETPOS, TRUE, mem_size);
        SetDlgItemText (hDlg, IDC_FASTRAM, memsize_names[msi_fast[mem_size]]);
 
-       mem_size = 0;
-       switch (workprefs.fastmem2_size) {
-       case 0x00000000: mem_size = 0; break;
-       case 0x00010000: mem_size = 1; break;
-       case 0x00020000: mem_size = 2; break;
-       case 0x00040000: mem_size = 3; break;
-       case 0x00080000: mem_size = 4; break;
-       case 0x00100000: mem_size = 5; break;
-       case 0x00200000: mem_size = 6; break;
-       case 0x00400000: mem_size = 7; break;
-       case 0x00800000: mem_size = 8; break;
-       case 0x01000000: mem_size = 9; break;
-       }
-       SendDlgItemMessage (hDlg, IDC_FASTMEM2, TBM_SETPOS, TRUE, mem_size);
-       SetDlgItemText (hDlg, IDC_FASTRAM2, memsize_names[msi_fast[mem_size]]);
-
        mem_size = 0;
        switch (workprefs.bogomem_size) {
        case 0x00000000: mem_size = 0; break;
@@ -8015,8 +8277,8 @@ static void values_to_memorydlg (HWND hDlg)
        SetDlgItemText (hDlg, IDC_SLOWRAM, memsize_names[msi_bogo[mem_size]]);
 
        mem_size = 0;
-       v = workprefs.z3fastmem_size + workprefs.z3fastmem2_size;
-       if      (v < 0x00100000)
+       v = workprefs.z3fastmem[0].size;
+       if (v < 0x00100000)
                mem_size = 0;
        else if (v < 0x00200000)
                mem_size = 1;
@@ -8034,24 +8296,12 @@ static void values_to_memorydlg (HWND hDlg)
                mem_size = 7;
        else if (v < 0x10000000)
                mem_size = 8;
-       else if (v < 0x18000000)
-               mem_size = 9;
        else if (v < 0x20000000)
+               mem_size = 9;
+       else if (v < 0x40000000)
                mem_size = 10;
-       else if (v < 0x30000000)
+       else // 1GB
                mem_size = 11;
-       else if (v < 0x40000000) // 1GB
-               mem_size = 12;
-       else if (v < 0x60000000) // 1.5GB
-               mem_size = 13;
-       else if (v < 0x80000000) // 2GB
-               mem_size = 14;
-       else if (v < 0xA8000000) // 2.5GB
-               mem_size = 15;
-       else if (v < 0xC0000000) // 3GB
-               mem_size = 16;
-       else
-               mem_size = 17;
        SendDlgItemMessage (hDlg, IDC_Z3FASTMEM, TBM_SETPOS, TRUE, mem_size);
        SetDlgItemText (hDlg, IDC_Z3FASTRAM, memsize_names[msi_z3fast[mem_size]]);
 
@@ -8080,7 +8330,7 @@ static void values_to_memorydlg (HWND hDlg)
 
        SendDlgItemMessage (hDlg, IDC_Z3CHIPMEM, TBM_SETPOS, TRUE, mem_size);
        SetDlgItemText (hDlg, IDC_Z3CHIPRAM, memsize_names[msi_z3chip[mem_size]]);
-
+#if 0
        mem_size = 0;
        switch (workprefs.mbresmem_low_size) {
        case 0x00000000: mem_size = 0; break;
@@ -8109,7 +8359,7 @@ static void values_to_memorydlg (HWND hDlg)
        }
        SendDlgItemMessage (hDlg, IDC_MBMEM2, TBM_SETPOS, TRUE, mem_size);
        SetDlgItemText (hDlg, IDC_MBRAM2, memsize_names[msi_gfx[mem_size]]);
-
+#endif
        setmax32bitram (hDlg);
 
 }
@@ -8118,54 +8368,15 @@ static void fix_values_memorydlg (void)
 {
        if (workprefs.chipmem_size <= 0x200000)
                return;
-       if (workprefs.fastmem_size > 262144)
-               workprefs.fastmem_size = 262144;
-       if (workprefs.fastmem2_size > 262144)
-               workprefs.fastmem2_size = 262144;
-       if (workprefs.fastmem_size + workprefs.fastmem2_size > 262144) {
-               workprefs.fastmem_size = 0;
-               workprefs.fastmem2_size = 0;
-       }
-}
-static void updatez3 (uae_u32 *size1p, uae_u32 *size2p)
-{
-       int i;
-       uae_u32 s1, s2;
-
-       // no 2GB Z3 size so we need 2x1G
-       if (*size1p >= 0x80000000) {
-               *size2p = *size1p - 0x40000000;
-               *size1p = 0x40000000;
-               return;
-       }
-       s1 = *size1p;
-       *size1p = 0;
-       *size2p = 0;
-       s2 = 0;
-       for (i = 32; i >= 0; i--) {
-               if (s1 & (1 << i))
-                       break;
-       }
-       if (i < 20)
-               return;
-       if (s1 == (1 << i)) {
-               *size1p = s1;
-               return;
-       }
-       s2 = s1 & ((1 << i) - 1);
-       s1 = 1 << i;
-       i--;
-       while (i >= 0) {
-               if (s2 & (1 << i)) {
-                       s2 = 1 << i;
-                       break;
+       int total = 0;
+       for (int i = 0; i < MAX_RAM_BOARDS; i++) {
+               if (workprefs.fastmem[i].size > 262144)
+                       workprefs.fastmem[i].size = 262144;
+               total += workprefs.fastmem[i].size;
+               if (total > 262144) {
+                       workprefs.fastmem[i].size = 0;
                }
-               i--;
        }
-       if (i < 19)
-               s2 = 0;
-       *size1p = s1;
-       *size2p = s2;
 }
 
 static void addromfiles(UAEREG *fkey, HWND hDlg, DWORD d, const TCHAR *path, int type1, int type2)
@@ -8409,7 +8620,7 @@ static void expansion_net (HWND hDlg)
        SendDlgItemMessage (hDlg, IDC_NETDEVICE, CB_RESETCONTENT, 0, 0);
        WIN32GUI_LoadUIString (IDS_NETDISCONNECTED, tmp, sizeof tmp / sizeof (TCHAR));
        SendDlgItemMessage (hDlg, IDC_NETDEVICE, CB_ADDSTRING, 0, (LPARAM)tmp);
-       if (!_tcsicmp (workprefs.a2065name, _T("none")) && !_tcsicmp(workprefs.ne2000pciname, _T("none"))) {
+       if (!_tcsicmp (workprefs.a2065name, _T("none")) && !_tcsicmp(workprefs.ne2000pciname, _T("none")) && !_tcsicmp(workprefs.ne2000pcmcianame, _T("none"))) {
                SendDlgItemMessage (hDlg, IDC_NETDEVICE, CB_SETCURSEL, 0, 0);
                notset = false;
        }
@@ -8427,7 +8638,8 @@ static void expansion_net (HWND hDlg)
                        _stprintf (tmp, _T("%s %s"), mac, ndd[i]->desc);
                        SendDlgItemMessage (hDlg, IDC_NETDEVICE, CB_ADDSTRING, 0, (LPARAM)tmp);
                        if (!_tcsicmp (workprefs.a2065name, mac) || !_tcsicmp (workprefs.a2065name, ndd[i]->name) ||
-                               !_tcsicmp(workprefs.ne2000pciname, mac) || !_tcsicmp(workprefs.ne2000pciname, ndd[i]->name)) {
+                               !_tcsicmp(workprefs.ne2000pciname, mac) || !_tcsicmp(workprefs.ne2000pciname, ndd[i]->name) ||
+                               !_tcsicmp(workprefs.ne2000pcmcianame, mac) || !_tcsicmp(workprefs.ne2000pcmcianame, ndd[i]->name)) {
                                SendDlgItemMessage (hDlg, IDC_NETDEVICE, CB_SETCURSEL, cnt, 0);
                                notset = false;
                        }
@@ -8438,7 +8650,11 @@ static void expansion_net (HWND hDlg)
                SendDlgItemMessage (hDlg, IDC_NETDEVICE, CB_SETCURSEL, 0, 0);
 }
 
-static const int scsiromselectedmask[] = { EXPANSIONTYPE_SCSI, EXPANSIONTYPE_IDE, EXPANSIONTYPE_SASI, EXPANSIONTYPE_CUSTOM, EXPANSIONTYPE_PCI_BRIDGE, EXPANSIONTYPE_X86_BRIDGE, EXPANSIONTYPE_RTG };
+static const int scsiromselectedmask[] = {
+       EXPANSIONTYPE_INTERNAL, EXPANSIONTYPE_SCSI, EXPANSIONTYPE_IDE, EXPANSIONTYPE_SASI, EXPANSIONTYPE_CUSTOM,
+       EXPANSIONTYPE_PCI_BRIDGE, EXPANSIONTYPE_X86_BRIDGE, EXPANSIONTYPE_RTG,
+       EXPANSIONTYPE_SOUND, EXPANSIONTYPE_NET, EXPANSIONTYPE_FLOPPY
+};
 static void init_expansion2(HWND hDlg, bool init)
 {
        static int first = -1;
@@ -8446,17 +8662,22 @@ static void init_expansion2(HWND hDlg, bool init)
 
        for (;;) {
                bool matched = false;
+               int *idtab;
+               int total = 0;
                SendDlgItemMessage(hDlg, IDC_SCSIROMSELECT, CB_RESETCONTENT, 0, 0);
                scsiromselect_table[0] = -1;
                for (int i = 0; expansionroms[i].name; i++) {
-                       TCHAR name[256];
+                       total++;
+               }
+               idtab = xcalloc(int, total * 2);
+               int idcnt = 0;
+               for (int i = 0; expansionroms[i].name; i++) {
                        if (expansionroms[i].romtype & ROMTYPE_CPUBOARD)
                                continue;
                        if (!(expansionroms[i].deviceflags & scsiromselectedmask[scsiromselectedcatnum]))
                                continue;
                        if (scsiromselectedcatnum == 0 && (expansionroms[i].deviceflags & (EXPANSIONTYPE_SASI | EXPANSIONTYPE_CUSTOM)))
                                continue;
-                       name[0] = 0;
                        int cnt = 0;
                        for (int j = 0; j < MAX_DUPLICATE_EXPANSION_BOARDS; j++) {
                                if (cfgfile_board_enabled(&workprefs, expansionroms[i].romtype, j)) {
@@ -8469,18 +8690,40 @@ static void init_expansion2(HWND hDlg, bool init)
                                if (first < 0)
                                        first = i;
                        }
-                       if (cnt == 1)
-                               _tcscat(name, _T("* "));
-                       else if (cnt > 1)
-                               _stprintf(name + _tcslen(name), _T("[%d] "), cnt);
-                       _tcscat(name, expansionroms[i].friendlyname);
-                       if (expansionroms[i].friendlymanufacturer) {
-                               _tcscat(name, _T(" ("));
-                               _tcscat(name, expansionroms[i].friendlymanufacturer);
-                               _tcscat(name, _T(")"));
+                       idtab[idcnt++] = i;
+                       idtab[idcnt++] = cnt;
+               }
+               for (int j = 0; j < idcnt; j += 2) {
+                       TCHAR *nameval = NULL;
+                       int ididx = -1;
+                       for (int i = 0; i < idcnt; i += 2) {
+                               TCHAR name[256];
+                               int id = idtab[i];
+                               int cnt = idtab[i + 1];
+                               if (id < 0)
+                                       continue;
+                               name[0] = 0;
+                               if (cnt == 1)
+                                       _tcscat(name, _T("* "));
+                               else if (cnt > 1)
+                                       _stprintf(name + _tcslen(name), _T("[%d] "), cnt);
+                               _tcscat(name, expansionroms[id].friendlyname);
+                               if (expansionroms[id].friendlymanufacturer) {
+                                       _tcscat(name, _T(" ("));
+                                       _tcscat(name, expansionroms[id].friendlymanufacturer);
+                                       _tcscat(name, _T(")"));
+                               }
+                               if (!nameval || _tcsicmp(nameval, name) > 0) {
+                                       xfree(nameval);
+                                       nameval = my_strdup(name);
+                                       ididx = i;
+                               }
                        }
-                       gui_add_string(scsiromselect_table, hDlg, IDC_SCSIROMSELECT, i, name);
+                       gui_add_string(scsiromselect_table, hDlg, IDC_SCSIROMSELECT, idtab[ididx], nameval);
+                       idtab[ididx] = -1;
+                       xfree(nameval);
                }
+               xfree(idtab);
 
                if (scsiromselected > 0 && matched)
                        break;
@@ -8532,7 +8775,7 @@ static void init_expansion2(HWND hDlg, bool init)
        for (int i = 0; i < 8; i++) {
                TCHAR tmp[10];
                _stprintf(tmp, _T("%d"), i);
-               SendDlgItemMessage(hDlg, IDC_SCSIROMID, CB_ADDSTRING, 0, (LPARAM) tmp);
+               SendDlgItemMessage(hDlg, IDC_SCSIROMID, CB_ADDSTRING, 0, (LPARAM)tmp);
        }
 }
 
@@ -8686,26 +8929,51 @@ static void values_to_expansion2_expansion_roms(HWND hDlg, UAEREG *fkey)
                regclosetree(fkey);
 }
 
-static void values_to_expansion2_expansion_settings(HWND hDlg)
+#if 0
+static void createautoconfiginfo(struct autoconfig_info *aci, TCHAR *buf)
+{
+       TCHAR tmp2[200];
+       if (aci->autoconfig[0] == 0xff) {
+               buf[0] = 0;
+               return;
+       }
+       if (aci->start != 0xffffffff)
+               _stprintf(tmp2, _T("0x%08x-0x%08x"), aci->start, aci->start + aci->size - 1);
+       else
+               _tcscpy(tmp2, _T("--------"));
+       _stprintf(buf, _T("%u/%u [0x%04x/0x%02x] %s "),
+               (aci->autoconfig[4] << 8) | aci->autoconfig[5], aci->autoconfig[1],
+               (aci->autoconfig[4] << 8) | aci->autoconfig[5], aci->autoconfig[1],
+               tmp2
+       );
+       TCHAR *p = buf + _tcslen(buf);
+       for (int i = 0; i < 12; i++) {
+               if (i > 0)
+                       _tcscat(p, _T("."));
+               _stprintf(p + _tcslen(p), _T("%02x"), aci->autoconfig[i]);
+       }
+}
+#endif
+
+static void values_to_expansion2_expansion_settings(HWND hDlg, int mode)
 {
        int index;
        struct boardromconfig *brc;
-       const struct expansionromtype *ert = &expansionroms[scsiromselected];
-       brc = get_device_rom(&workprefs, expansionroms[scsiromselected].romtype, scsiromselectednum, &index);
-       if (brc) {
-               if (brc->roms[index].romfile[0])
-                       ew(hDlg, IDC_SCSIROMFILEAUTOBOOT, ert->autoboot_jumper);
-       } else {
-               if (brc)
-                       brc->roms[index].autoboot_disabled = false;
-               ew(hDlg, IDC_SCSIROMFILEAUTOBOOT, FALSE);
-               setchecked(hDlg, IDC_SCSIROMFILEAUTOBOOT, false);
+       if (scsiromselected) {
+               const struct expansionromtype *ert = &expansionroms[scsiromselected];
+               brc = get_device_rom(&workprefs, expansionroms[scsiromselected].romtype, scsiromselectednum, &index);
+               if (brc) {
+                       if (brc->roms[index].romfile[0])
+                               ew(hDlg, IDC_SCSIROMFILEAUTOBOOT, ert->autoboot_jumper);
+               } else {
+                       ew(hDlg, IDC_SCSIROMFILEAUTOBOOT, FALSE);
+                       setchecked(hDlg, IDC_SCSIROMFILEAUTOBOOT, false);
+               }
+               ew(hDlg, IDC_SCSIROMID, ert->id_jumper);
+               const struct expansionboardsettings *cbs = ert->settings;
+               create_expansionrom_gui(hDlg, &expansion_gui_item, cbs, brc ? brc->roms[index].device_settings : 0, IDC_EXPANSIONBOARDITEMSELECTOR, IDC_EXPANSIONBOARDSELECTOR, IDC_EXPANSIONBOARDCHECKBOX);
        }
-       ew(hDlg, IDC_SCSIROMID, ert->id_jumper);
 
-       const struct expansionboardsettings *cbs = ert->settings;
-
-       create_expansionrom_gui(hDlg, &expansion_gui_item, cbs, brc ? brc->roms[index].device_settings : 0, IDC_EXPANSIONBOARDITEMSELECTOR, IDC_EXPANSIONBOARDSELECTOR, IDC_EXPANSIONBOARDCHECKBOX);
 
 #if 0
        for (int i = 0; expansion_settings_id[i] >= 0; i++) {
@@ -8738,23 +9006,17 @@ static void enable_for_expansion2dlg (HWND hDlg)
 
        en = !!full_property_sheet;
        cw = catweasel_detect ();
-       ew (hDlg, IDC_CATWEASEL, cw && en);
-       ew (hDlg, IDC_SOCKETS, en);
-       ew (hDlg, IDC_SCSIDEVICE, en);
-       ew (hDlg, IDC_CATWEASEL, en);
-       ew (hDlg, IDC_NETDEVICE, en);
-       ew (hDlg, IDC_SANA2, en);
-       ew (hDlg, IDC_A2065, en);
-       ew (hDlg, IDC_NE2000, en);
-       ew (hDlg, IDC_NETDEVICE, en && (workprefs.a2065name[0] || workprefs.ne2000pciname[0]));
-
-       ShowWindow (GetDlgItem(hDlg, IDC_CS_SCSIMODE), SW_HIDE);
+       ew(hDlg, IDC_CATWEASEL, cw && en);
+       ew(hDlg, IDC_SOCKETS, en);
+       ew(hDlg, IDC_SCSIDEVICE, en);
+       ew(hDlg, IDC_CATWEASEL, en);
+       ew(hDlg, IDC_SANA2, en);
+       ew(hDlg, IDC_A2065, en);
+       ew(hDlg, IDC_NE2000, en);
+       ew(hDlg, IDC_NE2000PCMCIA, en || workprefs.cs_pcmcia);
+       ew(hDlg, IDC_NETDEVICE, (workprefs.cs_pcmcia && workprefs.ne2000pcmcianame) || (en && (workprefs.a2065name[0] || workprefs.ne2000pciname[0])));
+
        ew(hDlg, IDC_CS_CD32FMV, en);
-       ew(hDlg, IDC_CS_TOCCATA, en);
-       ew(hDlg, IDC_CS_TOCCATAMIXER, en && workprefs.sound_toccata);
-       ew(hDlg, IDC_CS_ES1370, en);
-       ew(hDlg, IDC_CS_FM801, en);
-       ew (hDlg, IDC_CS_SCSIMODE, FALSE);
 
        ew(hDlg, IDC_CPUBOARDROMFILE, workprefs.cpuboard_type != 0);
        ew(hDlg, IDC_CPUBOARDROMCHOOSER, workprefs.cpuboard_type != 0);
@@ -8780,24 +9042,20 @@ static void enable_for_expansion2dlg (HWND hDlg)
 #endif
 }
 
-static void values_to_expansion2dlg (HWND hDlg)
+static void values_to_expansion2dlg (HWND hDlg, int mode)
 {
        int cw;
        int index;
        struct boardromconfig *brc;
 
-       CheckDlgButton (hDlg, IDC_SOCKETS, workprefs.socket_emu);
-       CheckDlgButton (hDlg, IDC_CATWEASEL, workprefs.catweasel);
-       CheckDlgButton (hDlg, IDC_SCSIDEVICE, workprefs.scsi == 1);
-       CheckDlgButton (hDlg, IDC_SANA2, workprefs.sana2);
+       CheckDlgButton(hDlg, IDC_SOCKETS, workprefs.socket_emu);
+       CheckDlgButton(hDlg, IDC_CATWEASEL, workprefs.catweasel);
+       CheckDlgButton(hDlg, IDC_SCSIDEVICE, workprefs.scsi == 1);
+       CheckDlgButton(hDlg, IDC_SANA2, workprefs.sana2);
        CheckDlgButton(hDlg, IDC_A2065, workprefs.a2065name[0] ? 1 : 0);
        CheckDlgButton(hDlg, IDC_NE2000, workprefs.ne2000pciname[0] ? 1 : 0);
+       CheckDlgButton(hDlg, IDC_NE2000PCMCIA, workprefs.ne2000pcmcianame[0] ? 1 : 0);
        CheckDlgButton(hDlg, IDC_CS_CD32FMV, workprefs.cs_cd32fmv);
-       CheckDlgButton(hDlg, IDC_CS_TOCCATA, workprefs.sound_toccata);
-       CheckDlgButton(hDlg, IDC_CS_TOCCATAMIXER, workprefs.sound_toccata_mixer);
-       CheckDlgButton(hDlg, IDC_CS_ES1370, workprefs.sound_es1370);
-       CheckDlgButton(hDlg, IDC_CS_FM801, workprefs.sound_fm801);
-       CheckDlgButton(hDlg, IDC_CS_SCSIMODE, workprefs.scsi == 2);
        cw = catweasel_detect ();
        ew (hDlg, IDC_CATWEASEL, cw);
        if (!cw && workprefs.catweasel < 100)
@@ -8808,7 +9066,7 @@ static void values_to_expansion2dlg (HWND hDlg)
 
        values_to_expansion2_expansion_roms(hDlg, fkey);
 
-       values_to_expansion2_expansion_settings(hDlg);
+       values_to_expansion2_expansion_settings(hDlg, mode);
 
        if (workprefs.cpuboard_type) {
                const struct cpuboardsubtype *cst = &cpuboards[workprefs.cpuboard_type].subtypes[workprefs.cpuboard_subtype];
@@ -8856,26 +9114,7 @@ static void updatecpuboardsubtypes(HWND hDlg)
 #endif
 }
 
-static void set_expansion_rtg_rom(void)
-{
-       int idx;
-       uae_u32 romtype = gfxboard_get_romtype(&workprefs.rtgboards[0]);
-       if (romtype) {
-               struct boardromconfig *bc = get_device_rom_new(&workprefs, romtype, 0, &idx);
-               if (bc && bc->roms[idx].romfile[0] == 0) {
-                       _tcscpy(bc->roms[idx].romfile, _T(":NOROM"));
-               }
-       }
-       for (int i = 0; expansionroms[i].name; i++) {
-               const struct expansionromtype *ert = &expansionroms[i];
-               if (ert->deviceflags & EXPANSIONTYPE_RTG) {
-                       if ((ert->romtype & ROMTYPE_MASK) != (romtype & ROMTYPE_MASK)) {
-                               clear_device_rom(&workprefs, ert->romtype, 0, true);
-                       }
-               }
-       }
-}
-
+static int rtg_index;
 
 static void expansion2filebuttons(HWND hDlg, WPARAM wParam, TCHAR *path)
 {
@@ -8883,11 +9122,11 @@ static void expansion2filebuttons(HWND hDlg, WPARAM wParam, TCHAR *path)
        {
                case IDC_SCSIROMCHOOSER:
                DiskSelection(hDlg, IDC_SCSIROMFILE, 6, &workprefs, path);
-               values_to_expansion2dlg(hDlg);
+               values_to_expansion2dlg(hDlg, 1);
                break;
                case IDC_CPUBOARDROMCHOOSER:
                DiskSelection(hDlg, IDC_CPUBOARDROMFILE, 6, &workprefs, path);
-               values_to_expansion2dlg(hDlg);
+               values_to_expansion2dlg(hDlg, 2);
                break;
        }
 }
@@ -8909,6 +9148,7 @@ static INT_PTR CALLBACK Expansion2DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LP
                        currentpage = EXPANSION2_ID;
                        int ids[] = { IDC_SCSIROMFILE, IDC_CPUBOARDROMFILE, -1 };
                        setmultiautocomplete(hDlg, ids);
+
                        if (!enumerated) {
                                ethernet_enumerate(ndd, NULL);
                                for (int i = 0; ndd[i]; i++) {
@@ -8926,12 +9166,14 @@ static INT_PTR CALLBACK Expansion2DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LP
                                }
                                enumerated = 1;
                        }
+
                        SendDlgItemMessage(hDlg, IDC_CPUBOARD_TYPE, CB_RESETCONTENT, 0, 0);
                        for (int i = 0; cpuboards[i].name; i++) {
                                SendDlgItemMessage(hDlg, IDC_CPUBOARD_TYPE, CB_ADDSTRING, 0, (LPARAM) cpuboards[i].name);
                        }
 
                        SendDlgItemMessage(hDlg, IDC_SCSIROMSELECTCAT, CB_RESETCONTENT, 0, 0);
+                       SendDlgItemMessage(hDlg, IDC_SCSIROMSELECTCAT, CB_ADDSTRING, 0, (LPARAM)_T("Built-in CD/HD Controllers"));
                        SendDlgItemMessage(hDlg, IDC_SCSIROMSELECTCAT, CB_ADDSTRING, 0, (LPARAM)_T("SCSI Controllers"));
                        SendDlgItemMessage(hDlg, IDC_SCSIROMSELECTCAT, CB_ADDSTRING, 0, (LPARAM)_T("IDE Controllers"));
                        SendDlgItemMessage(hDlg, IDC_SCSIROMSELECTCAT, CB_ADDSTRING, 0, (LPARAM)_T("SASI Controllers"));
@@ -8939,19 +9181,25 @@ static INT_PTR CALLBACK Expansion2DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LP
                        SendDlgItemMessage(hDlg, IDC_SCSIROMSELECTCAT, CB_ADDSTRING, 0, (LPARAM)_T("PCI Bridgeboards"));
                        SendDlgItemMessage(hDlg, IDC_SCSIROMSELECTCAT, CB_ADDSTRING, 0, (LPARAM)_T("x86 Bridgeboards"));
                        SendDlgItemMessage(hDlg, IDC_SCSIROMSELECTCAT, CB_ADDSTRING, 0, (LPARAM)_T("RTG boards"));
+                       SendDlgItemMessage(hDlg, IDC_SCSIROMSELECTCAT, CB_ADDSTRING, 0, (LPARAM)_T("Sound cards"));
+                       SendDlgItemMessage(hDlg, IDC_SCSIROMSELECTCAT, CB_ADDSTRING, 0, (LPARAM)_T("Network adapters"));
+                       SendDlgItemMessage(hDlg, IDC_SCSIROMSELECTCAT, CB_ADDSTRING, 0, (LPARAM)_T("Disk controllers"));
+
                        reset_expansionrom_gui(hDlg, &expansion_gui_item, IDC_EXPANSIONBOARDITEMSELECTOR, IDC_EXPANSIONBOARDSELECTOR, IDC_EXPANSIONBOARDCHECKBOX);
                        reset_expansionrom_gui(hDlg, &accelerator_gui_item, IDC_ACCELERATORBOARDITEMSELECTOR, IDC_ACCELERATORBOARDSELECTOR, IDC_ACCELERATORBOARDCHECKBOX);
+
                        hide(hDlg, IDC_SCSIROMSELECTED, 1);
                        expansion_net(hDlg);
                        init_expansion2(hDlg, true);
                        updatecpuboardsubtypes(hDlg);
                        setcpuboardmemsize(hDlg);
+
                        recursive--;
                }
 
                case WM_USER:
                recursive++;
-               values_to_expansion2dlg(hDlg);
+               values_to_expansion2dlg(hDlg, 0);
                enable_for_expansion2dlg(hDlg);
                recursive--;
                break;
@@ -8988,13 +9236,17 @@ static INT_PTR CALLBACK Expansion2DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LP
                                if (ischecked(hDlg, IDC_A2065)) {
                                        _tcscpy(workprefs.a2065name, _T("none"));
                                        workprefs.ne2000pciname[0] = 0;
+                                       workprefs.ne2000pcmcianame[0] = 0;
                                        setchecked(hDlg, IDC_NE2000, false);
+                                       setchecked(hDlg, IDC_NE2000PCMCIA, false);
+                                       cfgfile_compatibility_romtype(&workprefs);
                                        expansion_net(hDlg);
                                        enable_for_expansion2dlg(hDlg);
                                } else {
-                                       if (!workprefs.ne2000pciname[0])
+                                       if (!workprefs.ne2000pcmcianame[0] && !workprefs.ne2000pciname[0])
                                                ew(hDlg, IDC_NETDEVICE, FALSE);
                                        workprefs.a2065name[0] = 0;
+                                       cfgfile_compatibility_romtype(&workprefs);
                                        enable_for_expansion2dlg(hDlg);
                                }
                                break;
@@ -9002,57 +9254,48 @@ static INT_PTR CALLBACK Expansion2DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LP
                                if (ischecked(hDlg, IDC_NE2000)) {
                                        _tcscpy(workprefs.ne2000pciname, _T("none"));
                                        workprefs.a2065name[0] = 0;
+                                       workprefs.ne2000pcmcianame[0] = 0;
                                        setchecked(hDlg, IDC_A2065, false);
+                                       setchecked(hDlg, IDC_NE2000PCMCIA, false);
+                                       cfgfile_compatibility_romtype(&workprefs);
                                        expansion_net(hDlg);
                                        enable_for_expansion2dlg(hDlg);
                                } else {
-                                       if (!workprefs.a2065name[0])
+                                       if (!workprefs.a2065name[0] && !workprefs.ne2000pcmcianame[0])
                                                ew(hDlg, IDC_NETDEVICE, FALSE);
                                        workprefs.ne2000pciname[0] = 0;
+                                       cfgfile_compatibility_romtype(&workprefs);
+                                       enable_for_expansion2dlg(hDlg);
+                               }
+                               case IDC_NE2000PCMCIA:
+                               if (ischecked(hDlg, IDC_NE2000PCMCIA)) {
+                                       _tcscpy(workprefs.ne2000pcmcianame, _T("none"));
+                                       workprefs.a2065name[0] = 0;
+                                       workprefs.ne2000pciname[0] = 0;
+                                       setchecked(hDlg, IDC_A2065, false);
+                                       setchecked(hDlg, IDC_NE2000, false);
+                                       cfgfile_compatibility_romtype(&workprefs);
+                                       expansion_net(hDlg);
+                                       enable_for_expansion2dlg(hDlg);
+                               } else {
+                                       if (!workprefs.a2065name[0] && !workprefs.ne2000pciname[0])
+                                               ew(hDlg, IDC_NETDEVICE, FALSE);
+                                       workprefs.ne2000pcmcianame[0] = 0;
+                                       cfgfile_compatibility_romtype(&workprefs);
                                        enable_for_expansion2dlg(hDlg);
                                }
                                break;
                                case IDC_CATWEASEL:
                                workprefs.catweasel = ischecked(hDlg, IDC_CATWEASEL) ? -1 : 0;
+                               cfgfile_compatibility_romtype(&workprefs);
                                break;
                                case IDC_CS_CD32FMV:
                                workprefs.cs_cd32fmv = ischecked(hDlg, IDC_CS_CD32FMV) ? 1 : 0;
-                               break;
-                               case IDC_CS_TOCCATA:
-                               workprefs.sound_toccata = ischecked(hDlg, IDC_CS_TOCCATA) ? 1 : 0;
-                               if (!workprefs.sound_toccata)
-                                       workprefs.sound_toccata_mixer = false;
-                               enable_for_expansion2dlg(hDlg);
-                               if (workprefs.sound_toccata && (workprefs.sound_fm801 || workprefs.sound_es1370)) {
-                                       workprefs.sound_fm801 = 0;
-                                       workprefs.sound_es1370 = 0;
-                               }
-                               break;
-                               case IDC_CS_TOCCATAMIXER:
-                               workprefs.sound_toccata_mixer = ischecked(hDlg, IDC_CS_TOCCATAMIXER) ? 1 : 0;
-                               break;
-                               case IDC_CS_ES1370:
-                               workprefs.sound_es1370 = ischecked(hDlg, IDC_CS_ES1370) ? 1 : 0;
-                               if (workprefs.sound_es1370 && (workprefs.sound_fm801 || workprefs.sound_toccata)) {
-                                       workprefs.sound_fm801 = 0;
-                                       workprefs.sound_toccata = 0;
-                                       workprefs.sound_toccata_mixer = false;
-                                       values_to_expansion2dlg(hDlg);
-                                       enable_for_expansion2dlg(hDlg);
-                               }
-                               break;
-                               case IDC_CS_FM801:
-                               workprefs.sound_fm801 = ischecked(hDlg, IDC_CS_FM801) ? 1 : 0;
-                               if (workprefs.sound_fm801 && (workprefs.sound_es1370 || workprefs.sound_toccata)) {
-                                       workprefs.sound_es1370 = 0;
-                                       workprefs.sound_toccata = 0;
-                                       workprefs.sound_toccata_mixer = false;
-                                       values_to_expansion2dlg(hDlg);
-                                       enable_for_expansion2dlg(hDlg);
-                               }
+                               cfgfile_compatibility_romtype(&workprefs);
                                break;
                                case IDC_SCSIROMSELECTED:
                                values_from_expansion2dlg(hDlg);
+                               values_to_expansion2_expansion_settings(hDlg, 1);
                                break;
                        }
                        expansion2filebuttons(hDlg, wParam, NULL);
@@ -9071,15 +9314,18 @@ static INT_PTR CALLBACK Expansion2DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LP
                                        break;
                                        case IDC_SCSIROMFILE:
                                        case IDC_SCSIROMID:
+                                       values_from_expansion2dlg(hDlg);
+                                       values_to_expansion2_expansion_settings(hDlg, 1);
+                                       break;
                                        case IDC_CPUBOARDROMFILE:
                                        case IDC_CPUBOARDROMSUBSELECT:
                                        values_from_expansion2dlg(hDlg);
-                                       values_to_expansion2_expansion_settings(hDlg);
+                                       values_to_expansion2_expansion_settings(hDlg, 2);
                                        break;
                                        case IDC_SCSIROMSUBSELECT:
                                        values_from_expansion2dlg(hDlg);
                                        values_to_expansion2_expansion_roms(hDlg, NULL);
-                                       values_to_expansion2_expansion_settings(hDlg);
+                                       values_to_expansion2_expansion_settings(hDlg, 1);
                                        break;
                                        case IDC_SCSIROMSELECTCAT:
                                        val = SendDlgItemMessage(hDlg, IDC_SCSIROMSELECTCAT, CB_GETCURSEL, 0, 0);
@@ -9088,7 +9334,7 @@ static INT_PTR CALLBACK Expansion2DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LP
                                                scsiromselected = 0;
                                                init_expansion2(hDlg, false);
                                                values_to_expansion2_expansion_roms(hDlg, NULL);
-                                               values_to_expansion2_expansion_settings(hDlg);
+                                               values_to_expansion2_expansion_settings(hDlg, 1);
                                                values_to_expansion2dlg_sub(hDlg);
                                        }
                                        break;
@@ -9101,7 +9347,7 @@ static INT_PTR CALLBACK Expansion2DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LP
                                        if (val != CB_ERR) {
                                                scsiromselected = val;
                                                values_to_expansion2_expansion_roms(hDlg, NULL);
-                                               values_to_expansion2_expansion_settings(hDlg);
+                                               values_to_expansion2_expansion_settings(hDlg, 1);
                                                values_to_expansion2dlg_sub(hDlg);
                                        }
                                        break;
@@ -9120,7 +9366,7 @@ static INT_PTR CALLBACK Expansion2DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LP
                                                built_in_cpuboard_prefs(&workprefs);
                                                setcpuboardmemsize(hDlg);
                                                enable_for_expansion2dlg(hDlg);
-                                               values_to_expansion2dlg(hDlg);
+                                               values_to_expansion2dlg(hDlg, 2);
                                        }
                                        break;
                                        case IDC_CPUBOARD_SUBTYPE:
@@ -9136,7 +9382,7 @@ static INT_PTR CALLBACK Expansion2DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LP
                                                built_in_cpuboard_prefs(&workprefs);
                                                setcpuboardmemsize(hDlg);
                                                enable_for_expansion2dlg(hDlg);
-                                               values_to_expansion2dlg(hDlg);
+                                               values_to_expansion2dlg(hDlg, 2);
                                        }
                                        break;
                                        case IDC_NETDEVICE:
@@ -9153,12 +9399,23 @@ static INT_PTR CALLBACK Expansion2DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LP
                                                if (ischecked(hDlg, IDC_A2065)) {
                                                        _tcscpy(workprefs.a2065name, s);
                                                        workprefs.ne2000pciname[0] = 0;
+                                                       workprefs.ne2000pcmcianame[0] = 0;
                                                        setchecked(hDlg, IDC_NE2000, false);
+                                                       setchecked(hDlg, IDC_NE2000PCMCIA, false);
                                                }
                                                if (ischecked(hDlg, IDC_NE2000)) {
                                                        _tcscpy(workprefs.ne2000pciname, s);
                                                        workprefs.a2065name[0] = 0;
+                                                       workprefs.ne2000pcmcianame[0] = 0;
                                                        setchecked(hDlg, IDC_A2065, false);
+                                                       setchecked(hDlg, IDC_NE2000PCMCIA, false);
+                                               }
+                                               if (ischecked(hDlg, IDC_NE2000PCMCIA)) {
+                                                       _tcscpy(workprefs.ne2000pcmcianame, s);
+                                                       workprefs.a2065name[0] = 0;
+                                                       workprefs.ne2000pciname[0] = 0;
+                                                       setchecked(hDlg, IDC_A2065, false);
+                                                       setchecked(hDlg, IDC_NE2000, false);
                                                }
                                        }
                                        break;
@@ -9175,8 +9432,12 @@ static INT_PTR CALLBACK Expansion2DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LP
                }
                break;
                case WM_HSCROLL:
+               if (recursive > 0)
+                       break;
+               recursive++;
                workprefs.cpuboardmem1_size = memsizes[msi_cpuboard[SendMessage(GetDlgItem(hDlg, IDC_CPUBOARDMEM), TBM_GETPOS, 0, 0)]];
                setcpuboardmemsize(hDlg);
+               recursive--;
                break;
        }
        return FALSE;
@@ -9189,13 +9450,20 @@ static void enable_for_expansiondlg(HWND hDlg)
 
        en = !!full_property_sheet;
 
-       int rtg = workprefs.rtgboards[0].rtgmem_size && full_property_sheet && workprefs.rtgboards[0].rtgmem_type < GFXBOARD_HARDWARE;
-       int rtg2 = workprefs.rtgboards[0].rtgmem_size || workprefs.rtgboards[0].rtgmem_type >= GFXBOARD_HARDWARE;
-       int rtg3 = workprefs.rtgboards[0].rtgmem_size && workprefs.rtgboards[0].rtgmem_type < GFXBOARD_HARDWARE;
-       int rtg4 = workprefs.rtgboards[0].rtgmem_type < GFXBOARD_HARDWARE;
+       int rtg = workprefs.rtgboards[rtg_index].rtgmem_size && full_property_sheet && workprefs.rtgboards[rtg_index].rtgmem_type < GFXBOARD_HARDWARE;
+       int rtg2 = workprefs.rtgboards[rtg_index].rtgmem_size || workprefs.rtgboards[rtg_index].rtgmem_type >= GFXBOARD_HARDWARE;
+       int rtg3 = workprefs.rtgboards[rtg_index].rtgmem_size && workprefs.rtgboards[rtg_index].rtgmem_type < GFXBOARD_HARDWARE;
+       int rtg4 = workprefs.rtgboards[rtg_index].rtgmem_type < GFXBOARD_HARDWARE;
+
+       int rtg0 = rtg2;
+       if (rtg_index > 0) {
+               rtg = false;
+               rtg2 = false;
+               rtg3 = false;
+       }
 
-       ew(hDlg, IDC_P96RAM, rtg2);
-       ew(hDlg, IDC_P96MEM, rtg2);
+       ew(hDlg, IDC_P96RAM, rtg0);
+       ew(hDlg, IDC_P96MEM, rtg0);
        ew(hDlg, IDC_RTG_Z2Z3, z3);
        ew(hDlg, IDC_RTG_8BIT, rtg);
        ew(hDlg, IDC_RTG_16BIT, rtg);
@@ -9223,22 +9491,16 @@ static void values_to_expansiondlg(HWND hDlg)
 
        int min_mem = MIN_P96_MEM;
        int max_mem = MAX_P96_MEM_Z3;
-       struct rtgboardconfig *rbc = &workprefs.rtgboards[0];
+       struct rtgboardconfig *rbc = &workprefs.rtgboards[rtg_index];
        if (gfxboard_get_configtype(rbc) == 2) {
                int v = rbc->rtgmem_size;
-               max_mem = 0;
+               max_mem = MAX_P96_MEM_Z2;
                rbc->rtgmem_size = 1024 * 1024;
-               while (getz2size(&workprefs) > 0) {
-                       rbc->rtgmem_size *= 2;
-                       max_mem++;
-               }
                if (rbc->rtgmem_type >= GFXBOARD_HARDWARE && v > gfxboard_get_vram_max(rbc))
                        v = gfxboard_get_vram_max(rbc);
                if (rbc->rtgmem_type >= GFXBOARD_HARDWARE && v < gfxboard_get_vram_min(rbc))
                        v = gfxboard_get_vram_min(rbc);
                rbc->rtgmem_size = v;
-               while (getz2size(&workprefs) < 0 && rbc->rtgmem_size > 0)
-                       rbc->rtgmem_size -= 1024 * 1024;
        } else if (gfxboard_get_configtype(rbc) == 3) {
                int v = rbc->rtgmem_size;
                if (rbc->rtgmem_type >= GFXBOARD_HARDWARE && v > gfxboard_get_vram_max(rbc))
@@ -9286,6 +9548,7 @@ static void values_to_expansiondlg(HWND hDlg)
        SetDlgItemText(hDlg, IDC_P96RAM, memsize_names[msi_gfx[mem_size]]);
 
        SendDlgItemMessage(hDlg, IDC_RTG_Z2Z3, CB_SETCURSEL, rbc->rtgmem_size == 0 ? 0 : rbc->rtgmem_type + 1, 0);
+       SendDlgItemMessage(hDlg, IDC_RTG_NUM, CB_SETCURSEL, rtg_index, 0);
        SendDlgItemMessage(hDlg, IDC_RTG_8BIT, CB_SETCURSEL, (workprefs.picasso96_modeflags & RGBFF_CLUT) ? 1 : 0, 0);
        SendDlgItemMessage(hDlg, IDC_RTG_16BIT, CB_SETCURSEL,
                                           (manybits(workprefs.picasso96_modeflags, RGBFF_R5G6B5PC | RGBFF_R5G6B5PC | RGBFF_R5G6B5 | RGBFF_R5G5B5 | RGBFF_B5G6R5PC | RGBFF_B5G5R5PC)) ? 1 :
@@ -9352,6 +9615,12 @@ static INT_PTR CALLBACK ExpansionDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LP
                currentpage = EXPANSION_ID;
 
                init_displays_combo (hDlg, true);
+               
+               SendDlgItemMessage(hDlg, IDC_RTG_NUM, CB_RESETCONTENT, 0, 0);
+               for (int i = 0; i < MAX_RTG_BOARDS; i++) {
+                       _stprintf(tmp, _T("%d"), i + 1);
+                       SendDlgItemMessage(hDlg, IDC_RTG_NUM, CB_ADDSTRING, 0, (LPARAM)tmp);
+               }
 
                SendDlgItemMessage (hDlg, IDC_RTG_Z2Z3, CB_RESETCONTENT, 0, 0);
                SendDlgItemMessage (hDlg, IDC_RTG_Z2Z3, CB_ADDSTRING, 0, (LPARAM)_T("-"));
@@ -9396,7 +9665,7 @@ static INT_PTR CALLBACK ExpansionDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LP
                SendDlgItemMessage (hDlg, IDC_RTG_32BIT, CB_ADDSTRING, 0, (LPARAM)_T("A8B8G8R8"));
                SendDlgItemMessage (hDlg, IDC_RTG_32BIT, CB_ADDSTRING, 0, (LPARAM)_T("R8G8B8A8"));
                SendDlgItemMessage (hDlg, IDC_RTG_32BIT, CB_ADDSTRING, 0, (LPARAM)_T("B8G8R8A8 (*)"));
-               SendDlgItemMessage (hDlg, IDC_P96MEM, TBM_SETRANGE, TRUE, MAKELONG (MIN_P96_MEM, gfxboard_get_configtype(&workprefs.rtgboards[0]) == 3 ? MAX_P96_MEM_Z3 : MAX_P96_MEM_Z2));
+               SendDlgItemMessage (hDlg, IDC_P96MEM, TBM_SETRANGE, TRUE, MAKELONG (MIN_P96_MEM, gfxboard_get_configtype(&workprefs.rtgboards[rtg_index]) == 3 ? MAX_P96_MEM_Z3 : MAX_P96_MEM_Z2));
                SendDlgItemMessage (hDlg, IDC_RTG_SCALE_ASPECTRATIO, CB_RESETCONTENT, 0, 0);
                WIN32GUI_LoadUIString (IDS_DISABLED, tmp, sizeof tmp / sizeof (TCHAR));
                SendDlgItemMessage (hDlg, IDC_RTG_SCALE_ASPECTRATIO, CB_ADDSTRING, 0, (LPARAM)tmp);
@@ -9424,7 +9693,7 @@ static INT_PTR CALLBACK ExpansionDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LP
                break;
 
        case WM_HSCROLL:
-               workprefs.rtgboards[0].rtgmem_size = memsizes[msi_gfx[SendMessage (GetDlgItem (hDlg, IDC_P96MEM), TBM_GETPOS, 0, 0)]];
+               workprefs.rtgboards[rtg_index].rtgmem_size = memsizes[msi_gfx[SendMessage (GetDlgItem (hDlg, IDC_P96MEM), TBM_GETPOS, 0, 0)]];
                values_to_expansiondlg(hDlg);
                enable_for_expansiondlg(hDlg);
                break;
@@ -9482,18 +9751,26 @@ static INT_PTR CALLBACK ExpansionDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LP
                                                        workprefs.win32_rtgscaleaspectratio = getaspectratio (v - 2);
                                        }
                                        break;
+                               case IDC_RTG_NUM:
+                                       v = SendDlgItemMessage(hDlg, IDC_RTG_NUM, CB_GETCURSEL, 0, 0L);
+                                       if (v != CB_ERR) {
+                                               rtg_index = v;
+                                               values_to_expansiondlg(hDlg);
+                                               enable_for_expansiondlg(hDlg);
+                                       }
+                                       break;
                                case IDC_RTG_Z2Z3:
                                        v = SendDlgItemMessage (hDlg, IDC_RTG_Z2Z3, CB_GETCURSEL, 0, 0L);
                                        if (v != CB_ERR) {
                                                if (v == 0) {
-                                                       workprefs.rtgboards[0].rtgmem_type = 1;
-                                                       workprefs.rtgboards[0].rtgmem_size = 0;
+                                                       workprefs.rtgboards[rtg_index].rtgmem_type = 1;
+                                                       workprefs.rtgboards[rtg_index].rtgmem_size = 0;
                                                } else {
-                                                       workprefs.rtgboards[0].rtgmem_type = v - 1;
-                                                       if (workprefs.rtgboards[0].rtgmem_size == 0)
-                                                               workprefs.rtgboards[0].rtgmem_size = 4096 * 1024;
+                                                       workprefs.rtgboards[rtg_index].rtgmem_type = v - 1;
+                                                       if (workprefs.rtgboards[rtg_index].rtgmem_size == 0)
+                                                               workprefs.rtgboards[rtg_index].rtgmem_size = 4096 * 1024;
                                                }
-                                               set_expansion_rtg_rom();
+                                               cfgfile_compatibility_rtg(&workprefs);
                                                enable_for_expansiondlg (hDlg);
                                        }
                                        break;
@@ -9581,6 +9858,83 @@ static INT_PTR CALLBACK ExpansionDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LP
        return FALSE;
 }
 
+
+static INT_PTR CALLBACK BoardsDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+       static int recursive = 0;
+       static int selected = -1;
+
+       switch (msg)
+       {
+               case WM_INITDIALOG:
+               recursive++;
+               pages[BOARD_ID] = hDlg;
+               currentpage = BOARD_ID;
+               setchecked(hDlg, IDC_AUTOCONFIGCUSTOMSORT, workprefs.autoconfig_custom_sort);
+               ew(hDlg, IDC_BOARDLIST, workprefs.autoconfig_custom_sort != 0 && full_property_sheet);
+               ew(hDlg, IDC_BOARDS_UP, FALSE);
+               ew(hDlg, IDC_BOARDS_DOWN, FALSE);
+               ew(hDlg, IDC_AUTOCONFIGCUSTOMSORT, full_property_sheet);
+               InitializeListView(hDlg);
+               recursive--;
+               break;
+
+               case WM_COMMAND:
+               if (!recursive) {
+                       recursive++;
+                       switch (LOWORD(wParam))
+                       {
+                               case IDC_AUTOCONFIGCUSTOMSORT:
+                               workprefs.autoconfig_custom_sort = ischecked(hDlg, IDC_AUTOCONFIGCUSTOMSORT);
+                               expansion_set_autoconfig_sort(&workprefs);
+                               ew(hDlg, IDC_BOARDLIST, workprefs.autoconfig_custom_sort != 0);
+                               InitializeListView(hDlg);
+                               break;
+                               case IDC_BOARDS_UP:
+                               case IDC_BOARDS_DOWN:
+                               if (selected >= 0) {
+                                       int newpos = expansion_autoconfig_move(&workprefs, selected, LOWORD(wParam) == IDC_BOARDS_UP ? -1 : 1);
+                                       if (newpos >= 0) {
+                                               selected = newpos;
+                                               
+                                               
+                                               InitializeListView(hDlg);
+
+
+                                               ListView_SetItemState(cachedlist, selected, LVIS_SELECTED, LVIS_SELECTED);
+
+                                       }
+                               }
+                               break;
+                       }
+                       recursive--;
+               }
+               break;
+
+               case WM_NOTIFY:
+               if (((LPNMHDR)lParam)->idFrom == IDC_BOARDLIST) {
+                       int column;
+                       NM_LISTVIEW *nmlistview = (NM_LISTVIEW *)lParam;
+                       HWND list = nmlistview->hdr.hwndFrom;
+                       switch (nmlistview->hdr.code)
+                       {
+                               case NM_CLICK:
+                               {
+                                       int entry = listview_entry_from_click(list, &column);
+                                       if (entry >= 0) {
+                                               selected = entry;
+                                               ew(hDlg, IDC_BOARDS_UP, TRUE);
+                                               ew(hDlg, IDC_BOARDS_DOWN, TRUE);
+                                       }
+                               }
+                               break;
+                       }
+               }
+       }
+       return FALSE;
+}
+
+
 static INT_PTR CALLBACK MemoryDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
 {
        TCHAR tmp[MAX_DPATH];
@@ -9595,13 +9949,9 @@ static INT_PTR CALLBACK MemoryDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARA
                currentpage = MEMORY_ID;
                SendDlgItemMessage (hDlg, IDC_CHIPMEM, TBM_SETRANGE, TRUE, MAKELONG (MIN_CHIP_MEM, MAX_CHIP_MEM));
                SendDlgItemMessage (hDlg, IDC_FASTMEM, TBM_SETRANGE, TRUE, MAKELONG (MIN_FAST_MEM, MAX_FAST_MEM));
-               SendDlgItemMessage (hDlg, IDC_FASTMEM2, TBM_SETRANGE, TRUE, MAKELONG (MIN_FAST_MEM, MAX_FAST_MEM));
                SendDlgItemMessage (hDlg, IDC_SLOWMEM, TBM_SETRANGE, TRUE, MAKELONG (MIN_SLOW_MEM, MAX_SLOW_MEM));
                SendDlgItemMessage (hDlg, IDC_Z3FASTMEM, TBM_SETRANGE, TRUE, MAKELONG (MIN_Z3_MEM, MAX_Z3_MEM));
                SendDlgItemMessage (hDlg, IDC_Z3CHIPMEM, TBM_SETRANGE, TRUE, MAKELONG (MIN_Z3_MEM, MAX_Z3_CHIPMEM));
-               SendDlgItemMessage (hDlg, IDC_MBMEM1, TBM_SETRANGE, TRUE, MAKELONG (MIN_MB_MEM, MAX_MBL_MEM));
-               SendDlgItemMessage (hDlg, IDC_MBMEM2, TBM_SETRANGE, TRUE, MAKELONG (MIN_MB_MEM, MAX_MBH_MEM));
-               CheckDlgButton(hDlg, IDC_FASTMEMAUTOCONFIG, workprefs.fastmem_autoconfig);
                SendDlgItemMessage (hDlg, IDC_Z3MAPPING, CB_RESETCONTENT, 0, 0);
                WIN32GUI_LoadUIString (IDS_AUTOMATIC, tmp, sizeof tmp / sizeof (TCHAR));
                _tcscat(tmp, _T(" (*)"));
@@ -9609,6 +9959,9 @@ static INT_PTR CALLBACK MemoryDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARA
                SendDlgItemMessage(hDlg, IDC_Z3MAPPING, CB_ADDSTRING, 0, (LPARAM)_T("UAE (0x10000000)"));
                SendDlgItemMessage(hDlg, IDC_Z3MAPPING, CB_ADDSTRING, 0, (LPARAM)_T("Real (0x40000000)"));
                SendDlgItemMessage (hDlg, IDC_Z3MAPPING, CB_SETCURSEL, workprefs.z3_mapping_mode, 0);
+
+               setfastram_selectmenu(hDlg, 0);
+
                recursive--;
 
        case WM_USER:
@@ -9622,6 +9975,16 @@ static INT_PTR CALLBACK MemoryDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARA
        case WM_COMMAND:
                if (!recursive) {
                        recursive++;
+                       switch (LOWORD(wParam))
+                       {
+                               case IDC_FASTMEMAUTOCONFIGUSE:
+                               if (fastram_select_ramboard) {
+                                       struct ramboard *rb = fastram_select_ramboard;
+                                       rb->autoconfig_inuse = ischecked(hDlg, IDC_FASTMEMAUTOCONFIGUSE);
+                                       setfastram_selectmenu(hDlg, 0);
+                               }
+                               break;
+                       }
                        if (HIWORD (wParam) == CBN_SELCHANGE || HIWORD (wParam) == CBN_KILLFOCUS)  {
                                switch (LOWORD (wParam))
                                {
@@ -9631,27 +9994,100 @@ static INT_PTR CALLBACK MemoryDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARA
                                                workprefs.z3_mapping_mode = v;
                                        }
                                        break;
+                                       case IDC_MEMORYSELECT:
+                                       v = SendDlgItemMessage(hDlg, IDC_MEMORYSELECT, CB_GETCURSEL, 0, 0L);
+                                       if (v != CB_ERR) {
+                                               fastram_select = v;
+                                               setfastram_selectmenu(hDlg, 0);
+                                       }
+                                       break;
+                               }
+                       } else if (HIWORD(wParam) == EN_CHANGE) {
+                               switch (LOWORD(wParam))
+                               {
+                                       case IDC_AUTOCONFIG_MANUFACTURER:
+                                       case IDC_AUTOCONFIG_PRODUCT:
+                                       if (fastram_select_ramboard) {
+                                               GetDlgItemText(hDlg, IDC_AUTOCONFIG_MANUFACTURER, tmp, sizeof tmp / sizeof(TCHAR));
+                                               fastram_select_ramboard->manufacturer = _tstol(tmp);
+                                               GetDlgItemText(hDlg, IDC_AUTOCONFIG_PRODUCT, tmp, sizeof tmp / sizeof(TCHAR));
+                                               fastram_select_ramboard->product = _tstol(tmp);
+                                               setfastram_selectmenu(hDlg, 1);
+                                       }
+                                       break;
+                                       case IDC_AUTOCONFIG_DATA:
+                                       if (fastram_select_ramboard && fastram_select_ramboard->autoconfig_inuse) {
+                                               struct ramboard *rb = fastram_select_ramboard;
+                                               GetDlgItemText(hDlg, IDC_AUTOCONFIG_DATA, tmp, sizeof tmp / sizeof(TCHAR));
+                                               memset(rb->autoconfig, 0, sizeof rb->autoconfig);
+                                               for (int i = 0; i < sizeof rb->autoconfig; i++) {
+                                                       TCHAR *s2 = &tmp[i * 3];
+                                                       if (i + 1 < 12 && s2[2] != '.')
+                                                               break;
+                                                       TCHAR *endptr;
+                                                       tmp[2] = 0;
+                                                       rb->autoconfig[i] = (uae_u8)_tcstol(s2, &endptr, 16);
+                                               }
+                                               setfastram_selectmenu(hDlg, 2);
+                                       }
+                                       break;
                                }
                        }
-                       workprefs.fastmem_autoconfig = ischecked (hDlg, IDC_FASTMEMAUTOCONFIG);
                        recursive--;
                }
                break;
 
        case WM_HSCROLL:
-               workprefs.chipmem_size = memsizes[msi_chip[SendMessage (GetDlgItem (hDlg, IDC_CHIPMEM), TBM_GETPOS, 0, 0)]];
-               workprefs.bogomem_size = memsizes[msi_bogo[SendMessage (GetDlgItem (hDlg, IDC_SLOWMEM), TBM_GETPOS, 0, 0)]];
-               workprefs.fastmem_size = memsizes[msi_fast[SendMessage (GetDlgItem (hDlg, IDC_FASTMEM), TBM_GETPOS, 0, 0)]];
-               workprefs.fastmem2_size = memsizes[msi_fast[SendMessage (GetDlgItem (hDlg, IDC_FASTMEM2), TBM_GETPOS, 0, 0)]];
-               workprefs.z3fastmem_size = memsizes[msi_z3fast[SendMessage (GetDlgItem (hDlg, IDC_Z3FASTMEM), TBM_GETPOS, 0, 0)]];
-               updatez3 (&workprefs.z3fastmem_size, &workprefs.z3fastmem2_size);
-               workprefs.z3chipmem_size = memsizes[msi_z3chip[SendMessage (GetDlgItem (hDlg, IDC_Z3CHIPMEM), TBM_GETPOS, 0, 0)]];
-               workprefs.mbresmem_low_size = memsizes[msi_gfx[SendMessage (GetDlgItem (hDlg, IDC_MBMEM1), TBM_GETPOS, 0, 0)]];
-               workprefs.mbresmem_high_size = memsizes[msi_gfx[SendMessage (GetDlgItem (hDlg, IDC_MBMEM2), TBM_GETPOS, 0, 0)]];
-               fix_values_memorydlg ();
-               values_to_memorydlg (hDlg);
-               enable_for_memorydlg (hDlg);
+       {
+               recursive++;
+               bool change1 = false;
+               uae_u32 v;
+               v = memsizes[msi_chip[SendMessage (GetDlgItem (hDlg, IDC_CHIPMEM), TBM_GETPOS, 0, 0)]];
+               if (v != workprefs.chipmem_size) {
+                       change1 = true;
+                       workprefs.chipmem_size = v;
+               }
+               v = memsizes[msi_bogo[SendMessage (GetDlgItem (hDlg, IDC_SLOWMEM), TBM_GETPOS, 0, 0)]];
+               if (v != workprefs.bogomem_size) {
+                       change1 = true;
+                       workprefs.bogomem_size = v;
+               }
+               v = memsizes[msi_fast[SendMessage (GetDlgItem (hDlg, IDC_FASTMEM), TBM_GETPOS, 0, 0)]];
+               if (v != workprefs.fastmem[0].size) {
+                       change1 = true;
+                       workprefs.fastmem[0].size = v;
+                       fastram_select = 0;
+                       setfastram_selectmenu(hDlg, 0);
+               }
+               v = memsizes[msi_z3fast[SendMessage (GetDlgItem (hDlg, IDC_Z3FASTMEM), TBM_GETPOS, 0, 0)]];
+               if (v != workprefs.z3fastmem[0].size) {
+                       change1 = true;
+                       workprefs.z3fastmem[0].size = v;
+                       fastram_select = MAX_RAM_BOARDS;
+                       setfastram_selectmenu(hDlg, 0);
+               }
+               v = memsizes[msi_z3chip[SendMessage (GetDlgItem (hDlg, IDC_Z3CHIPMEM), TBM_GETPOS, 0, 0)]];
+               if (v != workprefs.z3chipmem_size) {
+                       change1 = true;
+                       workprefs.z3chipmem_size = v;
+               }
+               if (!change1 && fastram_select_pointer) {
+                       v = memsizes[fastram_select_msi[SendMessage(GetDlgItem(hDlg, IDC_MEMORYMEM), TBM_GETPOS, 0, 0)]];
+                       if (*fastram_select_pointer != v) {
+                               *fastram_select_pointer = v;
+                               setfastram_selectmenu(hDlg, 0);
+                               values_to_memorydlg(hDlg);
+                       }
+               }
+               if (change1) {
+                       fix_values_memorydlg ();
+                       values_to_memorydlg (hDlg);
+                       setfastram_selectmenu(hDlg, 0);
+                       enable_for_memorydlg (hDlg);
+               }
+               recursive--;
                break;
+       }
 
        }
        return FALSE;
@@ -11391,7 +11827,8 @@ static void hardfile_testrdb (struct hfdlg_vals *hdf)
                for (i = 0; i < 16; i++) {
                        hdf_read_rdb (&hfd, id, i * 512, 512);
                        if (i == 0 && !memcmp (id + 2, "CIS", 3)) {
-                               hdf->ci.controller_type = HD_CONTROLLER_TYPE_PCMCIA_SRAM;
+                               hdf->ci.controller_type = HD_CONTROLLER_TYPE_PCMCIA;
+                               hdf->ci.controller_type_unit = 0;
                                break;
                        }
                        if (!memcmp (id, "RDSK\0\0\0", 7) || !memcmp (id, "CDSK\0\0\0", 7) || !memcmp (id, "DRKS\0\0", 6) || (id[0] == 0x53 && id[1] == 0x10 && id[2] == 0x9b && id[3] == 0x13 && id[4] == 0 && id[5] == 0)) {
@@ -11634,7 +12071,7 @@ static void sethardfile (HWND hDlg)
        hide(hDlg, IDC_RESERVED_TEXT, rdb);
        hide(hDlg, IDC_CYLINDERS_TEXT, !rdb);
        gui_set_string_cursor(hdmenutable, hDlg, IDC_HDF_CONTROLLER, current_hfdlg.ci.controller_type +  current_hfdlg.ci.controller_type_unit * HD_CONTROLLER_NEXT_UNIT);
-       SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER_UNIT, CB_SETCURSEL, current_hfdlg.ci.controller_unit, 0);
+       SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER_UNIT, CB_SETCURSEL, current_hfdlg.ci.controller_type != HD_CONTROLLER_TYPE_PCMCIA ? current_hfdlg.ci.controller_unit : current_hfdlg.ci.controller_type_unit, 0);
        ew(hDlg, IDC_HDF_CONTROLLER_TYPE, ide);
        ew(hDlg, IDC_HDF_FEATURE_LEVEL, ide || scsi);
        if (!ide) {
@@ -11685,7 +12122,6 @@ static void inithdcontroller (HWND hDlg, int ctype, int ctype_unit, int devtype)
 
        gui_add_string(hdmenutable, hDlg, IDC_HDF_CONTROLLER, 0, _T(""));
        gui_add_string(hdmenutable, hDlg, IDC_HDF_CONTROLLER, HD_CONTROLLER_TYPE_IDE_AUTO, _T("IDE (Auto)"));
-       gui_add_string(hdmenutable, hDlg, IDC_HDF_CONTROLLER, HD_CONTROLLER_TYPE_IDE_MB, _T("A600/A1200/A4000"));
 
        for (int i = 0; expansionroms[i].name; i++) {
                const struct expansionromtype *erc = &expansionroms[i];
@@ -11696,9 +12132,6 @@ static void inithdcontroller (HWND hDlg, int ctype, int ctype_unit, int devtype)
 
        gui_add_string(hdmenutable, hDlg, IDC_HDF_CONTROLLER, 0, _T(""));
        gui_add_string(hdmenutable, hDlg, IDC_HDF_CONTROLLER, HD_CONTROLLER_TYPE_SCSI_AUTO, _T("SCSI (Auto)"));
-       gui_add_string(hdmenutable, hDlg, IDC_HDF_CONTROLLER, HD_CONTROLLER_TYPE_SCSI_A3000, _T("A3000"));
-       gui_add_string(hdmenutable, hDlg, IDC_HDF_CONTROLLER, HD_CONTROLLER_TYPE_SCSI_A4000T, _T("A4000T"));
-       gui_add_string(hdmenutable, hDlg, IDC_HDF_CONTROLLER, HD_CONTROLLER_TYPE_SCSI_CDTV, _T("CDTV"));
 
        for (int i = 0; expansionroms[i].name; i++) {
                const struct expansionromtype *erc = &expansionroms[i];
@@ -11708,8 +12141,13 @@ static void inithdcontroller (HWND hDlg, int ctype, int ctype_unit, int devtype)
        }
 
        gui_add_string(hdmenutable, hDlg, IDC_HDF_CONTROLLER, 0, _T(""));
-       gui_add_string(hdmenutable, hDlg, IDC_HDF_CONTROLLER, HD_CONTROLLER_TYPE_PCMCIA_SRAM, _T("PCMCIA SRAM"));
-       gui_add_string(hdmenutable, hDlg, IDC_HDF_CONTROLLER, HD_CONTROLLER_TYPE_PCMCIA_IDE, _T("PCMCIA IDE"));
+       for (int i = 0; expansionroms[i].name; i++) {
+               const struct expansionromtype *erc = &expansionroms[i];
+               if ((erc->romtype & ROMTYPE_MASK) == ROMTYPE_MB_PCMCIA) {
+                       addhdcontroller(hDlg, erc, hdmenutable, HD_CONTROLLER_TYPE_PCMCIA, 0);
+                       ctype_unit = 0;
+               }
+       }
 
        gui_set_string_cursor(hdmenutable, hDlg, IDC_HDF_CONTROLLER, ctype + ctype_unit * HD_CONTROLLER_NEXT_UNIT);
 
@@ -11742,6 +12180,10 @@ static void inithdcontroller (HWND hDlg, int ctype, int ctype_unit, int devtype)
                        }
                }
                ew(hDlg, IDC_HDF_CONTROLLER_UNIT, TRUE);
+       } else if (ctype == HD_CONTROLLER_TYPE_PCMCIA) {
+               SendDlgItemMessage(hDlg, IDC_HDF_CONTROLLER_UNIT, CB_ADDSTRING, 0, (LPARAM)_T("SRAM"));
+               SendDlgItemMessage(hDlg, IDC_HDF_CONTROLLER_UNIT, CB_ADDSTRING, 0, (LPARAM)_T("IDE"));
+               ew(hDlg, IDC_HDF_CONTROLLER_UNIT, TRUE);
        } else {
                ew(hDlg, IDC_HDF_CONTROLLER_UNIT, FALSE);
        }
@@ -11957,7 +12399,7 @@ static INT_PTR CALLBACK TapeDriveSettingsProc (HWND hDlg, UINT msg, WPARAM wPara
                if (current_tapedlg.ci.controller_type < HD_CONTROLLER_TYPE_SCSI_AUTO)
                        current_tapedlg.ci.controller_type = HD_CONTROLLER_TYPE_SCSI_AUTO;
                inithdcontroller(hDlg, current_tapedlg.ci.controller_type, current_tapedlg.ci.controller_type_unit, UAEDEV_TAPE);
-               SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER_UNIT, CB_SETCURSEL, current_tapedlg.ci.controller_unit, 0);
+               SendDlgItemMessage(hDlg, IDC_HDF_CONTROLLER_UNIT, CB_SETCURSEL, current_tapedlg.ci.controller_type != HD_CONTROLLER_TYPE_PCMCIA ? current_tapedlg.ci.controller_unit : current_tapedlg.ci.controller_type_unit, 0);
                setautocomplete (hDlg, IDC_PATH_NAME);
                addhistorymenu(hDlg, current_tapedlg.ci.rootdir, IDC_PATH_NAME, HISTORY_TAPE, false);
                readonly = my_existsfile (current_tapedlg.ci.rootdir);
@@ -11990,13 +12432,17 @@ static INT_PTR CALLBACK TapeDriveSettingsProc (HWND hDlg, UINT msg, WPARAM wPara
                                        current_tapedlg.ci.controller_type = posn % HD_CONTROLLER_NEXT_UNIT;
                                        current_tapedlg.ci.controller_type_unit = posn / HD_CONTROLLER_NEXT_UNIT;
                                        inithdcontroller(hDlg, current_tapedlg.ci.controller_type, current_tapedlg.ci.controller_type_unit, UAEDEV_TAPE);
-                                       SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER_UNIT, CB_SETCURSEL, current_tapedlg.ci.controller_unit, 0);
+                                       SendDlgItemMessage(hDlg, IDC_HDF_CONTROLLER_UNIT, CB_SETCURSEL, current_tapedlg.ci.controller_type != HD_CONTROLLER_TYPE_PCMCIA ? current_tapedlg.ci.controller_unit : current_tapedlg.ci.controller_type_unit, 0);
                                }
                                break;
                        case IDC_HDF_CONTROLLER_UNIT:
                                posn = SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER_UNIT, CB_GETCURSEL, 0, 0);
-                               if (posn != CB_ERR)
-                                       current_tapedlg.ci.controller_unit = posn;
+                               if (posn != CB_ERR) {
+                                       if (current_tapedlg.ci.controller_type == HD_CONTROLLER_TYPE_PCMCIA)
+                                               current_tapedlg.ci.controller_type_unit = posn;
+                                       else
+                                               current_tapedlg.ci.controller_unit = posn;
+                               }
                                break;
                        }
                }
@@ -12066,7 +12512,7 @@ static INT_PTR CALLBACK CDDriveSettingsProc (HWND hDlg, UINT msg, WPARAM wParam,
                        workprefs.cs_cdtvscsi ||
                        (workprefs.cs_mbdmac & 3)) ? HD_CONTROLLER_TYPE_SCSI_AUTO : HD_CONTROLLER_TYPE_IDE_AUTO;
                inithdcontroller(hDlg, current_cddlg.ci.controller_type, current_cddlg.ci.controller_type_unit, UAEDEV_CD);
-               SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER_UNIT, CB_SETCURSEL, current_cddlg.ci.controller_unit, 0);
+               SendDlgItemMessage(hDlg, IDC_HDF_CONTROLLER_UNIT, CB_SETCURSEL, current_cddlg.ci.controller_type != HD_CONTROLLER_TYPE_PCMCIA ? current_cddlg.ci.controller_unit : current_cddlg.ci.controller_type_unit, 0);
                InitializeListView (hDlg);
                recursive--;
                customDlgType = IDD_CDDRIVE;
@@ -12097,13 +12543,17 @@ static INT_PTR CALLBACK CDDriveSettingsProc (HWND hDlg, UINT msg, WPARAM wParam,
                                current_cddlg.ci.controller_type = posn % HD_CONTROLLER_NEXT_UNIT;
                                current_cddlg.ci.controller_type_unit = posn / HD_CONTROLLER_NEXT_UNIT;
                                inithdcontroller(hDlg, current_cddlg.ci.controller_type, current_cddlg.ci.controller_type_unit, UAEDEV_CD);
-                               SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER_UNIT, CB_SETCURSEL, current_cddlg.ci.controller_unit, 0);
+                               SendDlgItemMessage(hDlg, IDC_HDF_CONTROLLER_UNIT, CB_SETCURSEL, current_cddlg.ci.controller_type != HD_CONTROLLER_TYPE_PCMCIA ? current_cddlg.ci.controller_unit : current_cddlg.ci.controller_type_unit, 0);
                        }
                        break;
                case IDC_HDF_CONTROLLER_UNIT:
                        posn = SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER_UNIT, CB_GETCURSEL, 0, 0);
-                       if (posn != CB_ERR)
-                               current_cddlg.ci.controller_unit = posn;
+                       if (posn != CB_ERR) {
+                               if (current_cddlg.ci.controller_type == HD_CONTROLLER_TYPE_PCMCIA)
+                                       current_cddlg.ci.controller_type_unit = posn;
+                               else
+                                       current_cddlg.ci.controller_unit = posn;
+                       }
                        break;
                }
                recursive--;
@@ -12203,7 +12653,10 @@ static INT_PTR CALLBACK HardfileSettingsProc (HWND hDlg, UINT msg, WPARAM wParam
                        case IDC_HDF_CONTROLLER_UNIT:
                                posn = SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER_UNIT, CB_GETCURSEL, 0, 0);
                                if (posn != CB_ERR) {
-                                       current_hfdlg.ci.controller_unit = posn;
+                                       if (current_hfdlg.ci.controller_type == HD_CONTROLLER_TYPE_PCMCIA)
+                                               current_hfdlg.ci.controller_type_unit = posn;
+                                       else
+                                               current_hfdlg.ci.controller_unit = posn;
                                        sethardfile (hDlg);
                                }
                                break;
@@ -12393,7 +12846,7 @@ static INT_PTR CALLBACK HarddriveSettingsProc (HWND hDlg, UINT msg, WPARAM wPara
                        if (index >= 0) {
                                SendDlgItemMessage (hDlg, IDC_HARDDRIVE, CB_SETCURSEL, index, 0);
                                gui_set_string_cursor(hdmenutable, hDlg, IDC_HDF_CONTROLLER, current_hfdlg.ci.controller_type + current_hfdlg.ci.controller_type_unit * HD_CONTROLLER_NEXT_UNIT);
-                               SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER_UNIT, CB_SETCURSEL, current_hfdlg.ci.controller_unit, 0);
+                               SendDlgItemMessage(hDlg, IDC_HDF_CONTROLLER_UNIT, CB_SETCURSEL, current_hfdlg.ci.controller_type != HD_CONTROLLER_TYPE_PCMCIA ? current_hfdlg.ci.controller_unit : current_hfdlg.ci.controller_type_unit, 0);
                                SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER_TYPE, CB_SETCURSEL, current_hfdlg.ci.controller_media_type, 0);
                        }
                        recursive--;
@@ -12450,7 +12903,7 @@ static INT_PTR CALLBACK HarddriveSettingsProc (HWND hDlg, UINT msg, WPARAM wPara
                                        SetDlgItemText (hDlg, IDC_HDFINFO2, _T(""));
                                        updatehdfinfo (hDlg, true, true);
                                        gui_set_string_cursor(hdmenutable, hDlg, IDC_HDF_CONTROLLER, current_hfdlg.ci.controller_type + current_hfdlg.ci.controller_type_unit * MAX_DUPLICATE_EXPANSION_BOARDS);
-                                       SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER_UNIT, CB_SETCURSEL, current_hfdlg.ci.controller_unit, 0);
+                                       SendDlgItemMessage(hDlg, IDC_HDF_CONTROLLER_UNIT, CB_SETCURSEL, current_hfdlg.ci.controller_type != HD_CONTROLLER_TYPE_PCMCIA ? current_hfdlg.ci.controller_unit : current_hfdlg.ci.controller_type_unit, 0);
                                        CheckDlgButton(hDlg, IDC_HDF_RW, !current_hfdlg.ci.readonly);
                                        _tcscpy (current_hfdlg.ci.rootdir, hdf_getnameharddrive ((int)posn, 4, &current_hfdlg.ci.blocksize, NULL));
                                }
@@ -12466,12 +12919,15 @@ static INT_PTR CALLBACK HarddriveSettingsProc (HWND hDlg, UINT msg, WPARAM wPara
                                SetDlgItemText (hDlg, IDC_HDFINFO2, _T(""));
                                updatehdfinfo (hDlg, true, true);
                                inithdcontroller(hDlg, current_hfdlg.ci.controller_type, current_hfdlg.ci.controller_type_unit, UAEDEV_HDF);
-                               SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER_UNIT, CB_SETCURSEL, current_hfdlg.ci.controller_unit, 0);
+                               SendDlgItemMessage(hDlg, IDC_HDF_CONTROLLER_UNIT, CB_SETCURSEL, current_hfdlg.ci.controller_type != HD_CONTROLLER_TYPE_PCMCIA ? current_hfdlg.ci.controller_unit : current_hfdlg.ci.controller_type_unit, 0);
                        }
                } else if (LOWORD(wParam) == IDC_HDF_CONTROLLER_UNIT) {
                        posn = SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER_UNIT, CB_GETCURSEL, 0, 0);
                        if (posn != CB_ERR) {
-                               current_hfdlg.ci.controller_unit = posn;
+                               if (current_hfdlg.ci.controller_type == HD_CONTROLLER_TYPE_PCMCIA)
+                                       current_hfdlg.ci.controller_type_unit = posn;
+                               else
+                                       current_hfdlg.ci.controller_unit = posn;
                        }
                } else if (LOWORD(wParam) == IDC_HDF_CONTROLLER_TYPE) {
                        posn = SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER_TYPE, CB_GETCURSEL, 0, 0);
@@ -14920,7 +15376,7 @@ static void clearinputlistview (HWND hDlg)
 
 static void doinputcustom (HWND hDlg, int newcustom)
 {
-       TCHAR custom1[MAX_DPATH];
+       TCHAR custom1[CONFIG_BLEN];
        uae_u64 flags;
        int port;
 
@@ -15795,13 +16251,18 @@ static void input_togglesetmode (void)
        if (evtnum) {
                const struct inputevent *evt = inputdevice_get_eventinfo (evtnum);
                if (evt && (evt->allow_mask & AM_SETTOGGLE)) {
-                       if ((flags & (IDEV_MAPPED_SET_ONOFF | IDEV_MAPPED_SET_ONOFF_VAL)) == (IDEV_MAPPED_SET_ONOFF | IDEV_MAPPED_SET_ONOFF_VAL)) {
-                               flags &= ~(IDEV_MAPPED_SET_ONOFF | IDEV_MAPPED_SET_ONOFF_VAL);
+                       if ((flags & (IDEV_MAPPED_SET_ONOFF | IDEV_MAPPED_SET_ONOFF_VAL1 | IDEV_MAPPED_SET_ONOFF_VAL2)) == (IDEV_MAPPED_SET_ONOFF | IDEV_MAPPED_SET_ONOFF_VAL1 | IDEV_MAPPED_SET_ONOFF_VAL2)) {
+                               flags &= ~(IDEV_MAPPED_SET_ONOFF | IDEV_MAPPED_SET_ONOFF_VAL1 | IDEV_MAPPED_SET_ONOFF_VAL1);
+                       } else if ((flags & (IDEV_MAPPED_SET_ONOFF | IDEV_MAPPED_SET_ONOFF_VAL2)) == (IDEV_MAPPED_SET_ONOFF | IDEV_MAPPED_SET_ONOFF_VAL2)) {
+                               flags |= IDEV_MAPPED_SET_ONOFF_VAL1;
+                       } else if ((flags & (IDEV_MAPPED_SET_ONOFF | IDEV_MAPPED_SET_ONOFF_VAL1)) == (IDEV_MAPPED_SET_ONOFF | IDEV_MAPPED_SET_ONOFF_VAL1)) {
+                               flags &= ~IDEV_MAPPED_SET_ONOFF_VAL1;
+                               flags |= IDEV_MAPPED_SET_ONOFF_VAL2;
                        } else if (flags & IDEV_MAPPED_SET_ONOFF) {
-                               flags |= IDEV_MAPPED_SET_ONOFF_VAL;
+                               flags |= IDEV_MAPPED_SET_ONOFF_VAL1;
                        } else {
                                flags |= IDEV_MAPPED_SET_ONOFF;
-                               flags &= ~IDEV_MAPPED_SET_ONOFF_VAL;
+                               flags &= ~(IDEV_MAPPED_SET_ONOFF_VAL1 | IDEV_MAPPED_SET_ONOFF_VAL2);
                        }
                        inputdevice_set_mapping (input_selected_device, input_selected_widget,
                                name, custom, flags, -1, input_selected_sub_num);
@@ -18046,6 +18507,7 @@ static void createTreeView (HWND hDlg)
        CN (HARDDISK_ID, _T("harddisk"));
        CN(EXPANSION2_ID, _T("expansion2"));
        CN(EXPANSION_ID, _T("expansion"));
+       CN(BOARD_ID, _T("board"));
 
        p2 = p = CreateFolderNode (TVhDlg, IDS_TREEVIEW_HOST, root, LOADSAVE_ID, CONFIG_TYPE_HOST, _T("configuration_host"));
        CN (DISPLAY_ID, _T("display"));
@@ -18898,7 +19360,9 @@ static int GetSettings (int all_options, HWND hwnd)
                QUICKSTART_ID = init_page (IDD_QUICKSTART, IDI_QUICKSTART, IDS_QUICKSTART, QuickstartDlgProc, NULL, _T("gui/quickstart.htm"), 0);
                ABOUT_ID = init_page (IDD_ABOUT, IDI_ABOUT, IDS_ABOUT, AboutDlgProc, NULL, NULL, 0);
                FRONTEND_ID = init_page (IDD_FRONTEND, IDI_QUICKSTART, IDS_FRONTEND, AboutDlgProc, NULL, NULL, 0);
-               C_PAGES = FRONTEND_ID + 1;
+               BOARD_ID = init_page(IDD_BOARDS, IDI_EXPANSION, IDS_BOARD, BoardsDlgProc, NULL, NULL, 0);
+               C_PAGES = BOARD_ID + 1;
+
                init_called = 1;
                if (quickstart && !qs_override)
                        currentpage = QUICKSTART_ID;
@@ -18997,7 +19461,7 @@ static int GetSettings (int all_options, HWND hwnd)
                        }
                }
 
-               tres = scaleresource (panelresource, hwnd, gui_resize_enabled, gui_fullscreen, workprefs.win32_alwaysontop ? WS_EX_TOPMOST : 0);
+               tres = scaleresource (panelresource, hwnd, gui_resize_enabled, gui_fullscreen, workprefs.win32_gui_alwaysontop || workprefs.win32_main_alwaysontop ? WS_EX_TOPMOST : 0);
                dhwnd = CreateDialogIndirect (tres->inst, tres->resource, isfullscreen () != 0 ? hwnd : NULL, DialogProc);
                dialog_rect.top = dialog_rect.left = 0;
                dialog_rect.right = tres->width;
@@ -19204,6 +19668,8 @@ static void gui_flicker_led2 (int led, int unitnum, int status)
                p = &gui_data.cd;
        else if (led == LED_MD)
                p = &gui_data.md;
+       else if (led == LED_NET)
+               p = &gui_data.net;
        else
                return;
        old = *p;
@@ -19235,7 +19701,7 @@ static void gui_flicker_led2 (int led, int unitnum, int status)
        }
 #endif
        *p = status;
-       resetcounter[led] = 6;
+       resetcounter[led] = 4;
        if (old != *p)
                gui_led (led, *p, -1);
 }
@@ -19243,12 +19709,13 @@ static void gui_flicker_led2 (int led, int unitnum, int status)
 void gui_flicker_led (int led, int unitnum, int status)
 {
        if (led < 0) {
-               gui_flicker_led2 (LED_HD, 0, 0);
-               gui_flicker_led2 (LED_CD, 0, 0);
+               gui_flicker_led2(LED_HD, 0, 0);
+               gui_flicker_led2(LED_CD, 0, 0);
+               gui_flicker_led2(LED_NET, 0, 0);
                if (gui_data.md >= 0)
-                       gui_flicker_led2 (LED_MD, 0, 0);
+                       gui_flicker_led2(LED_MD, 0, 0);
        } else {
-               gui_flicker_led2 (led, unitnum, status);
+               gui_flicker_led2(led, unitnum, status);
        }
 }
 
@@ -19288,7 +19755,7 @@ void gui_led (int led, int on, int brightness)
                return;
        tt = NULL;
        if (led >= LED_DF0 && led <= LED_DF3) {
-               pos = 6 + (led - LED_DF0);
+               pos = 7 + (led - LED_DF0);
                ptr = drive_text + pos * LED_STRING_WIDTH;
                if (gui_data.drive_disabled[led - 1])
                        _tcscpy (ptr, _T(""));
@@ -19331,17 +19798,30 @@ void gui_led (int led, int on, int brightness)
                                active2 = 1;
                        on &= 1;
                }
+       } else if (led == LED_NET) {
+               pos = 6;
+               ptr = _tcscpy(drive_text + pos * LED_STRING_WIDTH, _T("N"));
+               center = 1;
+               if (on > 1)
+                       writing = 1;
        } else if (led == LED_FPS) {
                double fps = (double)gui_data.fps / 10.0;
                extern double p96vblank;
                pos = 2;
                ptr = drive_text + pos * LED_STRING_WIDTH;
-               if (fps > 999.9)
-                       fps = 999.9;
-               if (picasso_on)
-                       _stprintf (ptr, _T("%.1f [%.1f]"), p96vblank, fps);
-               else
-                       _stprintf (ptr, _T("FPS: %.1f"), fps);
+               if (fps > 9999.9)
+                       fps = 9999.9;
+               if (fps < 1000) {
+                       if (picasso_on)
+                               _stprintf (ptr, _T("%.1f [%.1f]"), p96vblank, fps);
+                       else
+                               _stprintf (ptr, _T("FPS: %.1f"), fps);
+               } else {
+                       if (picasso_on)
+                               _stprintf(ptr, _T("%.0f [%.0f]"), p96vblank, fps);
+                       else
+                               _stprintf(ptr, _T("FPS: %.0f"), fps);
+               }
                if (gui_data.cpu_halted > 0) {
                        _stprintf (ptr, _T("HALT%d"), gui_data.cpu_halted);
                        center = 1;
@@ -19397,7 +19877,7 @@ void gui_led (int led, int on, int brightness)
                } else {
                        _stprintf(p, _T("%s: %.0f%%"), m68label, (double)((gui_data.idle) / 10.0));
                }
-       } else if (led == LED_SND && gui_data.drive_disabled[3]) {
+       } else if (led == LED_SND && gui_data.sndbuf_avail) {
                pos = 0;
                ptr = drive_text + pos * LED_STRING_WIDTH;
                if (gui_data.sndbuf_status < 3 && !pause_emulation && !sound_paused()) {
@@ -19408,7 +19888,7 @@ void gui_led (int led, int on, int brightness)
                        on = 0;
                }
        } else if (led == LED_MD) {
-               pos = 6 + 3;
+               pos = 7 + 3;
                ptr = _tcscpy(drive_text + pos * LED_STRING_WIDTH, _T("NV"));
        }
 
index 056256f2d4a4e1ba0a7b9bfda13d2e7186182689..86e80423b26fd7024ba74768c88b8b2a133c35f1 100644 (file)
@@ -1,6 +1,6 @@
 ï»¿<?xml version="1.0" encoding="utf-8"?>
 <Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="packages\VisualCppTools.14.0.24203-Pre\build\native\VisualCppTools.props" Condition="Exists('packages\VisualCppTools.14.0.24203-Pre\build\native\VisualCppTools.props')" />
+  <Import Project="packages\VisualCppTools.14.0.24224-Pre\build\native\VisualCppTools.props" Condition="Exists('packages\VisualCppTools.14.0.24224-Pre\build\native\VisualCppTools.props')" />
   <ItemGroup Label="ProjectConfigurations">
     <ProjectConfiguration Include="Debug|Win32">
       <Configuration>Debug</Configuration>
     <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">winuae64</TargetName>
     <TargetName Condition="'$(Configuration)|$(Platform)'=='Test|x64'">winuae64</TargetName>
     <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">winuae64</TargetName>
-    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;C:\dev\include;$(IncludePath)</IncludePath>
-    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Test|Win32'">C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;C:\dev\include;$(IncludePath)</IncludePath>
-    <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x86;C:\dev\lib;C:\dev\WinDDK\7600.16385.1\lib\win7\i386;$(LibraryPath)</LibraryPath>
-    <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Test|Win32'">C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x86;C:\dev\lib;C:\dev\WinDDK\7600.16385.1\lib\win7\i386;$(LibraryPath)</LibraryPath>
+    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.10240.0\ucrt;C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;C:\dev\include;$(IncludePath)</IncludePath>
+    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Test|Win32'">$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.10240.0\ucrt;C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;C:\dev\include;$(IncludePath)</IncludePath>
+    <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(MSBuildProgramFiles32)\Windows Kits\10\lib\10.0.10240.0\ucrt\$(PlatformShortName);C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x86;C:\dev\lib;C:\dev\WinDDK\7600.16385.1\lib\win7\i386;$(LibraryPath)</LibraryPath>
+    <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Test|Win32'">$(MSBuildProgramFiles32)\Windows Kits\10\lib\10.0.10240.0\ucrt\$(PlatformShortName);C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x86;C:\dev\lib;C:\dev\WinDDK\7600.16385.1\lib\win7\i386;$(LibraryPath)</LibraryPath>
     <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x86;C:\dev\lib;C:\dev\WinDDK\7600.16385.1\lib\win7\i386;$(LibraryPath)</LibraryPath>
     <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;C:\dev\include;$(IncludePath)</IncludePath>
-    <IncludePath Condition="'$(Configuration)|$(Platform)'=='FullRelease|Win32'">C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;C:\dev\include;$(IncludePath)</IncludePath>
+    <IncludePath Condition="'$(Configuration)|$(Platform)'=='FullRelease|Win32'">$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.10240.0\ucrt;C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;C:\dev\include;$(IncludePath)</IncludePath>
     <ReferencePath Condition="'$(Configuration)|$(Platform)'=='FullRelease|Win32'">$(ReferencePath)</ReferencePath>
-    <LibraryPath Condition="'$(Configuration)|$(Platform)'=='FullRelease|Win32'">C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x86;C:\dev\lib;$(LibraryPath)</LibraryPath>
+    <LibraryPath Condition="'$(Configuration)|$(Platform)'=='FullRelease|Win32'">$(MSBuildProgramFiles32)\Windows Kits\10\lib\10.0.10240.0\ucrt\$(PlatformShortName);C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x86;C:\dev\lib;$(LibraryPath)</LibraryPath>
     <EmbedManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</EmbedManifest>
     <EmbedManifest Condition="'$(Configuration)|$(Platform)'=='Test|Win32'">true</EmbedManifest>
     <EmbedManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</EmbedManifest>
     <PropertyGroup>
       <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
     </PropertyGroup>
-    <Error Condition="!Exists('packages\VisualCppTools.14.0.24203-Pre\build\native\VisualCppTools.props')" Text="$([System.String]::Format('$(ErrorText)', 'packages\VisualCppTools.14.0.24203-Pre\build\native\VisualCppTools.props'))" />
+    <Error Condition="!Exists('packages\VisualCppTools.14.0.24224-Pre\build\native\VisualCppTools.props')" Text="$([System.String]::Format('$(ErrorText)', 'packages\VisualCppTools.14.0.24224-Pre\build\native\VisualCppTools.props'))" />
   </Target>
 </Project>
\ No newline at end of file
index eda8a91d65312bf8744e264ec9f900f1c49eebde..dae68333c9543576fade6251b89135424b2093bc 100644 (file)
     <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">winuae64</TargetName>
     <TargetName Condition="'$(Configuration)|$(Platform)'=='Test|x64'">winuae64</TargetName>
     <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">winuae64</TargetName>
-    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;C:\dev\include;$(IncludePath)</IncludePath>
-    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Test|Win32'">C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;C:\dev\include;$(IncludePath)</IncludePath>
-    <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x86;C:\dev\lib;C:\dev\WinDDK\7600.16385.1\lib\win7\i386;$(LibraryPath)</LibraryPath>
-    <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Test|Win32'">C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x86;C:\dev\lib;C:\dev\WinDDK\7600.16385.1\lib\win7\i386;$(LibraryPath)</LibraryPath>
+    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.10240.0\ucrt;C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;C:\dev\include;$(IncludePath)</IncludePath>
+    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Test|Win32'">$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.10240.0\ucrt;C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;C:\dev\include;$(IncludePath)</IncludePath>
+    <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(MSBuildProgramFiles32)\Windows Kits\10\lib\10.0.10240.0\ucrt\$(PlatformShortName);C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x86;C:\dev\lib;C:\dev\WinDDK\7600.16385.1\lib\win7\i386;$(LibraryPath)</LibraryPath>
+    <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Test|Win32'">$(MSBuildProgramFiles32)\Windows Kits\10\lib\10.0.10240.0\ucrt\$(PlatformShortName);C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x86;C:\dev\lib;C:\dev\WinDDK\7600.16385.1\lib\win7\i386;$(LibraryPath)</LibraryPath>
     <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x86;C:\dev\lib;C:\dev\WinDDK\7600.16385.1\lib\win7\i386;$(LibraryPath)</LibraryPath>
     <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;C:\dev\include;$(IncludePath)</IncludePath>
     <IncludePath Condition="'$(Configuration)|$(Platform)'=='FullRelease|Win32'">C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;C:\dev\include;$(IncludePath)</IncludePath>
       <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories);$(SolutionDir)\..\lib\</AdditionalLibraryDirectories>
       <AdditionalManifestDependencies>%(AdditionalManifestDependencies)</AdditionalManifestDependencies>
       <IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
-      <DelayLoadDLLs>wpcap.dll;packet.dll;d3dx9_43.dll;openal32.dll;portaudio_x86.dll;ws2_32.dll;msacm32.dll;wtsapi32.dll;dsound.dll;wininet.dll;avrt.dll;ddraw.dll;Iphlpapi.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
+      <DelayLoadDLLs>wpcap.dll;packet.dll;d3dx9_43.dll;openal32.dll;portaudio_x86.dll;ws2_32.dll;msacm32.dll;wtsapi32.dll;dsound.dll;wininet.dll;ddraw.dll;Iphlpapi.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <ProgramDatabaseFile>.\Release/winuae.pdb</ProgramDatabaseFile>
       <SubSystem>Windows</SubSystem>
       <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories);$(SolutionDir)\..\lib\</AdditionalLibraryDirectories>
       <AdditionalManifestDependencies>%(AdditionalManifestDependencies)</AdditionalManifestDependencies>
       <IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
-      <DelayLoadDLLs>wpcap.dll;packet.dll;d3dx9_43.dll;openal32.dll;portaudio_x86.dll;ws2_32.dll;msacm32.dll;wtsapi32.dll;dsound.dll;wininet.dll;avrt.dll;ddraw.dll;Iphlpapi.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
+      <DelayLoadDLLs>wpcap.dll;packet.dll;d3dx9_43.dll;openal32.dll;portaudio_x86.dll;ws2_32.dll;msacm32.dll;wtsapi32.dll;dsound.dll;wininet.dll;ddraw.dll;Iphlpapi.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <ProgramDatabaseFile>.\Test/winuae.pdb</ProgramDatabaseFile>
       <SubSystem>Windows</SubSystem>
index b34952d43f53500c02396947a8bebf0849199de3..70c503f035371d9c50877e1d5bfbf4df5cef4106 100644 (file)
@@ -465,6 +465,8 @@ static TCHAR *writets (void)
                return NULL;
        if (nodatestamps)
                return NULL;
+       if (!vsync_counter)
+               return NULL;
        _ftime (&tb);
        t = localtime (&tb.time);
        _tcsftime (curts, sizeof curts / sizeof (TCHAR), _T("%Y-%m-%d %H:%M:%S\n"), t);
diff --git a/pci.cpp b/pci.cpp
index ae6d698fd38a32e5722d8ccae97a0bb8a30ceac6..69c9970bffab2ca7496a3a59f739f5fdfb51f94b 100644 (file)
--- a/pci.cpp
+++ b/pci.cpp
@@ -885,19 +885,19 @@ static void REGPARAM2 pci_bridge_wput(uaecptr addr, uae_u32 b)
                        {
                                case 0x44:
                                if (pcib->type == PCI_BRIDGE_PROMETHEUS) {
-                                       if (validate_banks_z3(&pci_io_bank, (expamem_z3_pointer) >> 16, expamem_z3_size >> 16)) {
-                                               map_banks_z3(&pci_io_bank, (expamem_z3_pointer) >> 16, 0xf0000 >> 16);
-                                               map_banks_z3(&pci_mem_bank, (expamem_z3_pointer + 0x100000) >> 16, (511 * 1024 * 1024) >> 16);
-                                               map_banks_z3(&pci_config_bank, (expamem_z3_pointer + 0xf0000) >> 16, 0x10000 >> 16);
+                                       if (validate_banks_z3(&pci_io_bank, (expamem_board_pointer) >> 16, expamem_board_size >> 16)) {
+                                               map_banks_z3(&pci_io_bank, (expamem_board_pointer) >> 16, 0xf0000 >> 16);
+                                               map_banks_z3(&pci_mem_bank, (expamem_board_pointer + 0x100000) >> 16, (511 * 1024 * 1024) >> 16);
+                                               map_banks_z3(&pci_config_bank, (expamem_board_pointer + 0xf0000) >> 16, 0x10000 >> 16);
                                        }
                                        pcib->baseaddress_offset = pcib->baseaddress;
-                                       pcib->io_offset = expamem_z3_pointer;
+                                       pcib->io_offset = expamem_board_pointer;
                                } else if (pcib->type == PCI_BRIDGE_MEDIATOR) {
-                                       map_banks_z3(&pci_mem_bank, expamem_z3_pointer >> 16, expamem_z3_size >> 16);
+                                       map_banks_z3(&pci_mem_bank, expamem_board_pointer >> 16, expamem_board_size >> 16);
                                        pcib->baseaddress_offset = 0;
                                }
-                               pcib->baseaddress = expamem_z3_pointer;
-                               pcib->board_size = expamem_z3_size;
+                               pcib->baseaddress = expamem_board_pointer;
+                               pcib->board_size = expamem_board_size;
                                pcib->baseaddress_end = pcib->baseaddress + pcib->board_size;
                                pcib->configured = 1;
                                expamem_next(pcib->bank, NULL);
@@ -924,9 +924,9 @@ static void REGPARAM2 pci_bridge_bput(uaecptr addr, uae_u32 b)
                        {
                                case 0x48:
                                // Mediator 1200
-                               map_banks_z2(&pci_mem_bank, b, expamem_z2_size >> 16);                  
+                               map_banks_z2(&pci_mem_bank, b, expamem_board_size >> 16);                       
                                pcib->baseaddress = b << 16;
-                               pcib->board_size = expamem_z2_size;
+                               pcib->board_size = expamem_board_size;
                                pcib->baseaddress_end = pcib->baseaddress + pcib->board_size;
                                pcib->configured = 1;
                                expamem_next(pcib->bank, NULL);
@@ -1064,9 +1064,9 @@ static void REGPARAM2 pci_bridge_bput_2(uaecptr addr, uae_u32 b)
                                case 0x48:
                                // Mediator 1200 IO
                                pcib->baseaddress_2 = b << 16;
-                               pcib->baseaddress_end_2 = (b << 16) + expamem_z2_size;
+                               pcib->baseaddress_end_2 = (b << 16) + expamem_board_size;
                                map_banks_z2(pcib->bank_2, pcib->baseaddress_2 >> 16, 0x10000 >> 16);
-                               map_banks_z2(&dummy_bank, (pcib->baseaddress_2 + 0x10000) >> 16, (expamem_z2_size - 0x10000) >> 16);
+                               map_banks_z2(&dummy_bank, (pcib->baseaddress_2 + 0x10000) >> 16, (expamem_board_size - 0x10000) >> 16);
                                pcib->configured_2 = 1;
                                pcib->io_offset = pcib->baseaddress_2 + 0x10000;
                                expamem_next(pcib->bank_2, NULL);
@@ -1122,16 +1122,16 @@ static void REGPARAM2 pci_bridge_wput_2(uaecptr addr, uae_u32 b)
                        {
                                case 0x44:
                                // Mediator 4000 IO
-                               if (validate_banks_z3(&pci_io_bank, expamem_z3_pointer >> 16, expamem_z3_size >> 16)) {
-                                       map_banks(pcib->bank_2, expamem_z3_pointer >> 16, 0x800000 >> 16, 0);
-                                       map_banks(&pci_config_bank, (expamem_z3_pointer + 0x800000) >> 16, 0x400000 >> 16, 0);
-                                       map_banks(&pci_io_bank, (expamem_z3_pointer + 0xc00000) >> 16, 0x400000 >> 16, 0);
+                               if (validate_banks_z3(&pci_io_bank, expamem_board_pointer >> 16, expamem_board_size >> 16)) {
+                                       map_banks(pcib->bank_2, expamem_board_pointer >> 16, 0x800000 >> 16, 0);
+                                       map_banks(&pci_config_bank, (expamem_board_pointer + 0x800000) >> 16, 0x400000 >> 16, 0);
+                                       map_banks(&pci_io_bank, (expamem_board_pointer + 0xc00000) >> 16, 0x400000 >> 16, 0);
                                }
-                               pcib->baseaddress_2 = expamem_z3_pointer;
-                               pcib->baseaddress_end_2 = expamem_z3_pointer + expamem_z3_size;
-                               pcib->board_size_2 = expamem_z3_size;
+                               pcib->baseaddress_2 = expamem_board_pointer;
+                               pcib->baseaddress_end_2 = expamem_board_pointer + expamem_board_size;
+                               pcib->board_size_2 = expamem_board_size;
                                pcib->configured_2 = 1;
-                               pcib->io_offset = (expamem_z3_pointer + 0xc00000);
+                               pcib->io_offset = (expamem_board_pointer + 0xc00000);
                                expamem_next(pcib->bank, NULL);
                                break;
                        }
@@ -1473,13 +1473,13 @@ static void add_pci_devices(struct pci_bridge *pcib)
                pci_board_add(pcib, &ne2000_pci_board, slot++, 0);
        }
 
-       if (currprefs.sound_fm801) {
+       if (is_device_rom(&currprefs, ROMTYPE_FM801, 0) > 0) {
                pci_board_add(pcib, &fm801_pci_board, slot, 0);
                pci_board_add(pcib, &fm801_pci_board_func1, slot, 1);
                slot++;
        }
 
-       if (currprefs.sound_es1370) {
+       if (is_device_rom(&currprefs, ROMTYPE_ES1370, 0) > 0) {
                pci_board_add(pcib, &es1370_pci_board, slot++, 0);
        }
 
@@ -1496,7 +1496,7 @@ void wildfire_ncr815_irq(int v)
        set_pci_irq(bridges[PCI_BRIDGE_WILDFIRE], pcibs, v != 0);
 }
 
-addrbank *dkb_wildfire_pci_init(struct romconfig *rc)
+bool dkb_wildfire_pci_init(struct autoconfig_info *aci)
 {
        struct pci_bridge *pcib = pci_bridge_alloc();
 
@@ -1519,7 +1519,8 @@ addrbank *dkb_wildfire_pci_init(struct romconfig *rc)
        map_banks(&pci_io_bank, 0xc0000000 >> 16, 0x30000000 >> 16, 0);
        map_banks(&pci_bridge_bank, 0xffff0000 >> 16, 0x10000 >> 16, 0);
        pcib->data = xcalloc(uae_u8, 32768);
-       return &expamem_null;
+       aci->addrbank = &expamem_null;
+       return true;
 }
 
 // Prometheus: 44359/1
@@ -1551,11 +1552,18 @@ static int prometheus_get_index(uaecptr addr)
        return slot;
 }
 
-static addrbank *prometheus_pci_init(struct romconfig *rc)
+static bool prometheus_pci_init(struct autoconfig_info *aci)
 {
+       if (!aci->doinit) {
+               for (int i = 0; i < sizeof prometheus_autoconfig; i++) {
+                       ew(aci->autoconfig_raw, i * 4, prometheus_autoconfig[i]);
+               }
+               return true;
+       }
+       struct romconfig *rc = aci->rc;
        struct pci_bridge *pcib = pci_bridge_alloc_zorro(PCI_BRIDGE_PROMETHEUS, rc);
        if (!pcib)
-               return &expamem_null;
+               return false;
        pcib->label = _T("Prometheus");
        pcib->endian_swap_config = 1;
        pcib->endian_swap_io = -1;
@@ -1575,7 +1583,8 @@ static addrbank *prometheus_pci_init(struct romconfig *rc)
        for (int i = 0; i < sizeof prometheus_autoconfig; i++) {
                ew(pcib->acmemory, i * 4, prometheus_autoconfig[i]);
        }
-       return pcib->bank;
+       aci->addrbank = pcib->bank;
+       return true;
 }
 
 // G-REX
@@ -1593,7 +1602,7 @@ static int grex_get_index(uaecptr addr)
        return slot;
 }
 
-static addrbank *grex_pci_init(struct romconfig *rc)
+static bool grex_pci_init(struct autoconfig_info *aci)
 {
        struct pci_bridge *pcib = pci_bridge_alloc();
 
@@ -1615,7 +1624,12 @@ static addrbank *grex_pci_init(struct romconfig *rc)
        map_banks(&pci_io_bank, 0xfffa0000 >> 16, 0x20000 >> 16, 0);
        map_banks(&pci_bridge_bank, 0xfffe0000 >> 16, 0x10000 >> 16, 0);
        pcib->io_offset = 0xfffa0000;
-       return &expamem_null;
+
+       aci->addrbank = &expamem_nonautoconfig;
+       aci->parent_of_previous = true;
+       aci->start = 0x80000000;
+       aci->size = 0x80000000;
+       return true;
 }
 
 // CyberVision/BlizzardVision without VGA chip...
@@ -1628,7 +1642,7 @@ static int xvision_get_index(uaecptr addr)
        return -1;
 }
 
-static addrbank *cbvision(struct romconfig *rc)
+static bool cbvision(struct autoconfig_info *aci)
 {
        struct pci_bridge *pcib = pci_bridge_alloc();
 
@@ -1648,7 +1662,9 @@ static addrbank *cbvision(struct romconfig *rc)
        map_banks(&pci_io_bank, 0xfffa0000 >> 16, 0x20000 >> 16, 0);
        map_banks(&pci_bridge_bank, 0xfffe0000 >> 16, 0x10000 >> 16, 0);
        pcib->io_offset = 0xfffa0000;
-       return &expamem_null;
+       aci->addrbank = &expamem_nonautoconfig;
+       aci->parent_of_previous = true;
+       return true;
 }
 
 // Mediator
@@ -1745,8 +1761,14 @@ static void mediator_pci_init_1200(struct pci_bridge *pcib)
        mediator_set_window_offset(pcib, 0);
 }
 
-static addrbank *mediator_pci_init_1200_1(struct romconfig *rc, struct mediator_autoconfig *m_ac)
+static addrbank *mediator_pci_init_1200_1(struct autoconfig_info *aci, struct romconfig *rc, struct mediator_autoconfig *m_ac)
 {
+       if (!aci->doinit) {
+               for (int i = 0; i < 16; i++) {
+                       ew(aci->autoconfig_raw, i * 4, m_ac->io[i]);
+               }
+               return NULL;
+       }
        struct pci_bridge *pcib;
        if (!(rc->device_settings & 4)) {
                // io first
@@ -1767,8 +1789,15 @@ static addrbank *mediator_pci_init_1200_1(struct romconfig *rc, struct mediator_
        return &pci_bridge_bank_2;
 }
 
-static addrbank *mediator_pci_init_1200_2(struct romconfig *rc, struct mediator_autoconfig *m_ac)
+static addrbank *mediator_pci_init_1200_2(struct autoconfig_info *aci, struct romconfig *rc, struct mediator_autoconfig *m_ac)
 {
+       if (!aci->doinit) {
+               const uae_u8 *ac = (rc->device_settings & 2) ? m_ac->mem_large : m_ac->mem_small;
+               for (int i = 0; i < 16; i++) {
+                       ew(aci->autoconfig_raw, i * 4, ac[i]);
+               }
+               return NULL;
+       }
        struct pci_bridge *pcib;
        if (!(rc->device_settings & 4)) {
                // memory last
@@ -1810,8 +1839,12 @@ static void mediator_pci_init_4000(struct pci_bridge *pcib)
        mediator_set_window_offset(pcib, 0);
 }
 
-static addrbank *mediator_pci_init_4000_1(struct romconfig *rc, struct mediator_autoconfig *m_ac)
+static addrbank *mediator_pci_init_4000_1(struct autoconfig_info *aci, struct romconfig *rc, struct mediator_autoconfig *m_ac)
 {
+       if (!aci->doinit) {
+               aci->autoconfigp = m_ac->io;
+               return &pci_bridge_bank_2;
+       }
        struct pci_bridge *pcib;
        if (!(rc->device_settings & 4)) {
                // io first
@@ -1831,8 +1864,12 @@ static addrbank *mediator_pci_init_4000_1(struct romconfig *rc, struct mediator_
        }
        return &pci_bridge_bank_2;
 }
-static addrbank *mediator_pci_init_4000_2(struct romconfig *rc, struct mediator_autoconfig *m_ac)
+static addrbank *mediator_pci_init_4000_2(struct autoconfig_info *aci, struct romconfig *rc, struct mediator_autoconfig *m_ac)
 {
+       if (!aci->doinit) {
+               aci->autoconfigp = (rc->device_settings & 2) ? m_ac->mem_large : m_ac->mem_small;
+               return &pci_bridge_bank;
+       }
        struct pci_bridge *pcib;
        if (!(rc->device_settings & 4)) {
                // memory last
@@ -1856,83 +1893,101 @@ static addrbank *mediator_pci_init_4000_2(struct romconfig *rc, struct mediator_
        return &pci_bridge_bank;
 }
 
-addrbank *mediator_init(struct romconfig *rc)
+bool mediator_init(struct autoconfig_info *aci)
 {
+       struct romconfig *rc = aci->rc;
        struct mediator_autoconfig *ac;
        switch (rc->subtype)
        {
                case 0:
                ac = &mediator_ac[MED_1200];
                if (rc->device_settings & 4)
-                       return mediator_pci_init_1200_2(rc, ac);
+                       aci->addrbank = mediator_pci_init_1200_2(aci, rc, ac);
                else
-                       return mediator_pci_init_1200_1(rc, ac);
+                       aci->addrbank = mediator_pci_init_1200_1(aci, rc, ac);
+               return true;
                case 1:
                ac = &mediator_ac[MED_1200SX];
                if (rc->device_settings & 4)
-                       return mediator_pci_init_1200_2(rc, ac);
+                       aci->addrbank = mediator_pci_init_1200_2(aci, rc, ac);
                else
-                       return mediator_pci_init_1200_1(rc, ac);
+                       aci->addrbank = mediator_pci_init_1200_1(aci, rc, ac);
+               return true;
                case 2:
                ac = &mediator_ac[MED_1200TX];
                if (rc->device_settings & 4)
-                       return mediator_pci_init_1200_2(rc, ac);
+                       aci->addrbank = mediator_pci_init_1200_2(aci, rc, ac);
                else
-                       return mediator_pci_init_1200_1(rc, ac);
+                       aci->addrbank = mediator_pci_init_1200_1(aci, rc, ac);
+               return true;
                case 3:
                ac = &mediator_ac[MED_4000MK2];
                if (rc->device_settings & 4)
-                       return mediator_pci_init_4000_2(rc, ac);
+                       aci->addrbank = mediator_pci_init_4000_2(aci, rc, ac);
                else
-                       return mediator_pci_init_4000_1(rc, ac);
+                       aci->addrbank = mediator_pci_init_4000_1(aci, rc, ac);
+               return true;
        }
-       return &expamem_null;
+       return false;
 }
 
-addrbank *mediator_init2(struct romconfig *rc)
+bool mediator_init2(struct autoconfig_info *aci)
 {
+       struct romconfig *rc = aci->rc;
        struct mediator_autoconfig *ac;
        switch (rc->subtype)
        {
                case 0:
                ac = &mediator_ac[MED_1200];
                if (rc->device_settings & 4)
-                       return mediator_pci_init_1200_1(rc, ac);
+                       aci->addrbank = mediator_pci_init_1200_1(aci, rc, ac);
                else
-                       return mediator_pci_init_1200_2(rc, ac);
+                       aci->addrbank = mediator_pci_init_1200_2(aci, rc, ac);
+               return true;
                case 1:
                ac = &mediator_ac[MED_1200SX];
                if (rc->device_settings & 4)
-                       return mediator_pci_init_1200_1(rc, ac);
+                       aci->addrbank = mediator_pci_init_1200_1(aci, rc, ac);
                else
-                       return mediator_pci_init_1200_2(rc, ac);
+                       aci->addrbank = mediator_pci_init_1200_2(aci, rc, ac);
+               return true;
                case 2:
                ac = &mediator_ac[MED_1200TX];
                if (rc->device_settings & 4)
-                       return mediator_pci_init_1200_1(rc, ac);
+                       aci->addrbank = mediator_pci_init_1200_1(aci, rc, ac);
                else
-                       return mediator_pci_init_1200_2(rc, ac);
+                       aci->addrbank = mediator_pci_init_1200_2(aci, rc, ac);
+               return true;
                case 3:
                ac = &mediator_ac[MED_4000MK2];
                if (rc->device_settings & 4)
-                       return mediator_pci_init_4000_1(rc, ac);
+                       aci->addrbank = mediator_pci_init_4000_1(aci, rc, ac);
                else
-                       return mediator_pci_init_4000_2(rc, ac);
+                       aci->addrbank = mediator_pci_init_4000_2(aci, rc, ac);
+               return true;
        }
-       return &expamem_null;
+       return false;
+}
+
+bool prometheus_init(struct autoconfig_info *aci)
+{
+       return prometheus_pci_init(aci);
 }
 
-addrbank *prometheus_init(struct romconfig *rc)
+bool cbvision_init(struct autoconfig_info *aci)
 {
-       return prometheus_pci_init(rc);
+       return cbvision(aci);
 }
 
-addrbank *cbvision_init(struct romconfig *rc)
+bool grex_init(struct autoconfig_info *aci)
 {
-       return cbvision(rc);
+       return grex_pci_init(aci);
 }
 
-addrbank *grex_init(struct romconfig *rc)
+bool pci_expansion_init(struct autoconfig_info *aci)
 {
-       return grex_pci_init(rc);
+       static const int parent[] = { ROMTYPE_GREX, ROMTYPE_MEDIATOR, ROMTYPE_PROMETHEUS, 0 };
+       aci->parent_romtype = parent;
+       aci->addrbank = &expamem_nonautoconfig;
+       return true;
 }
index 33e5d26add2bb24439a4ffd73f2d2e9cc7be03d2..f708d86dcbab12fc63cab2c34b08d62a8895426b 100644 (file)
@@ -29,6 +29,7 @@
 #include "queue.h"
 #include "qemuaudio.h"
 
+#include "options.h"
 #include "memory.h"
 #include "pci_hw.h"
 
index f5886fcebe5549ff9239b140b95ba5f02df55411..0551096fb4ef9c8fbe1d7507d9b341aea55ce196 100644 (file)
@@ -31,6 +31,7 @@ struct SWVoiceOut
        int freq, ch, bits;
        audfmt_e fmt;
        int left_volume, right_volume;
+       int streamid;
 };
 struct SWVoiceIn
 {
index 997a64de18504b2e82a30575e980ab1bd7e06d9f..055edb282b3b752c7d4022282f807e868db77c51 100644 (file)
@@ -111,6 +111,7 @@ typedef struct MemoryRegionIoeventfd MemoryRegionIoeventfd;
 typedef struct MemoryRegion {
     /* All fields are private - violators will be prosecuted */
     void *opaque;
+       void *data;
 #if 0
        const MemoryRegionOps *ops;
     MemoryRegion *parent;
index 21b9f3c813cb93eb5fb0cbd6323e1e5daab4b9f6..004a04236355c6a4c843b7378c21849ae7dc937c 100644 (file)
@@ -90,7 +90,7 @@ int64_t get_ticks_per_sec(void);
 
 #define isa_mem_base 0
 
-#define QemuConsole uint32_t
+#define QemuConsole void
 #define console_ch_t uint8_t
 typedef struct GraphicHwOps {
     void (*invalidate)(void *opaque);
@@ -104,7 +104,7 @@ typedef struct GraphicHwOps {
 #define ram_addr_t uint32_t
 
 typedef struct DisplaySurface {
-       void *bah;
+       void *data;
 } DisplaySurface;
 
 uint16_t le16_to_cpu(uint16_t v);
index 4a6ddbbdaf47e546e7fb3ac5ab09a740c0f90b77..ac794df0af57bb989834270c9a2306690df8a1d9 100644 (file)
@@ -95,7 +95,7 @@ struct romdata *getromdatabypath (const TCHAR *path)
        return NULL;
 }
 
-#define NEXT_ROM_ID 164
+#define NEXT_ROM_ID 165
 
 #define ALTROM(id,grp,num,size,flags,crc32,a,b,c,d,e) \
 { _T("X"), 0, 0, 0, 0, 0, size, id, 0, 0, flags, (grp << 16) | num, 0, NULL, crc32, a, b, c, d, e },
@@ -346,6 +346,7 @@ static struct romdata roms[] = {
        0x9e9781d5, 0xf65b60d1,0x4300c50f,0x2ed17cf4,0x4dcfdef9,0x16697bc9, NULL,  _T("tekmagic2060.rom") },
        ALTROMPN(104, 1, 1, 32768, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0x888da4cf, 0x6ae85f3a, 0x65331ba4, 0xaaba67ae, 0x34763d70, 0x2bde0495)
        ALTROMPN(104, 1, 2, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0xaf1f47db, 0x28d5bed0, 0xbc517d46, 0x500e8159, 0x723e0b64, 0x4733c26a)
+
        { _T("A2620/A2630 -07"), 0, 0, 0, 0, _T("A2620\0A2630\0"), 65536, 105, 0, 0, ROMTYPE_CB_A26x0, 0, 0, _T("390282-07/390283-07"),
        0x169d80e9, 0x41f518cb,0x41c1dc1f,0xcc636383,0x20676af5,0x4969010c, NULL, NULL },
        ALTROMPN(105, 1, 1, 32768, ROMTYPE_ODD  | ROMTYPE_8BIT, _T("390282-07"), 0xf2904058, 0x33695119, 0x5fdf5d56, 0x095a696b, 0x0ba2641d, 0x334845df)
@@ -354,6 +355,11 @@ static struct romdata roms[] = {
        0xeb31fd9e, 0x2d6a5c68,0x1040f98d,0x7e63ad08,0x90da9e83,0x2b5c704d, NULL, NULL },
        ALTROMPN(106, 1, 1, 32768, ROMTYPE_ODD  | ROMTYPE_8BIT, _T("390282-06"), 0xd6ae582c, 0x47b3dea3, 0x31db76e6, 0x1380a3d6, 0x9f191657, 0xdd1cd4b3)
        ALTROMPN(106, 1, 2, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, _T("390283-06"), 0xcd379634, 0x65e251e2, 0xf6961c8e, 0x33a86c3d, 0x01248f70, 0xa159823b)
+       { _T("A2620/A2630 -01"), 0, 0, 0, 0, _T("A2620\0A2630\0"), 65536, 164, 0, 0, ROMTYPE_CB_A26x0, 0, 0, _T("390282-01/390283-01"),
+       0x6ee2ecdd, 0x4c82e3ba, 0x2d2dd1d3, 0x82f01098, 0xc26681b8, 0xff62f36d, NULL, NULL },
+       ALTROMPN(164, 1, 1, 32768, ROMTYPE_ODD | ROMTYPE_8BIT, _T("390282-01"), 0xdf76493b, 0x331ede0a, 0x8ca995cc, 0x1917f592, 0x18718e5b, 0x3c7fac39)
+       ALTROMPN(164, 1, 2, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, _T("390283-01"), 0xd74187de, 0x681e4985, 0x4da64bf1, 0x6f2f99f7, 0x4b195f54, 0x0b8bd614)
+
        { _T("DKB 12x0"), 1, 23, 1, 23, _T("DKB\0"), 32768, 112, 0, 0, ROMTYPE_CB_DKB12x0, 0, 0, NULL,
        0xf3b2b0b3, 0x1d539593,0xb1d7514e,0xeb214ab3,0x433a97fc,0x8a010366, NULL, NULL },
        { _T("Fusion Forty"), 0, 0, 0, 0, _T("FUSIONFORTY\0"), 131072, 113, 0, 0, ROMTYPE_CB_FUSION, 0, 0, NULL,
@@ -1665,8 +1671,14 @@ int configure_rom (struct uae_prefs *p, const int *rom, int msg)
                _tcscpy (p->romfile, path);
        if (rd->type & (ROMTYPE_EXTCD32 | ROMTYPE_EXTCDTV | ROMTYPE_ARCADIABIOS))
                _tcscpy (p->romextfile, path);
-       if (rd->type & (ROMTYPE_CD32CART | ROMTYPE_ARCADIAGAME) ||
-               rd->type == ROMTYPE_HRTMON || rd->type == ROMTYPE_XPOWER || rd->type ==  ROMTYPE_NORDIC || rd->type == ROMTYPE_AR || rd->type ==  ROMTYPE_SUPERIV)
+       if (rd->type & ROMTYPE_CD32CART) {
+               _tcscpy(p->cartfile, path);
+               struct boardromconfig *brc = get_device_rom_new(p, ROMTYPE_CD32CART, 0, NULL);
+               if (brc)
+                       _tcscpy(brc->roms[0].romfile, p->cartfile);
+       }
+       if ((rd->type & ROMTYPE_ARCADIAGAME) ||
+               rd->type == ROMTYPE_HRTMON || rd->type == ROMTYPE_XPOWER || rd->type ==  ROMTYPE_NORDIC || rd->type == ROMTYPE_AR || rd->type == ROMTYPE_SUPERIV)
                _tcscpy (p->cartfile, path);
        if (rd->type & ROMTYPE_CPUBOARD)
                set_device_rom(p, path, ROMTYPE_CPUBOARD, 0);
@@ -1708,14 +1720,31 @@ const struct expansionromtype *get_device_expansion_rom(int romtype)
        return NULL;
 }
 
-static void device_rom_defaults(struct boardromconfig *brc, int romtype, int devnum)
+static void device_rom_defaults(struct uae_prefs *p, struct boardromconfig *brc, int romtype, int devnum)
 {
        memset(brc, 0, sizeof(boardromconfig));
        brc->device_type = romtype;
        brc->device_num = devnum;
        for (int i = 0; i < MAX_BOARD_ROMS; i++) {
                brc->roms[i].device_id = 7;     
+               brc->roms[i].back = brc;
+       }
+       int order = 0;
+       for (int i = 0; i < MAX_EXPANSION_BOARDS; i++) {
+               if (p->expansionboard[i].device_order > order)
+                       order = p->expansionboard[i].device_order;
+       }
+       for (int i = 0; i < MAX_RAM_BOARDS; i++) {
+               if (p->fastmem[i].device_order > order)
+                       order = p->fastmem[i].device_order;
+               if (p->z3fastmem[i].device_order > order)
+                       order = p->z3fastmem[i].device_order;
        }
+       for (int i = 0; i < MAX_RTG_BOARDS; i++) {
+               if (p->rtgboards[i].device_order > order)
+                       order = p->rtgboards[i].device_order;
+       }
+       brc->device_order = order + 1;
 }
 
 struct boardromconfig *get_device_rom_new(struct uae_prefs *p, int romtype, int devnum, int *index)
@@ -1724,10 +1753,12 @@ struct boardromconfig *get_device_rom_new(struct uae_prefs *p, int romtype, int
        static struct boardromconfig fake;
        const struct expansionromtype *ert = get_device_expansion_rom(romtype);
        if (!ert) {
-               *index = 0;
+               if (index)
+                       *index = 0;
                return &fake;
        }
-       *index = ert->parentromtype ? 1 : 0;
+       if (index)
+               *index = ert->parentromtype ? 1 : 0;
        struct boardromconfig *brc = get_device_rom(p, ert->parentromtype ? ert->parentromtype : romtype, devnum, &idx2);
        if (!brc) {
                for (int i = 0; i < MAX_EXPANSION_BOARDS; i++) {
@@ -1745,7 +1776,7 @@ struct boardromconfig *get_device_rom_new(struct uae_prefs *p, int romtype, int
                for (int i = 0; i < MAX_EXPANSION_BOARDS; i++) {
                        brc = &p->expansionboard[i];
                        if (brc->device_type == 0) {
-                               device_rom_defaults(brc, romtype, devnum);
+                               device_rom_defaults(p, brc, romtype, devnum);
                                return brc;
                        }
                }
index 390a25b0bf4e1aabf9ead5570ab4404e3de5896c..12fb3a557bdf8d83b52b5fb7e8a16b8b34ecce68 100644 (file)
@@ -407,14 +407,20 @@ static uae_u8 *restore_chunk (struct zfile *f, TCHAR *name, unsigned int *len, u
        /* chunk data.  RAM contents will be loaded during the reset phase,
           no need to malloc multiple megabytes here.  */
        if (_tcscmp (name, _T("CRAM")) != 0
-               && _tcscmp (name, _T("BRAM")) != 0
-               && _tcscmp (name, _T("FRAM")) != 0
-               && _tcscmp (name, _T("ZRAM")) != 0
-               && _tcscmp (name, _T("ZCRM")) != 0
-               && _tcscmp (name, _T("PRAM")) != 0
-               && _tcscmp (name, _T("A3K1")) != 0
-               && _tcscmp (name, _T("A3K2")) != 0
-               && _tcscmp (name, _T("BORO")) != 0
+               && _tcscmp(name, _T("BRAM")) != 0
+               && _tcscmp(name, _T("FRAM")) != 0
+               && _tcscmp(name, _T("ZRAM")) != 0
+               && _tcscmp(name, _T("FRA2")) != 0
+               && _tcscmp(name, _T("ZRA2")) != 0
+               && _tcscmp(name, _T("FRA3")) != 0
+               && _tcscmp(name, _T("ZRA3")) != 0
+               && _tcscmp(name, _T("FRA4")) != 0
+               && _tcscmp(name, _T("ZRA4")) != 0
+               && _tcscmp(name, _T("ZCRM")) != 0
+               && _tcscmp(name, _T("PRAM")) != 0
+               && _tcscmp(name, _T("A3K1")) != 0
+               && _tcscmp(name, _T("A3K2")) != 0
+               && _tcscmp(name, _T("BORO")) != 0
        )
        {
                /* extra bytes at the end needed to handle old statefiles that now have new fields */
@@ -498,7 +504,7 @@ void restore_state (const TCHAR *filename)
        TCHAR name[5];
        unsigned int len, totallen;
        size_t filepos, filesize;
-       int z3num;
+       int z3num, z2num;
 
        chunk = 0;
        f = zfile_fopen (filename, _T("rb"), ZFD_NORMAL);
@@ -521,7 +527,7 @@ void restore_state (const TCHAR *filename)
        restore_header (chunk);
        xfree (chunk);
        devices_restore_start();
-       z3num = 0;
+       z2num = z3num = 0;
        for (;;) {
                name[0] = 0;
                chunk = end = restore_chunk (f, name, &len, &totallen, &filepos);
@@ -547,10 +553,7 @@ void restore_state (const TCHAR *filename)
                        continue;
 #ifdef AUTOCONFIG
                } else if (!_tcscmp (name, _T("FRAM"))) {
-                       restore_fram (totallen, filepos, 0);
-                       continue;
-               } else if (!_tcscmp (name, _T("FRA2"))) {
-                       restore_fram (totallen, filepos, 1);
+                       restore_fram (totallen, filepos, z2num++);
                        continue;
                } else if (!_tcscmp (name, _T("ZRAM"))) {
                        restore_zram (totallen, filepos, z3num++);
@@ -674,11 +677,9 @@ void restore_state (const TCHAR *filename)
 #ifdef CDTV
                else if (!_tcscmp (name, _T("CDTV")))
                        end = restore_cdtv (chunk);
-#if 0
                else if (!_tcscmp (name, _T("DMAC")))
                        end = restore_cdtv_dmac (chunk);
 #endif
-#endif
 #if 0
                else if (!_tcscmp (name, _T("DMC2")))
                        end = restore_scsi_dmac (WDTYPE_A3000, chunk);
@@ -705,6 +706,8 @@ void restore_state (const TCHAR *filename)
                else if (!_tcsncmp (name, _T("2065"), 4))
                        end = restore_a2065 (chunk);
 #endif
+               else if (!_tcsncmp (name, _T("EXPI"), 4))
+                       end = restore_expansion_info(chunk);
                else if (!_tcsncmp (name, _T("DMWP"), 4))
                        end = restore_debug_memwatch (chunk);
 
@@ -798,14 +801,14 @@ static void save_rams (struct zfile *f, int comp)
        dst = save_a3000hram (&len);
        save_chunk (f, dst, len, _T("A3K2"), comp);
 #ifdef AUTOCONFIG
-       dst = save_fram (&len, 0);
-       save_chunk (f, dst, len, _T("FRAM"), comp);
-       dst = save_fram (&len, 1);
-       save_chunk (f, dst, len, _T("FRA2"), comp);
-       dst = save_zram (&len, 0);
-       save_chunk (f, dst, len, _T("ZRAM"), comp);
-       dst = save_zram (&len, 1);
-       save_chunk (f, dst, len, _T("ZRAM"), comp);
+       for (int i = 0; i < MAX_RAM_BOARDS; i++) {
+               dst = save_fram(&len, i);
+               save_chunk(f, dst, len, _T("FRAM"), comp);
+       }
+       for (int i = 0; i < MAX_RAM_BOARDS; i++) {
+               dst = save_zram(&len, i);
+               save_chunk(f, dst, len, _T("ZRAM"), comp);
+       }
        dst = save_zram (&len, -1);
        save_chunk (f, dst, len, _T("ZCRM"), comp);
        dst = save_bootrom (&len);
@@ -947,8 +950,10 @@ static int save_state_internal (struct zfile *f, const TCHAR *description, int c
        xfree (dst);
 
 #ifdef AUTOCONFIG
-       dst = save_expansion (&len, 0);
-       save_chunk (f, dst, len, _T("EXPA"), 0);
+       dst = save_expansion_info(&len, 0);
+       save_chunk(f, dst, len, _T("EXPI"), 0);
+       dst = save_expansion(&len, 0);
+       save_chunk(f, dst, len, _T("EXPA"), 0);
 #endif
 #ifdef A2065
        dst = save_a2065 (&len, NULL);
@@ -977,12 +982,10 @@ static int save_state_internal (struct zfile *f, const TCHAR *description, int c
        dst = save_cdtv (&len, NULL);
        save_chunk (f, dst, len, _T("CDTV"), 0);
        xfree (dst);
-#if 0
        dst = save_cdtv_dmac (&len, NULL);
        save_chunk (f, dst, len, _T("DMAC"), 0);
        xfree (dst);
 #endif
-#endif
 #if 0
        dst = save_scsi_dmac (WDTYPE_A3000, &len, NULL);
        save_chunk (f, dst, len, _T("DMC2"), 0);
@@ -1300,10 +1303,10 @@ void savestate_rewind (void)
        p += len;
 #ifdef AUTOCONFIG
        len = restore_u32_func (&p);
-       memcpy (save_fram (&dummy, 0), p, currprefs.fastmem_size > len ? len : currprefs.fastmem_size);
+       memcpy (save_fram (&dummy, 0), p, currprefs.fastmem[0].size > len ? len : currprefs.fastmem[0].size);
        p += len;
        len = restore_u32_func (&p);
-       memcpy (save_zram (&dummy, 0), p, currprefs.z3fastmem_size > len ? len : currprefs.z3fastmem_size);
+       memcpy (save_zram (&dummy, 0), p, currprefs.z3fastmem[0].size > len ? len : currprefs.z3fastmem[0].size);
        p += len;
 #endif
 #ifdef ACTION_REPLAY
index 72bf02c538a7499d3b48e31e0b646f7b3cfda557..730f53309ab073823baae80ef5c557d42ad39b93 100644 (file)
--- a/scsi.cpp
+++ b/scsi.cpp
@@ -2842,8 +2842,8 @@ static void ncr80_bput2(struct soft_scsi *ncr, uaecptr addr, uae_u32 val, int si
                        ncr->rom[addr] = val & (0x80 | 0x40 | 0x02);
                } else if (addr == 0x1024) {
                        // memory board memory address reg
-                       if (currprefs.fastmem2_size)
-                               map_banks_z2(&fastmem2_bank, val, currprefs.fastmem2_size >> 16);
+                       if (currprefs.fastmem[0].size)
+                               map_banks_z2(&fastmem_bank[0], val, currprefs.fastmem[0].size >> 16);
                }
                else if (addr >= 0x2000 && addr < 0x3000) {
                        // clock
@@ -3066,8 +3066,8 @@ static void REGPARAM2 ncr80_bput(struct soft_scsi *ncr, uaecptr addr, uae_u32 b)
                switch (addr)
                {
                        case 0x48:
-                       map_banks_z2(ncr->bank, expamem_z2_pointer >> 16, ncr->board_size >> 16);
-                       ncr->baseaddress = expamem_z2_pointer;
+                       map_banks_z2(ncr->bank, expamem_board_pointer >> 16, ncr->board_size >> 16);
+                       ncr->baseaddress = expamem_board_pointer;
                        ncr->configured = 1;
                        expamem_next (ncr->bank, NULL);
                        break;
@@ -3201,26 +3201,30 @@ void soft_scsi_reset(void)
 
 */
 
-addrbank *supra_init(struct romconfig *rc)
+bool supra_init(struct autoconfig_info *aci)
 {
-       struct soft_scsi *scsi = getscsi(rc);
+       const struct expansionromtype *ert = get_device_expansion_rom(ROMTYPE_SUPRA);
+       aci->autoconfigp = ert->subtypes[aci->rc->subtype].autoconfig;
+       if (!aci->doinit)
+               return true;
 
+       struct soft_scsi *scsi = getscsi(aci->rc);
        if (!scsi)
-               return &expamem_null;
+               return false;
 
        scsi->intena = true;
 
-       const struct expansionromtype *ert = get_device_expansion_rom(ROMTYPE_SUPRA);
        struct zfile *z = NULL;
-       scsi->subtype = rc->subtype;
-       if (!rc->autoboot_disabled && scsi->subtype != 3) {
+       scsi->subtype = aci->rc->subtype;
+       if (!aci->rc->autoboot_disabled && scsi->subtype != 3) {
                for (int i = 0; i < 16; i++) {
-                       uae_u8 b = ert->subtypes[rc->subtype].autoconfig[i];
+                       uae_u8 b = ert->subtypes[aci->rc->subtype].autoconfig[i];
                        ew(scsi, i * 4, b);
                }
-               load_rom_rc(rc, ROMTYPE_SUPRA, 16384, 0, scsi->rom, 32768, LOADROM_EVENONLY_ODDONE | LOADROM_FILL);
+               load_rom_rc(aci->rc, ROMTYPE_SUPRA, 16384, 0, scsi->rom, 32768, LOADROM_EVENONLY_ODDONE | LOADROM_FILL);
        }
-       return scsi->bank;
+       aci->addrbank = scsi->bank;
+       return true;
 }
 
 void supra_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
@@ -3228,19 +3232,24 @@ void supra_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig
        generic_soft_scsi_add(ch, ci, rc, NCR5380_SUPRA, 65536, 2 * 16384, ROMTYPE_SUPRA);
 }
 
-addrbank *golem_init(struct romconfig *rc)
+bool golem_init(struct autoconfig_info *aci)
 {
-       struct soft_scsi *scsi = getscsi(rc);
-       
+       if (!aci->doinit) {
+               load_rom_rc(aci->rc, ROMTYPE_GOLEM, 8192, aci->rc->autoboot_disabled ? 8192 : 0, aci->autoconfig_raw, 128, 0);
+               return true;
+       }
+
+       struct soft_scsi *scsi = getscsi(aci->rc);      
        if (!scsi)
-               return &expamem_null;
+               return false;
 
        scsi->intena = true;
 
-       load_rom_rc(rc, ROMTYPE_GOLEM, 8192, rc->autoboot_disabled ? 8192 : 0, scsi->rom, 8192, 0);
+       load_rom_rc(aci->rc, ROMTYPE_GOLEM, 8192, aci->rc->autoboot_disabled ? 8192 : 0, scsi->rom, 8192, 0);
        memcpy(scsi->acmemory, scsi->rom, sizeof scsi->acmemory);
 
-       return scsi->bank;
+       aci->addrbank = scsi->bank;
+       return true;
 }
 
 void golem_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
@@ -3248,19 +3257,23 @@ void golem_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig
        generic_soft_scsi_add(ch, ci, rc, NONCR_GOLEM, 65536, 8192, ROMTYPE_GOLEM);
 }
 
-addrbank *stardrive_init(struct romconfig *rc)
+bool stardrive_init(struct autoconfig_info *aci)
 {
-       struct soft_scsi *scsi = getscsi(rc);
-       
+       const struct expansionromtype *ert = get_device_expansion_rom(ROMTYPE_STARDRIVE);
+       aci->autoconfigp = ert->autoconfig;
+       if (!aci->doinit)
+               return true;
+
+       struct soft_scsi *scsi = getscsi(aci->rc);      
        if (!scsi)
-               return &expamem_null;
+               return false;
 
-       const struct expansionromtype *ert = get_device_expansion_rom(ROMTYPE_STARDRIVE);
        for (int i = 0; i < 16; i++) {
                uae_u8 b = ert->autoconfig[i];
                ew(scsi, i * 4, b);
        }
-       return scsi->bank;
+       aci->addrbank = scsi->bank;
+       return true;
 }
 
 void stardrive_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
@@ -3268,23 +3281,26 @@ void stardrive_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romco
        generic_soft_scsi_add(ch, ci, rc, NCR5380_STARDRIVE, 65536, 0, ROMTYPE_STARDRIVE);
 }
 
-addrbank *kommos_init(struct romconfig *rc)
+bool kommos_init(struct autoconfig_info *aci)
 {
-       struct soft_scsi *scsi = getscsi(rc);
+       if (!aci->doinit)
+               return true;
+
+       struct soft_scsi *scsi = getscsi(aci->rc);
        
        if (!scsi)
-               return NULL;
+               return false;
 
        scsi->configured = 1;
 
-       load_rom_rc(rc, ROMTYPE_KOMMOS, 32768, 0, scsi->rom, 32768, 0);
+       load_rom_rc(aci->rc, ROMTYPE_KOMMOS, 32768, 0, scsi->rom, 32768, 0);
 
        map_banks(scsi->bank, 0xf10000 >> 16, 1, 0);
        map_banks(scsi->bank, 0xeb0000 >> 16, 1, 0);
        scsi->baseaddress = 0xeb0000;
        scsi->baseaddress2 = 0xf10000;
 
-       return NULL;
+       return true;
 }
 
 void kommos_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
@@ -3292,24 +3308,30 @@ void kommos_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfi
        generic_soft_scsi_add(ch, ci, rc, NONCR_KOMMOS, 65536, 32768, ROMTYPE_KOMMOS);
 }
 
-addrbank *vector_init(struct romconfig *rc)
+bool vector_init(struct autoconfig_info *aci)
 {
-       struct soft_scsi *scsi = getscsi(rc);
+       if (!aci->doinit) {
+               load_rom_rc(aci->rc, ROMTYPE_VECTOR, 32768, 0, aci->autoconfig_raw, 128, 0);
+               return true;
+       }
+
+       struct soft_scsi *scsi = getscsi(aci->rc);
        int roms[2];
        
        if (!scsi)
-               return &expamem_null;
+               return false;
 
        roms[0] = 128;
        roms[1] = -1;
 
        scsi->intena = true;
 
-       if (!rc->autoboot_disabled) {
-               load_rom_rc(rc, ROMTYPE_VECTOR, 32768, 0, scsi->rom, 32768, 0);
+       if (!aci->rc->autoboot_disabled) {
+               load_rom_rc(aci->rc, ROMTYPE_VECTOR, 32768, 0, scsi->rom, 32768, 0);
                memcpy(scsi->acmemory, scsi->rom, sizeof scsi->acmemory);
        }
-       return scsi->bank;
+       aci->addrbank = scsi->bank;
+       return true;
 }
 
 void vector_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
@@ -3318,16 +3340,21 @@ void vector_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfi
 }
 
 
-addrbank *protar_init(struct romconfig *rc)
+bool protar_init(struct autoconfig_info *aci)
 {
-       struct soft_scsi *scsi = getscsi(rc);
-       
+       if (!aci->doinit) {
+               load_rom_rc(aci->rc, ROMTYPE_PROTAR, 32768, 0x200, aci->autoconfig_raw, 128, LOADROM_EVENONLY_ODDONE);
+               return true;
+       }
+
+       struct soft_scsi *scsi = getscsi(aci->rc);
        if (!scsi)
-               return &expamem_null;
+               return false;
 
-       load_rom_rc(rc, ROMTYPE_PROTAR, 32768, 0, scsi->rom, 32768, LOADROM_EVENONLY_ODDONE);
+       load_rom_rc(aci->rc, ROMTYPE_PROTAR, 32768, 0, scsi->rom, 32768, LOADROM_EVENONLY_ODDONE);
        memcpy(scsi->acmemory, scsi->rom + 0x200 * 2, sizeof scsi->acmemory);
-       return scsi->bank;
+       aci->addrbank = scsi->bank;
+       return true;
 }
 
 void protar_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
@@ -3335,16 +3362,21 @@ void protar_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig
        generic_soft_scsi_add(ch, ci, rc, NCR5380_PROTAR, 65536, 65536, ROMTYPE_PROTAR);
 }
 
-addrbank *add500_init(struct romconfig *rc)
+bool add500_init(struct autoconfig_info *aci)
 {
-       struct soft_scsi *scsi = getscsi(rc);
-       
+       if (!aci->doinit) {
+               load_rom_rc(aci->rc, ROMTYPE_ADD500, 16384, 0, aci->autoconfig_raw, 128, LOADROM_EVENONLY_ODDONE | LOADROM_FILL);
+               return true;
+       }
+
+       struct soft_scsi *scsi = getscsi(aci->rc);
        if (!scsi)
-               return &expamem_null;
+               return false;
 
-       load_rom_rc(rc, ROMTYPE_ADD500, 16384, 0, scsi->rom, 32768, LOADROM_EVENONLY_ODDONE | LOADROM_FILL);
+       load_rom_rc(aci->rc, ROMTYPE_ADD500, 16384, 0, scsi->rom, 32768, LOADROM_EVENONLY_ODDONE | LOADROM_FILL);
        memcpy(scsi->acmemory, scsi->rom, sizeof scsi->acmemory);
-       return scsi->bank;
+       aci->addrbank = scsi->bank;
+       return true;
 }
 
 void add500_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
@@ -3352,18 +3384,21 @@ void add500_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfi
        generic_soft_scsi_add(ch, ci, rc, NCR5380_ADD500, 65536, 32768, ROMTYPE_ADD500);
 }
 
-addrbank *kronos_init(struct romconfig *rc)
+bool kronos_init(struct autoconfig_info *aci)
 {
-       struct soft_scsi *scsi = getscsi(rc);
-       
+       if (!aci->doinit)
+               return true;
+
+       struct soft_scsi *scsi = getscsi(aci->rc);      
        if (!scsi)
-               return &expamem_null;
+               return false;
 
        scsi->databuffer_size = 1024;
        scsi->databufferptr = xcalloc(uae_u8, scsi->databuffer_size);
 
-       load_rom_rc(rc, ROMTYPE_KRONOS, 4096, 0, scsi->rom, 32768, LOADROM_EVENONLY_ODDONE | LOADROM_FILL);
-       return scsi->bank;
+       load_rom_rc(aci->rc, ROMTYPE_KRONOS, 4096, 0, scsi->rom, 32768, LOADROM_EVENONLY_ODDONE | LOADROM_FILL);
+       aci->addrbank = scsi->bank;
+       return true;
 }
 
 void kronos_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
@@ -3371,16 +3406,21 @@ void kronos_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfi
        generic_soft_scsi_add(ch, ci, rc, NCR5380_KRONOS, 65536, 32768, ROMTYPE_KRONOS);
 }
 
-addrbank *adscsi_init(struct romconfig *rc)
+bool adscsi_init(struct autoconfig_info *aci)
 {
-       struct soft_scsi *scsi = getscsi(rc);
-       
+       if (!aci->doinit) {
+               load_rom_rc(aci->rc, ROMTYPE_ADSCSI, 32768, 0, aci->autoconfig_raw, 128, LOADROM_EVENONLY_ODDONE | LOADROM_FILL);
+               return true;
+       }
+
+       struct soft_scsi *scsi = getscsi(aci->rc);      
        if (!scsi)
-               return &expamem_null;
+               return false;
 
-       load_rom_rc(rc, ROMTYPE_ADSCSI, 32768, 0, scsi->rom, 65536, LOADROM_EVENONLY_ODDONE | LOADROM_FILL);
+       load_rom_rc(aci->rc, ROMTYPE_ADSCSI, 32768, 0, scsi->rom, 65536, LOADROM_EVENONLY_ODDONE | LOADROM_FILL);
        memcpy(scsi->acmemory, scsi->rom, sizeof scsi->acmemory);
-       return scsi->bank;
+       aci->addrbank = scsi->bank;
+       return true;
 }
 
 void adscsi_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
@@ -3388,24 +3428,27 @@ void adscsi_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfi
        generic_soft_scsi_add(ch, ci, rc, NCR5380_ADSCSI, 65536, 65536, ROMTYPE_ADSCSI);
 }
 
-addrbank *trumpcardpro_init(struct romconfig *rc)
+bool trumpcardpro_init(struct autoconfig_info *aci)
 {
-       struct soft_scsi *scsi = getscsi(rc);
+       const struct expansionromtype *ert = get_device_expansion_rom(ROMTYPE_IVSTPRO);
+       aci->autoconfigp = ert->autoconfig;
+       if (!aci->doinit)
+               return true;
 
+       struct soft_scsi *scsi = getscsi(aci->rc);
        if (!scsi)
-               return &expamem_null;
+               return false;
 
        scsi->intena = true;
 
-       load_rom_rc(rc, ROMTYPE_IVSTPRO, 16384, 0, scsi->rom, 32768, LOADROM_EVENONLY_ODDONE | LOADROM_FILL);
+       load_rom_rc(aci->rc, ROMTYPE_IVSTPRO, 16384, 0, scsi->rom, 32768, LOADROM_EVENONLY_ODDONE | LOADROM_FILL);
 
-       const struct expansionromtype *ert = get_device_expansion_rom(ROMTYPE_IVSTPRO);
        for (int i = 0; i < 16; i++) {
                uae_u8 b = ert->autoconfig[i];
                ew(scsi, i * 4, b);
        }
-
-       return scsi->bank;
+       aci->addrbank = scsi->bank;
+       return true;
 }
 
 void trumpcardpro_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
@@ -3436,21 +3479,27 @@ void rochard_scsi_put(uaecptr addr, uae_u8 v)
        soft_generic_bput(addr, v);
 }
 
-addrbank *cltda1000scsi_init(struct romconfig *rc) {
-       struct soft_scsi *scsi = getscsi(rc);
+bool cltda1000scsi_init(struct autoconfig_info *aci)
+{
+       const struct expansionromtype *ert = get_device_expansion_rom(ROMTYPE_CLTDSCSI);
+       aci->autoconfigp = ert->autoconfig;
+       if (!aci->doinit)
+               return true;
+
+       struct soft_scsi *scsi = getscsi(aci->rc);
 
        if (!scsi)
-               return &expamem_null;
+               return false;
 
        scsi->intena = true;
        scsi->delayed_irq = true;
 
-       const struct expansionromtype *ert = get_device_expansion_rom(ROMTYPE_CLTDSCSI);
        for (int i = 0; i < 16; i++) {
                uae_u8 b = ert->autoconfig[i];
                ew(scsi, i * 4, b);
        }
-       return scsi->bank;
+       aci->addrbank = scsi->bank;
+       return true;
 }
 
 void cltda1000scsi_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
@@ -3458,24 +3507,28 @@ void cltda1000scsi_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct r
        generic_soft_scsi_add(ch, ci, rc, NCR5380_CLTD, 65536, 0, ROMTYPE_CLTDSCSI);
 }
 
-addrbank *ptnexus_init(struct romconfig *rc)
+bool ptnexus_init(struct autoconfig_info *aci)
 {
-       struct soft_scsi *scsi = getscsi(rc);
+       const struct expansionromtype *ert = get_device_expansion_rom(ROMTYPE_PTNEXUS);
+       if (!aci->doinit) {
+               aci->autoconfigp = ert->autoconfig;
+               return true;
+       }
 
+       struct soft_scsi *scsi = getscsi(aci->rc);
        if (!scsi)
-               return &expamem_null;
+               return false;
 
        scsi->intena = true;
        scsi->delayed_irq = true;
 
-       const struct expansionromtype *ert = get_device_expansion_rom(ROMTYPE_PTNEXUS);
        for (int i = 0; i < 16; i++) {
                uae_u8 b = ert->autoconfig[i];
                ew(scsi, i * 4, b);
        }
-
-       load_rom_rc(rc, ROMTYPE_PTNEXUS, 8192, 0, scsi->rom, 65536, LOADROM_EVENONLY_ODDONE | LOADROM_FILL);
-       return scsi->bank;
+       load_rom_rc(aci->rc, ROMTYPE_PTNEXUS, 8192, 0, scsi->rom, 65536, LOADROM_EVENONLY_ODDONE | LOADROM_FILL);
+       aci->addrbank = scsi->bank;
+       return true;
 }
 
 void ptnexus_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
@@ -3483,19 +3536,22 @@ void ptnexus_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconf
        generic_soft_scsi_add(ch, ci, rc, NCR5380_PTNEXUS, 65536, 65536, ROMTYPE_PTNEXUS);
 }
 
-addrbank *dataflyer_init(struct romconfig *rc)
+bool dataflyer_init(struct autoconfig_info *aci)
 {
-       struct soft_scsi *scsi = getscsi(rc);
+       if (!aci->doinit)
+               return true;
+
+       struct soft_scsi *scsi = getscsi(aci->rc);
 
        if (!scsi)
-               return &expamem_null;
+               return false;
 
        scsi->baseaddress = (currprefs.cs_ide == IDE_A4000) ? 0xdd2000 : 0xda0000;
        scsi->configured = true;
 
        gayle_dataflyer_enable(true);
 
-       return NULL;
+       return true;
 }
 
 void dataflyer_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
@@ -3554,19 +3610,23 @@ static void expansion_add_protoautoconfig_board(uae_u8 *p, int board, uae_u16 ma
        }
 }
 
-addrbank *tecmar_init(struct romconfig *rc)
+bool tecmar_init(struct autoconfig_info *aci)
 {
-       struct soft_scsi *scsi = getscsi(rc);
-       int index = 0;
+       static const uae_u8 ac[16] = { 0x40, 0xff, 0, 0, 1001 >> 8, (uae_u8)1001 };
+       if (!aci->doinit) {
+               aci->autoconfigp = ac;
+               return true;
+       }
 
+       struct soft_scsi *scsi = getscsi(aci->rc);
+       int index = 0;
        if (!scsi)
-               return &expamem_null;
+               return false;
 
-       const struct expansionromtype *ert = get_device_expansion_rom(ROMTYPE_PTNEXUS);
        scsi->rom = xcalloc(uae_u8, 65536);
        expansion_add_protoautoconfig_box(scsi->rom, 3, 1001, 0);
        // memory
-       expansion_add_protoautoconfig_board(scsi->rom, index++, 1001, 1, currprefs.fastmem2_size);
+       expansion_add_protoautoconfig_board(scsi->rom, index++, 1001, 1, currprefs.fastmem[0].size);
        // clock
        expansion_add_protoautoconfig_board(scsi->rom, index++, 1001, 2, 0);
        // serial
@@ -3579,7 +3639,8 @@ addrbank *tecmar_init(struct romconfig *rc)
        tecmar_clock_regs[11] = 0x04 | 0x02 | 0x01;
        scsi->configured = true;
        scsi->baseaddress = 0xe80000;
-       return scsi->bank;
+       aci->addrbank = scsi->bank;
+       return true;
 }
 
 void tecmar_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
@@ -3587,18 +3648,20 @@ void tecmar_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfi
        generic_soft_scsi_add(ch, ci, rc, NONCR_TECMAR, 65536, 65536, ROMTYPE_TECMAR);
 }
 
-addrbank *microforge_init(struct romconfig *rc)
+bool microforge_init(struct autoconfig_info *aci)
 {
-       struct soft_scsi *scsi = getscsi(rc);
+       if (!aci->doinit)
+               return true;
 
+       struct soft_scsi *scsi = getscsi(aci->rc);
        if (!scsi)
-               return NULL;
+               return false;
 
        scsi->configured = 1;
 
        map_banks(scsi->bank, 0xef0000 >> 16, 0x10000 >> 16, 0);
        scsi->baseaddress = 0xef0000;
-       return NULL;
+       return true;
 }
 
 void microforge_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
@@ -3606,12 +3669,14 @@ void microforge_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romc
        generic_soft_scsi_add(ch, ci, rc, NONCR_MICROFORGE, 65536, 0, ROMTYPE_MICROFORGE);
 }
 
-addrbank *xebec_init(struct romconfig *rc)
+bool xebec_init(struct autoconfig_info *aci)
 {
-       struct soft_scsi *scsi = getscsi(rc);
+       if (!aci->doinit)
+               return true;
 
+       struct soft_scsi *scsi = getscsi(aci->rc);
        if (!scsi)
-               return NULL;
+               return false;
 
        scsi->configured = 1;
 
@@ -3623,7 +3688,7 @@ addrbank *xebec_init(struct romconfig *rc)
        scsi->dma_controller = true;
        scsi->databuffer_size = 32768;
        scsi->databufferptr = xcalloc(uae_u8, scsi->databuffer_size);
-       return NULL;
+       return true;
 }
 
 void xebec_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
@@ -3631,18 +3696,20 @@ void xebec_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig
        generic_soft_scsi_add(ch, ci, rc, NCR5380_XEBEC, 65536, 0, ROMTYPE_XEBEC);
 }
 
-addrbank *paradox_init(struct romconfig *rc)
+bool paradox_init(struct autoconfig_info *aci)
 {
-       struct soft_scsi *scsi = getscsi(rc);
+       if (!aci->doinit)
+               return true;
 
+       struct soft_scsi *scsi = getscsi(aci->rc);
        if (!scsi)
-               return NULL;
+               return false;
 
        scsi->configured = 1;
        parallel_port_scsi = true;
        parallel_port_scsi_data = scsi;
 
-       return NULL;
+       return true;
 }
 
 void paradox_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
@@ -3650,21 +3717,27 @@ void paradox_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconf
        generic_soft_scsi_add(ch, ci, rc, NONCR_PARADOX, 0, 0, ROMTYPE_PARADOX);
 }
 
-addrbank *hda506_init(struct romconfig *rc)
+bool hda506_init(struct autoconfig_info *aci)
 {
-       struct soft_scsi *scsi = getscsi(rc);
+       const struct expansionromtype *ert = get_device_expansion_rom(ROMTYPE_HDA506);
 
+       if (!aci->doinit) {
+               aci->autoconfigp = ert->autoconfig;
+               return true;
+       }
+
+       struct soft_scsi *scsi = getscsi(aci->rc);
        if (!scsi)
-               return NULL;
+               return false;
 
-       const struct expansionromtype *ert = get_device_expansion_rom(ROMTYPE_HDA506);
        for (int i = 0; i < 16; i++) {
                uae_u8 b = ert->autoconfig[i];
                ew(scsi, i * 4, b);
        }
        scsi->level6 = true;
        scsi->intena = true;
-       return scsi->bank;
+       aci->addrbank  = scsi->bank;
+       return true;
 }
 
 void hda506_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
@@ -3672,18 +3745,20 @@ void hda506_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfi
        generic_soft_scsi_add(ch, ci, rc, OMTI_HDA506, 0, 0, ROMTYPE_HDA506);
 }
 
-addrbank *alf1_init(struct romconfig *rc)
+bool alf1_init(struct autoconfig_info *aci)
 {
-       struct soft_scsi *scsi = getscsi(rc);
+       if (!aci->doinit)
+               return true;
 
+       struct soft_scsi *scsi = getscsi(aci->rc);
        if (!scsi)
-               return NULL;
+               return false;
        map_banks(scsi->bank, 0xef0000 >> 16, 0x10000 >> 16, 0);
        scsi->board_mask = 0xffff;
        scsi->baseaddress = 0xef0000;
        scsi->configured = 1;
-
-       return scsi->bank;
+       aci->addrbank = scsi->bank;
+       return true;
 }
 
 void alf1_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
@@ -3691,19 +3766,22 @@ void alf1_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig
        generic_soft_scsi_add(ch, ci, rc, OMTI_ALF1, 65536, 0, ROMTYPE_ALF1);
 }
 
-addrbank *promigos_init(struct romconfig *rc)
+bool promigos_init(struct autoconfig_info *aci)
 {
-       struct soft_scsi *scsi = getscsi(rc);
+       if (!aci->doinit)
+               return true;
 
+       struct soft_scsi *scsi = getscsi(aci->rc);
        if (!scsi)
-               return NULL;
+               return false;
        map_banks(scsi->bank, 0xf40000 >> 16, 0x10000 >> 16, 0);
        scsi->board_mask = 0xffff;
        scsi->baseaddress = 0xf40000;
        scsi->configured = 1;
        scsi->intena = true;
 
-       return scsi->bank;
+       aci->addrbank = scsi->bank;
+       return true;
 }
 
 void promigos_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
@@ -3711,20 +3789,24 @@ void promigos_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romcon
        generic_soft_scsi_add(ch, ci, rc, OMTI_PROMIGOS, 65536, 0, ROMTYPE_PROMIGOS);
 }
 
-addrbank *system2000_init(struct romconfig *rc)
+bool system2000_init(struct autoconfig_info *aci)
 {
-       struct soft_scsi *scsi = getscsi(rc);
+       if (!aci->doinit)
+               return true;
+
+       struct soft_scsi *scsi = getscsi(aci->rc);
 
        if (!scsi)
-               return NULL;
+               return false;
        map_banks(scsi->bank, 0xf00000 >> 16, 0x10000 >> 16, 0);
        scsi->board_mask = 0xffff;
        scsi->baseaddress = 0xf00000;
        scsi->configured = 1;
-       if (!rc->autoboot_disabled) {
-               load_rom_rc(rc, ROMTYPE_SYSTEM2000, 16384, 0, scsi->rom, 16384, 0);
+       if (!aci->rc->autoboot_disabled) {
+               load_rom_rc(aci->rc, ROMTYPE_SYSTEM2000, 16384, 0, scsi->rom, 16384, 0);
        }
-       return scsi->bank;
+       aci->addrbank = scsi->bank;
+       return true;
 }
 
 void system2000_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
@@ -3732,17 +3814,21 @@ void system2000_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romc
        generic_soft_scsi_add(ch, ci, rc, OMTI_SYSTEM2000, 65536, 16384, ROMTYPE_SYSTEM2000);
 }
 
-addrbank *omtiadapter_init(struct romconfig *rc)
+bool omtiadapter_init(struct autoconfig_info *aci)
 {
-       struct soft_scsi *scsi = getscsi(rc);
+       if (!aci->doinit)
+               return true;
+
+       struct soft_scsi *scsi = getscsi(aci->rc);
 
        if (!scsi)
-               return NULL;
+               return false;
        map_banks(scsi->bank, 0x8f0000 >> 16, 0x10000 >> 16, 0);
        scsi->board_mask = 0xffff;
        scsi->baseaddress = 0x8f0000;
        scsi->configured = 1;
-       return scsi->bank;
+       aci->addrbank = scsi->bank;
+       return true;
 }
 
 void omtiadapter_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
@@ -3751,18 +3837,21 @@ void omtiadapter_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconf
 }
 
 extern void x86_xt_ide_bios(struct zfile*, struct romconfig *rc);
-addrbank *x86_xt_hd_init(struct romconfig *rc)
+bool x86_xt_hd_init(struct autoconfig_info *aci)
 {
-       struct soft_scsi *scsi = getscsi(rc);
+       if (!aci->doinit)
+               return true;
+
+       struct soft_scsi *scsi = getscsi(aci->rc);
 
        if (!scsi)
-               return NULL;
-       struct zfile *f = read_device_from_romconfig(rc, 0);
-       x86_xt_ide_bios(f, rc);
+               return false;
+       struct zfile *f = read_device_from_romconfig(aci->rc, 0);
+       x86_xt_ide_bios(f, aci->rc);
        zfile_fclose(f);
        scsi->configured = 1;
        x86_hd_data = scsi;
-       return NULL;
+       return true;
 }
 
 void x86_add_xt_hd_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
@@ -3770,19 +3859,24 @@ void x86_add_xt_hd_unit(int ch, struct uaedev_config_info *ci, struct romconfig
        generic_soft_scsi_add(ch, ci, rc, OMTI_X86, 0, 0, ROMTYPE_X86_HD);
 }
 
-addrbank *phoenixboard_init(struct romconfig *rc)
+bool phoenixboard_init(struct autoconfig_info *aci)
 {
-       struct soft_scsi *scsi = getscsi(rc);
+       if (!aci->doinit) {
+               load_rom_rc(aci->rc, ROMTYPE_PHOENIXB, 8192, aci->rc->autoboot_disabled ? 0 : 8192, aci->autoconfig_raw, 128, LOADROM_EVENONLY_ODDONE | LOADROM_FILL);
+               return true;
+       }
+
+       struct soft_scsi *scsi = getscsi(aci->rc);
 
        if (!scsi)
-               return NULL;
+               return false;
 
-       const struct expansionromtype *ert = get_device_expansion_rom(ROMTYPE_PHOENIXB);
-       load_rom_rc(rc, ROMTYPE_PHOENIXB, 8192, rc->autoboot_disabled ? 0 : 8192, scsi->rom, 16384, LOADROM_EVENONLY_ODDONE | LOADROM_FILL);
-       load_rom_rc(rc, ROMTYPE_PHOENIXB, 16384, 16384, scsi->rom + 16384, 16384, LOADROM_EVENONLY_ODDONE | LOADROM_FILL);
+       load_rom_rc(aci->rc, ROMTYPE_PHOENIXB, 8192, aci->rc->autoboot_disabled ? 0 : 8192, scsi->rom, 16384, LOADROM_EVENONLY_ODDONE | LOADROM_FILL);
+       load_rom_rc(aci->rc, ROMTYPE_PHOENIXB, 16384, 16384, scsi->rom + 16384, 16384, LOADROM_EVENONLY_ODDONE | LOADROM_FILL);
        memcpy(scsi->acmemory, scsi->rom, sizeof scsi->acmemory);
 
-       return scsi->bank;
+       aci->addrbank = scsi->bank;
+       return true;
 }
 
 void phoenixboard_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
index 7d4b6df25d767636eeff4bbd6afaddaf1fd4443e..c280c125aaa769edcb1b08d283b74fd694c03cdc 100644 (file)
@@ -21,6 +21,7 @@
 #include "autoconf.h"
 #include "pci_hw.h"
 #include "qemuvga/qemuaudio.h"
+#include "rommgr.h"
 
 static uae_u8 *sndboard_get_buffer(int *frames);
 static void sndboard_release_buffer(uae_u8 *buffer, int frames);
@@ -29,6 +30,785 @@ static bool sndboard_init_capture(int freq);
 
 static double base_event_clock;
 
+extern addrbank uaesndboard_bank;
+
+#define MAX_DUPLICATE_SOUND_BOARDS 1
+
+static int uaesnd_active;
+#define MAX_UAE_CHANNELS 8
+#define MAX_UAE_STREAMS 8
+struct uaesndboard_stream
+{
+       int streamid;
+       int play;
+       int ch;
+       int bits;
+       int volume;
+       int freq;
+       int event_time;
+       uaecptr setaddr;
+       uaecptr address;
+       uaecptr next;
+       uaecptr repeat;
+       int len;
+       int replen;
+       int repcnt;
+       bool first;
+       bool repeating;
+       uae_u8 chmode;
+       uae_u8 intenamask;
+       uae_u8 intreqmask;
+       int framesize;
+       uae_u8 io[256];
+       uae_u16 wordlatch;
+       int sample[MAX_UAE_CHANNELS];
+};
+struct uaesndboard_data
+{
+       bool enabled;
+       bool z3;
+       int configured;
+       uae_u32 streammask;
+       uae_u32 streamallocmask;
+       uae_u8 acmemory[128];
+       int streamcnt;
+       int volume[MAX_UAE_CHANNELS];
+       struct uaesndboard_stream stream[MAX_UAE_STREAMS];
+       uae_u8 info[256];
+};
+static struct uaesndboard_data uaesndboard[MAX_DUPLICATE_SOUND_BOARDS];
+
+/*
+       autoconfig data
+
+       manufacturer 6502
+       product 2
+       Z2 64k board or Z3 16M board, no boot rom.
+
+       uaesnd sample set structure, located in Amiga address space.
+       It is never modified by UAE. Must be at least word aligned.
+
+        0.L sample address pointer
+        4.L sample length (in frames, negative = play backwards, set address after last sample.). 0 = next set/repeat after single sample period.
+        8.L playback frequency
+       12.L repeat sample address pointer (ignored if repeat count=0)
+       16.L repeat sample length (ignored if repeat count=0, negative = play backwards)
+       20.W repeat count (0=no repeat, -1=forever)
+       22.W volume (0 to 32768)
+       24.L next sample set address (0=end)
+       28.B number of channels. (interleaved samples if 2 or more channels)
+       29.B bits per sample (8, 16, 24 and 32)
+       30.B bit 0: interrupt when set starts, bit 1: interrupt when set ends, bit 2: interrupt when repeat, bit 3: after each sample.
+       31.B if mono stream, bit mask that selects output channels. (0=default, redirect to left and right channels)
+       (Can be used for example when playing tracker modules by using 4 single channel streams)
+       stereo or higher: channel mode.
+
+       Mode = 0
+
+       2: left, right
+       4: left, right, left back, right back
+       6: left, right, center, lfe, left back, right back, left surround
+       8: left, right, center, lfe, left back, right back, right surround
+
+       Mode = 1 (alternate channel order)
+
+       2: left, right (no change)
+       4: left, right, center, back
+       6: left, right, left back, right back, center, lfe
+       8: left, right, left back, right back, left surround, right surround, center, lfe
+
+       Hardware addresses relative to uaesnd autoconfig board start:
+
+       Read-only hardware information:
+
+       $0080.L uae version (ver.rev.subrev)
+       $0084.W uae sndboard "hardware" version
+       $0086.W uae sndboard "hardware" revision
+       $0088.L preferred frequency
+       $008C.B max number of channels/stream (8, 5.1 fully supported, 7.1 supported but last 2 surround channels are muted)
+       $008D.B active number of channels (selected UAE stereo mode. inactive channels are muted but can be still be used normally.)
+       $008E.B max number of simultaneous audio streams (currently 8)
+
+       $00E0.L allocated streams, bit mask. Hardware level stream allocation feature, use single test and set/clear instruction or
+               disable interrupts before allocating/freeing streams. If stream bit is not set, stream's address range is inactive.
+               byte access to $00E3 is also allowed.
+
+       $00F0.L stream enable bit mask. RW. Can be used to start or stop multiple streams simultaneously.
+       Changing stream mask always clears stream's interrupt status register.
+
+       $0100 stream 1
+
+       $0100-$011f: Current sample set structure. RW.
+       $0140-$015f: Latched sample set structure.
+               Reading from $0140.W/.L makes copy of current contents of $0100-$011f.
+               Writing to $0142.W/$0140.L copies back to $0100-$011f
+       $0180.L Current sample set pointer. RW.
+       $0184.B Reserved
+       $0185.B Reserved
+       $0186.B Reserved
+       $0187.B Interrupt status. 7: set when interrupt active. 0,1,2,3: same as 30.B bit, always set when condition matches,
+               even if 30.B bit is not set. If also 30.B bit is set: bit 7 set and interrupt is activated.
+               Reading clears interrupt. RO.
+       $0188.B Reserved
+       $0189.B Reserved
+       $018A.B Reserved
+       $018B.B Alternative interrupt status. Same as $187.B but reading does not clear interrupt. RO.
+
+       $0200 stream 2
+
+       ...
+
+       $0800 stream 8
+
+       Writing non-zero to sample set pointer ($180) starts audio if not already started and stream enable ($F0) bit is set.
+       Writing zero stops the stream immediately. Also clears automatically when stream ends.
+
+       Long wide registers have special feature when read using word wide reads (68000/10 CPU), when high word is read,
+       low word is copied to internal register. Low word read always comes from register copy.
+       This prevents situation where sound emulation can modify the register between high and low word reads.
+       Long accesses are always guaranteed safe.
+
+       Set structure is copied to emulator side internal address space when set starts.
+       This data can be read and written in real time by accessing $0100-$011f space.
+       Writes are nearly immediate, values are updated during next sample period.
+       (Probably not good idea to change number of channels or bits per sample values..)
+
+       Use hardware current sample set structure to detect current sample address, length and repeat count. 
+
+       Repeat address pointer and length values are (re-)fetched from set structure each time when new repeat starts.
+
+       Next sample set pointer is fetched when current set finishes.
+
+       Reading interrupt status register will also clear interrupts.
+
+       Sample set parameters are validated, any error causes audio to stop immediately and log message will be printed.
+
+       During non-repeat playback sample address increases and sample length decreases. When length becomes zero,
+       repeat count is checked, if it is non-zero, repeat address and repeat length are loaded from memory and start
+       counting (address increases, length decreases). Note that sample address and length won't change anymore.
+       when repeat counter becomes zero (or it was already zero), next sample set address is loaded and started.
+
+*/
+
+static bool uaesnd_rethink(void)
+{
+       bool irq = false;
+       for (int j = 0; j < MAX_DUPLICATE_SOUND_BOARDS; j++) {
+               struct uaesndboard_data *data = &uaesndboard[j];
+               if (data->enabled) {
+                       for (int i = 0; i < MAX_UAE_STREAMS; i++) {
+                               struct uaesndboard_stream *s = &uaesndboard[j].stream[i];
+                               if (s->intreqmask & 0x80) {
+                                       irq = true;
+                                       break;
+                               }
+                       }
+               }
+       }
+       return irq;
+}
+
+static void uaesnd_setfreq(struct uaesndboard_stream *s)
+{
+       if (s->freq < 1000)
+               s->freq = 1000;
+       if (s->freq > 96000)
+               s->freq = 96000;
+       s->event_time = base_event_clock * CYCLE_UNIT / s->freq;
+}
+
+static struct uaesndboard_stream *uaesnd_addr(uaecptr addr)
+{
+       if (addr < 0x100)
+               return NULL;
+       int stream = (addr - 0x100) / 0x100;
+       if (stream >= MAX_UAE_STREAMS)
+               return NULL;
+       if (!(uaesndboard[0].streamallocmask & (1 << stream)))
+               return NULL;
+       return &uaesndboard[0].stream[stream];
+}
+
+static struct uaesndboard_stream *uaesnd_get(uaecptr addr)
+{
+       struct uaesndboard_stream *s = uaesnd_addr(addr);
+       if (!s)
+               return NULL;
+
+       put_long_host(s->io + 0, s->address);
+       put_long_host(s->io + 4, s->len);
+       put_long_host(s->io + 8, s->freq);
+       put_long_host(s->io + 12, s->repeat);
+       put_long_host(s->io + 16, s->replen);
+       put_word_host(s->io + 20, s->repcnt);
+       put_word_host(s->io + 22, s->volume);
+       put_long_host(s->io + 24, s->next);
+       put_byte_host(s->io + 28, s->ch);
+       put_byte_host(s->io + 29, s->bits);
+       put_byte_host(s->io + 30, s->intenamask);
+       put_byte_host(s->io + 31, s->chmode);
+       put_long_host(s->io + 0x80, s->setaddr);
+       put_long_host(s->io + 0x84, s->intreqmask);
+       put_long_host(s->io + 0x88, s->intreqmask);
+
+       return s;
+}
+
+static void uaesndboard_stop(struct uaesndboard_stream *s)
+{
+       struct uaesndboard_data *data = &uaesndboard[0];
+       if (!s->play)
+               return;
+       s->play = 0;
+       data->streammask &= ~(1 << (s - data->stream));
+       audio_enable_stream(false, s->streamid, 0);
+       s->streamid = 0;
+       data->streamcnt--;
+}
+
+static void uaesndboard_start(struct uaesndboard_stream *s)
+{
+       struct uaesndboard_data *data = &uaesndboard[0];
+
+       if (s->play)
+               return;
+
+       if (!(data->streammask & (1 << (s - data->stream))))
+               return;
+
+       data->streamcnt++;
+       s->play = 1;
+       for (int i = 0; i < MAX_UAE_CHANNELS; i++) {
+               s->sample[i] = 0;
+       }
+       uaesnd_setfreq(s);
+       s->streamid = audio_enable_stream(true, -1, MAX_UAE_CHANNELS);
+       if (!s->streamid) {
+               uaesndboard_stop(s);
+       }
+}
+
+static bool uaesnd_validate(struct uaesndboard_stream *s)
+{
+
+       s->framesize = s->bits * s->ch / 8;
+
+       if (s->ch < 1 || s->ch >= MAX_UAE_CHANNELS || s->ch == 3 || s->ch == 5 || s->ch == 7) {
+               write_log(_T("UAESND: unsupported number of channels %d\n"), s->ch);
+               return false;
+       }
+       if (s->bits != 8 && s->bits != 16 && s->bits != 24 && s->bits != 32) {
+               write_log(_T("UAESND: unsupported sample bits %d\n"), s->bits);
+               return false;
+       }
+       if (s->freq < 1000 || s->freq > 96000) {
+               write_log(_T("UAESND: unsupported frequency %d\n"), s->freq);
+               return false;
+       }
+       if (s->volume < 0 || s->volume > 32768) {
+               write_log(_T("UAESND: unsupported volume %d\n"), s->volume);
+               return false;
+       }
+       if (s->next && ((s->next & 1) || !valid_address(s->next, 32))) {
+               write_log(_T("UAESND: invalid next sample set pointer %08x\n"), s->next);
+               return false;
+       }
+       uaecptr saddr = s->address;
+       if (s->len < 0)
+               saddr -= abs(s->len) * s->framesize;
+       if (!valid_address(saddr, abs(s->len) * s->framesize)) {
+               write_log(_T("UAESND: invalid sample pointer range %08x - %08x\n"), saddr, saddr + s->len * s->framesize);
+               return false;
+       }
+       if (s->repcnt) {
+               if (s->replen == 0) {
+                       write_log(_T("UAESND: invalid repeat len %d\n"), s->replen);
+                       return false;
+               }
+               uaecptr repeat = s->repeat;
+               if (s->replen < 0)
+                       repeat -= abs(s->replen) * s->framesize;
+               if (s->repeat && !valid_address(repeat, abs(s->replen) * s->framesize)) {
+                       write_log(_T("UAESND: invalid sample repeat pointer range %08x - %08x\n"), repeat, repeat + s->replen * s->framesize);
+                       return false;
+               }
+       } else {
+               if (s->replen != 0) {
+                       write_log(_T("UAESND: repeat count == 0: repeat length must be also zero.\n"));
+                       return false;
+               }
+               if (s->repeat != 0) {
+                       write_log(_T("UAESND: repeat count == 0: repeat address must be also zero.\n"));
+                       return false;
+               }
+       }
+       uaesnd_setfreq(s);
+       for (int i = s->ch; i < MAX_UAE_CHANNELS; i++) {
+               s->sample[i] = 0;
+       }
+       return true;
+}
+
+static bool uaesnd_next(struct uaesndboard_stream *s, uaecptr addr)
+{
+       if ((addr & 1) || !valid_address(addr, 32)) {
+               write_log(_T("UAESND: invalid sample set pointer %08x\n"), addr);
+               return false;
+       }
+
+       s->setaddr = addr;
+       s->address = get_long(addr);
+       s->len = get_long(addr + 4);
+       s->freq = get_long(addr + 8);
+       s->repeat = get_long(addr + 12);
+       s->replen = get_long(addr + 16);
+       s->repcnt = get_word(addr + 20);
+       s->volume = get_word(addr + 22);
+       s->next = get_long(addr + 24);
+       s->ch = get_byte(addr + 28);
+       s->bits = get_byte(addr + 29);
+       s->intenamask = get_byte(addr + 30);
+       s->chmode = get_byte(addr + 31);
+       s->first = true;
+       s->repeating = false;
+
+       return uaesnd_validate(s);
+}
+
+static void uaesnd_stream_start(struct uaesndboard_stream *s)
+{
+       struct uaesndboard_data *data = &uaesndboard[0];
+       if (!s->play && s->next) {
+               if (data->streammask & (1 << (s - data->stream))) {
+                       if (uaesnd_next(s, s->next)) {
+                               uaesndboard_start(s);
+                       }
+               }
+       } else if (s->play && !s->next) {
+               uaesndboard_stop(s);
+       }
+}
+
+static void uaesnd_irq(struct uaesndboard_stream *s, uae_u8 mask)
+{
+       s->intreqmask |= mask;
+       if ((s->intenamask & mask)) {
+               s->intreqmask |= 0x80;
+               sndboard_rethink();
+       }
+}
+
+static void uaesnd_streammask(uae_u32 m)
+{
+       struct uaesndboard_data *data = &uaesndboard[0];
+       uae_u32 old = data->streammask;
+       data->streammask = m;
+       data->streammask &= (1 << MAX_UAE_STREAMS) - 1;
+       for (int i = 0; i < MAX_UAE_STREAMS; i++) {
+               if ((old ^ data->streammask) & (1 << i)) {
+                       struct uaesndboard_stream *s = &data->stream[i];
+                       s->intreqmask = 0;
+                       if (data->streammask & (1 << i)) {
+                               uaesnd_stream_start(s);
+                       } else {
+                               uaesndboard_stop(s);
+                       }
+               }
+       }
+}
+
+static void audio_state_sndboard_uae(int streamid)
+{
+       struct uaesndboard_data *data = &uaesndboard[0];
+       struct uaesndboard_stream *s = NULL;
+       int highestch = s->ch;
+
+       for (int i = 0; i < MAX_UAE_STREAMS; i++) {
+               if (data->stream[i].streamid == streamid) {
+                       s = &data->stream[i];
+                       break;
+               }
+       }
+       int streamnum = s - data->stream;
+       if (!s)
+               return;
+       if (s->play && (data->streammask & (1 << streamnum))) {
+               int len = s->repeating ? s->replen : s->len;
+               uaecptr addr = s->repeating ? s->repeat : s->address;
+               if (len != 0) {
+                       if (len < 0)
+                               addr -= s->framesize;
+                       for (int i = 0; i < s->ch; i++) {
+                               uae_s16 sample = 0;
+                               if (s->bits == 16) {
+                                       sample = get_word(addr);
+                                       addr += 2;
+                               } else if (s->bits == 8) {
+                                       sample = get_byte(addr);
+                                       sample = (sample << 8) | sample;
+                                       addr += 1;
+                               } else if (s->bits == 24) {
+                                       sample = get_word(addr); // just drop lowest 8 bits for now
+                                       addr += 3;
+                               } else if (s->bits == 32) {
+                                       sample = get_word(addr); // just drop lowest 16 bits for now
+                                       addr += 4;
+                               }
+                               s->sample[i] = sample * ((s->volume + 1) / 2 + (data->volume[i] + 1) / 2) / 32768;
+                       }
+                       if (len < 0)
+                               addr -= s->framesize;
+                       if (s->repeating) {
+                               s->repeat = addr;
+                               if (s->replen > 0)
+                                       s->replen--;
+                               else
+                                       s->replen++;
+                               len = s->replen;
+                       } else {
+                               s->address = addr;
+                               if (s->len > 0)
+                                       s->len--;
+                               else
+                                       s->len++;
+                               len = s->len;
+                       }
+                       uaesnd_irq(s, 8);
+               }
+               if (s->first) {
+                       uaesnd_irq(s, 1);
+                       s->first = false;
+               }
+               if (len == 0) {
+                       if (s->repcnt) {
+                               if (s->repcnt != 0xffff)
+                                       s->repcnt--;
+                               s->repeat = get_long(s->setaddr + 12);
+                               s->replen = get_long(s->setaddr + 16);
+                               s->repeating = true;
+                               uaesnd_irq(s, 4);
+                       } else {
+                               s->next = get_long(s->setaddr + 24);
+                               if (s->next) {
+                                       if (uaesnd_next(s, s->next)) {
+                                               uaesnd_irq(s, 2);
+                                       } else {
+                                               uaesndboard_stop(s);
+                                       }
+                               } else {
+                                       uaesndboard_stop(s);
+                               }
+                       }
+               }
+       }
+       if (s->ch == 1 && s->chmode) {
+               int smp = s->sample[0];
+               for (int i = 0; i < MAX_UAE_CHANNELS; i++) {
+                       if ((1 << i) & s->chmode) {
+                               s->sample[i] = smp;
+                               if (i > highestch)
+                                       highestch = i;
+                       }
+               }
+       } else if (s->ch == 4 && s->chmode == 1) {
+               s->sample[2] = s->sample[4];
+               s->sample[3] = s->sample[5];
+       } else if (s->ch == 6 && s->chmode == 1) {
+               int c = s->sample[2];
+               int lfe = s->sample[3];
+               s->sample[2] = s->sample[4];
+               s->sample[3] = s->sample[5];
+               s->sample[4] = c;
+               s->sample[5] = lfe;
+       } else if (s->ch == 8 && s->chmode == 1) {
+               int c = s->sample[2];
+               int lfe = s->sample[3];
+               s->sample[2] = s->sample[4];
+               s->sample[3] = s->sample[5];
+               s->sample[4] = s->sample[6];
+               s->sample[5] = s->sample[7];
+               s->sample[6] = c;
+               s->sample[7] = lfe;
+       }
+       audio_state_stream_state(s->streamid, s->sample, highestch, s->event_time);
+}
+
+static void uaesnd_latch(struct uaesndboard_stream *s)
+{
+       memcpy(s->io + 0x40, s->io + 0x00, 0x40);
+}
+static void uaesnd_latch_back(struct uaesndboard_stream *s)
+{
+       memcpy(s->io + 0x00, s->io + 0x40, 0x40);
+       if (!uaesnd_validate(s)) {
+               uaesndboard_stop(s);
+       } else if (!s->play) {
+               uaesndboard_start(s);
+       }
+}
+
+static void uaesnd_put(struct uaesndboard_stream *s, int reg)
+{
+       if (reg == 0x80) { // set pointer write?
+               uaecptr setaddr = get_long_host(s->io + 0x80);
+               s->next = setaddr;
+               uaesnd_stream_start(s);
+       }
+}
+
+static uae_u32 REGPARAM2 uaesndboard_bget(uaecptr addr)
+{
+       struct uaesndboard_data *data = &uaesndboard[0];
+       addr &= 65535;
+       if (addr < 0x80) {
+               return data->acmemory[addr];
+       } else if (data->configured) {
+               struct uaesndboard_stream *s = uaesnd_get(addr);
+               if (s) {
+                       int reg = addr & 255;
+                       if (reg == 0x84)
+                               s->intreqmask = 0;
+                       return get_byte_host(s->io + reg);
+               } else if (addr >= 0x80 && addr < 0x100) {
+                       return get_byte_host(data->info + (addr & 0x7f));
+               } else if (addr == 0xe3) {
+                       return data->streamallocmask;
+               }
+       }
+       return 0;
+}
+static uae_u32 REGPARAM2 uaesndboard_wget(uaecptr addr)
+{
+       struct uaesndboard_data *data = &uaesndboard[0];
+       addr &= 65535;
+       if (addr < 0x80) {
+               return (uaesndboard_bget(addr) << 8) | uaesndboard_bget(addr + 1);
+       } else if (data->configured) {
+               struct uaesndboard_stream *s = uaesnd_get(addr);
+               if (s) {
+                       int reg = addr & 255;
+                       int reg4 = reg / 4;
+                       if (reg4 <= 4 || reg4 == 6) {
+                               if (!(reg & 2)) {
+                                       s->wordlatch = get_word_host(s->io + ((reg + 2) & 255));
+                               } else {
+                                       return s->wordlatch;
+                               }
+                       }
+                       if (reg == 0x40) {
+                               uaesnd_latch(s);
+                       } else if (reg == 0x84 || reg == 0x85 || reg == 0x86 || reg == 0x87) {
+                               s->intreqmask = 0;
+                       }
+                       return get_word_host(s->io + reg);
+               } else if (addr >= 0x80 && addr < 0x100 - 1) {
+                       return get_word_host(data->info + (addr & 0x7f));
+               } else if (addr == 0xf0) {
+                       return data->streammask >> 16;
+               } else if (addr == 0xf2) {
+                       return data->streammask;
+               }
+       }
+       return 0;
+}
+static uae_u32 REGPARAM2 uaesndboard_lget(uaecptr addr)
+{
+       struct uaesndboard_data *data = &uaesndboard[0];
+       addr &= 65535;
+       if (addr < 0x80) {
+               return (uaesndboard_wget(addr) << 16) | uaesndboard_wget(addr + 2);
+       } else if (data->configured) {
+               struct uaesndboard_stream *s = uaesnd_get(addr);
+               if (s) {
+                       int reg = addr & 255;
+                       if (reg == 0x40)
+                               uaesnd_latch(s);
+                       if (reg == 0x84 || reg == 0x85 || reg == 0x86 || reg == 0x87)
+                               s->intreqmask = 0;
+                       return get_long_host(s->io + reg);
+               } else if (addr >= 0x80 && addr < 0xf0 - 3) {
+                       return get_long_host(data->info + (addr & 0x7f));
+               } else if (addr == 0xe0) {
+                       return data->streamallocmask;
+               } else if (addr == 0xf0) {
+                       return data->streammask;
+               }
+       }
+       return 0;
+}
+static void REGPARAM2 uaesndboard_bput(uaecptr addr, uae_u32 b)
+{
+       struct uaesndboard_data *data = &uaesndboard[0];
+       addr &= 65535;
+       if (!data->configured) {
+               switch (addr) {
+                       case 0x48:
+                       if (!data->z3) {
+                               map_banks_z2(&uaesndboard_bank, expamem_board_pointer >> 16, 65536 >> 16);
+                               data->configured = 1;
+                               expamem_next(&uaesndboard_bank, NULL);
+                       }
+                       break;
+                       case 0x4c:
+                       data->configured = -1;
+                       expamem_shutup(&uaesndboard_bank);
+                       break;
+               }
+               return;
+       } else {
+               struct uaesndboard_stream *s = uaesnd_addr(addr);
+               if (s) {
+                       int reg = addr & 255;
+                       put_byte_host(s->io + reg, b);
+                       uaesnd_put(s, reg);
+               } else if (addr == 0xe3) {
+                       uae_u32 v = data->streamallocmask;
+                       v &= 0x000000ff;
+                       v |= b;
+                       uaesnd_streammask(data->streammask & v);
+                       data->streamallocmask = v;
+               }
+       }
+}
+static void REGPARAM2 uaesndboard_wput(uaecptr addr, uae_u32 b)
+{
+       struct uaesndboard_data *data = &uaesndboard[0];
+       addr &= 65535;
+       if (!data->configured) {
+               switch (addr) {
+                       case 0x44:
+                       if (data->z3) {
+                               map_banks_z3(&uaesndboard_bank, expamem_board_pointer >> 16, (16 * 1024 * 1024) >> 16);
+                               data->configured = 1;
+                               expamem_next(&uaesndboard_bank, NULL);
+                       }
+                       break;
+               }
+               return;
+       } else {
+               struct uaesndboard_stream *s = uaesnd_addr(addr);
+               if (s) {
+                       int reg = addr & 255;
+                       put_word_host(s->io + reg, b);
+                       uaesnd_put(s, reg);
+                       if (reg == 0x42) {
+                               uaesnd_latch_back(s);
+                       }
+               } else if (addr == 0xf2) {
+                       uaesnd_streammask(b);
+               }
+       }
+}
+static void REGPARAM2 uaesndboard_lput(uaecptr addr, uae_u32 b)
+{
+       struct uaesndboard_data *data = &uaesndboard[0];
+       addr &= 65535;
+       if (data->configured) {
+               struct uaesndboard_stream *s = uaesnd_addr(addr);
+               if (s) {
+                       int reg = addr & 255;
+                       put_long_host(s->io + reg, b);
+                       uaesnd_put(s, reg);
+                       if (reg == 0x40) {
+                               uaesnd_latch_back(s);
+                       }
+               } else if (addr == 0xe0) {
+                       uaesnd_streammask(data->streammask & b);
+                       data->streamallocmask = b;
+               } else if (addr == 0xf0) {
+                       uaesnd_streammask(b);
+               }
+       }
+}
+
+static addrbank uaesndboard_bank = {
+       uaesndboard_lget, uaesndboard_wget, uaesndboard_bget,
+       uaesndboard_lput, uaesndboard_wput, uaesndboard_bput,
+       default_xlate, default_check, NULL, NULL, _T("uaesnd"),
+       dummy_lgeti, dummy_wgeti,
+       ABFLAG_IO, S_READ, S_WRITE
+};
+
+static void ew(uae_u8 *acmemory, int addr, uae_u32 value)
+{
+       addr &= 0xffff;
+       if (addr == 00 || addr == 02 || addr == 0x40 || addr == 0x42) {
+               acmemory[addr] = (value & 0xf0);
+               acmemory[addr + 2] = (value & 0x0f) << 4;
+       } else {
+               acmemory[addr] = ~(value & 0xf0);
+               acmemory[addr + 2] = ~((value & 0x0f) << 4);
+       }
+}
+
+bool uaesndboard_init (struct autoconfig_info *aci, int z)
+{
+       struct uaesndboard_data *data = &uaesndboard[0];
+
+       data->configured = 0;
+       data->enabled = true;
+       data->z3 = z == 3;
+       memset(data->acmemory, 0xff, sizeof data->acmemory);
+       const struct expansionromtype *ert = get_device_expansion_rom(z == 3 ? ROMTYPE_UAESNDZ3 : ROMTYPE_UAESNDZ2);
+       if (!ert)
+               return false;
+       data->streammask = 0;
+       data->volume[0] = 32768;
+       data->volume[1] = 32768;
+       put_long_host(data->info + 0, (UAEMAJOR << 16) | (UAEMINOR << 8) | (UAESUBREV));
+       put_long_host(data->info + 4, (1 << 16) | (0));
+       put_long_host(data->info + 8, currprefs.sound_freq);
+       put_byte_host(data->info + 12, MAX_UAE_CHANNELS);
+       put_byte_host(data->info + 13, get_audio_nativechannels(currprefs.sound_stereo));
+       put_byte_host(data->info + 14, MAX_UAE_STREAMS);
+
+       for (int i = 0; i < 16; i++) {
+               uae_u8 b = ert->autoconfig[i];
+               ew(data->acmemory, i * 4, b);
+       }
+
+       memcpy(aci->autoconfig_raw, data->acmemory, sizeof data->acmemory);
+       aci->addrbank = &uaesndboard_bank;
+       return true;
+}
+
+bool uaesndboard_init_z2(struct autoconfig_info *aci)
+{
+       return uaesndboard_init(aci, 2);
+}
+bool uaesndboard_init_z3(struct autoconfig_info *aci)
+{
+       return uaesndboard_init(aci, 3);
+}
+
+void uaesndboard_free(void)
+{
+       for (int j = 0; j < MAX_DUPLICATE_SOUND_BOARDS; j++) {
+               struct uaesndboard_data *data = &uaesndboard[j];
+               data->enabled = false;
+       }
+       sndboard_rethink();
+}
+
+void uaesndboard_reset(void)
+{
+       for (int j = 0; j < MAX_DUPLICATE_SOUND_BOARDS; j++) {
+               struct uaesndboard_data *data = &uaesndboard[j];
+               if (data->enabled) {
+                       for (int i = 0; i < MAX_UAE_STREAMS; i++) {
+                               if (data->stream[i].streamid) {
+                                       audio_enable_stream(false, data->stream[i].streamid, 0);
+                                       memset(&data->stream[i], 0, sizeof(struct uaesndboard_stream));
+                               }
+                       }
+               }
+               data->streammask = 0;
+       }
+}
+
+
+// TOCCATA
+
 #define DEBUG_TOCCATA 0
 
 #define BOARD_MASK 65535
@@ -37,9 +817,8 @@ static double base_event_clock;
 #define FIFO_SIZE 1024
 #define FIFO_SIZE_HALF (FIFO_SIZE / 2)
 
-static const uae_u8 toccata_autoconfig[16] = { 0xc1, 12, 0, 0, 18260 >> 8, 18260 & 255 };
-
 struct toccata_data {
+       bool enabled;
        uae_u8 acmemory[128];
        int configured;
        uae_u8 ad1848_index;
@@ -58,6 +837,7 @@ struct toccata_data {
        int data_in_record_fifo;
        uae_u8 record_fifo[FIFO_SIZE];
 
+       int streamid;
        int ch_sample[2];
 
        int fifo_half;
@@ -68,9 +848,11 @@ struct toccata_data {
        int event_time, record_event_time;
        int record_event_counter;
        int bytespersample;
+
+       struct romconfig *rc;
 };
 
-static struct toccata_data toccata;
+static struct toccata_data toccata[MAX_DUPLICATE_SOUND_BOARDS];
 
 extern addrbank toccata_bank;
 
@@ -94,7 +876,7 @@ void update_sndboard_sound (double clk)
 
 static void process_fifo(void)
 {
-       struct toccata_data *data = &toccata;
+       struct toccata_data *data = &toccata[0];
        int prev_data_in_fifo = data->data_in_fifo;
        if (data->data_in_fifo >= data->bytespersample) {
                uae_s16 v;
@@ -129,10 +911,12 @@ static void process_fifo(void)
                data->fifo_half |= STATUS_FIFO_PLAY;
 }
 
-static void audio_state_sndboard_toccata(int ch)
+static void audio_state_sndboard_toccata(int streamid)
 {
-       struct toccata_data *data = &toccata;
-       if ((data->toccata_active & STATUS_FIFO_PLAY) && ch == 0) {
+       struct toccata_data *data = &toccata[0];
+       if (data->streamid != streamid)
+               return;
+       if ((data->toccata_active & STATUS_FIFO_PLAY)) {
                // get all bytes at once to prevent fifo going out of sync
                // if fifo has for example 3 bytes remaining but we need 4.
                process_fifo();
@@ -152,7 +936,7 @@ static void audio_state_sndboard_toccata(int ch)
 #endif
                }
        }
-       audio_state_sndboard_state(ch, data->ch_sample[ch], data->event_time);
+       audio_state_stream_state(data->streamid, data->ch_sample, 2, data->event_time);
 }
 
 static int get_volume(uae_u8 v)
@@ -179,14 +963,14 @@ static int get_volume_in(uae_u8 v)
 
 static void calculate_volume_toccata(void)
 {
-       struct toccata_data *data = &toccata;
+       struct toccata_data *data = &toccata[0];
        data->left_volume = (100 - currprefs.sound_volume_board) * 32768 / 100;
        data->right_volume = (100 - currprefs.sound_volume_board) * 32768 / 100;
 
        data->left_volume = get_volume(data->ad1848_regs[6]) * data->left_volume / 32768;
        data->right_volume = get_volume(data->ad1848_regs[7]) * data->right_volume / 32768;
 
-       if (currprefs.sound_toccata_mixer) {
+       if (data->rc->device_settings & 1) {
                sound_paula_volume[0] = get_volume_in(data->ad1848_regs[4]);
                sound_paula_volume[1] = get_volume_in(data->ad1848_regs[5]);
 
@@ -216,7 +1000,7 @@ static const int freq_dividers[] = {
 
 static void codec_setup(void)
 {
-       struct toccata_data *data = &toccata;
+       struct toccata_data *data = &toccata[0];
        uae_u8 c = data->ad1848_regs[8];
 
        data->channels = (c & 0x10) ? 2 : 1;
@@ -236,7 +1020,7 @@ static uae_u8 *capture_buffer;
 
 static void codec_start(void)
 {
-       struct toccata_data *data = &toccata;
+       struct toccata_data *data = &toccata[0];
        data->toccata_active  = (data->ad1848_regs[9] & 1) ? STATUS_FIFO_PLAY : 0;
        data->toccata_active |= (data->ad1848_regs[9] & 2) ? STATUS_FIFO_RECORD : 0;
 
@@ -247,7 +1031,7 @@ static void codec_start(void)
        data->record_event_counter = 0;
 
        if (data->toccata_active & STATUS_FIFO_PLAY) {
-               audio_enable_sndboard(true);
+               data->streamid = audio_enable_stream(true, -1, 2);
        }
        if (data->toccata_active & STATUS_FIFO_RECORD) {
                capture_buffer = xcalloc(uae_u8, capture_buffer_size);
@@ -257,26 +1041,37 @@ static void codec_start(void)
 
 static void codec_stop(void)
 {
-       struct toccata_data *data = &toccata;
+       struct toccata_data *data = &toccata[0];
        write_log(_T("TOCCATA stop\n"));
        data->toccata_active = 0;
        sndboard_free_capture();
-       audio_enable_sndboard(false);
+       audio_enable_stream(false, data->streamid, 0);
+       data->streamid = 0;
        xfree(capture_buffer);
        capture_buffer = NULL;
 }
 
 void sndboard_rethink(void)
 {
-       struct toccata_data *data = &toccata;
-       atomic_and(&uae_int_requested, ~0x200);
-       if (data->toccata_irq)
+       bool irq = false;
+       if (toccata[0].enabled) {
+               struct toccata_data *data = &toccata[0];
+               irq = data->toccata_irq != 0;
+       }
+       if (uaesndboard[0].enabled) {
+               irq |= uaesnd_rethink();
+       }
+       if (irq) {
                atomic_or(&uae_int_requested, 0x200);
+               set_special_exter(SPCFLAG_UAEINT);
+       } else {
+               atomic_and(&uae_int_requested, ~0x200);
+       }
 }
 
 static void sndboard_process_capture(void)
 {
-       struct toccata_data *data = &toccata;
+       struct toccata_data *data = &toccata[0];
        int frames;
        uae_u8 *buffer = sndboard_get_buffer(&frames);
        if (buffer && frames) {
@@ -298,7 +1093,7 @@ static void sndboard_process_capture(void)
 
 void sndboard_hsync(void)
 {
-       struct toccata_data *data = &toccata;
+       struct toccata_data *data = &toccata[0];
        static int capcnt;
 
        if (data->autocalibration > 0)
@@ -365,7 +1160,7 @@ void sndboard_hsync(void)
 
                if (data->data_in_record_fifo > FIFO_SIZE_HALF && oldfifo <= FIFO_SIZE_HALF) {
                        data->fifo_half |= STATUS_FIFO_RECORD;
-                       audio_state_sndboard(-1);
+                       //audio_state_sndboard(-1, -1);
                }
                data->record_event_counter -= oldbytes * data->record_event_time;
        }
@@ -373,7 +1168,7 @@ void sndboard_hsync(void)
 
 static void sndboard_vsync_toccata(void)
 {
-       struct toccata_data *data = &toccata;
+       struct toccata_data *data = &toccata[0];
        if (data->toccata_active) {
                calculate_volume_toccata();
                audio_activate();
@@ -382,7 +1177,7 @@ static void sndboard_vsync_toccata(void)
 
 static void toccata_put(uaecptr addr, uae_u8 v)
 {
-       struct toccata_data *data = &toccata;
+       struct toccata_data *data = &toccata[0];
        int idx = data->ad1848_index & 15;
 
 #if DEBUG_TOCCATA > 2
@@ -462,7 +1257,7 @@ static void toccata_put(uaecptr addr, uae_u8 v)
 
 static uae_u8 toccata_get(uaecptr addr)
 {
-       struct toccata_data *data = &toccata;
+       struct toccata_data *data = &toccata[0];
        int idx = data->ad1848_index & 15;
        uae_u8 v = 0;
 
@@ -523,14 +1318,14 @@ static uae_u8 toccata_get(uaecptr addr)
 
 static void REGPARAM2 toccata_bput(uaecptr addr, uae_u32 b)
 {
-       struct toccata_data *data = &toccata;
+       struct toccata_data *data = &toccata[0];
        b &= 0xff;
        addr &= BOARD_MASK;
        if (!data->configured) {
                switch (addr)
                {
                        case 0x48:
-                       map_banks_z2(&toccata_bank, expamem_z2_pointer >> 16, BOARD_SIZE >> 16);
+                       map_banks_z2(&toccata_bank, expamem_board_pointer >> 16, BOARD_SIZE >> 16);
                        data->configured = 1;
                        expamem_next(&toccata_bank, NULL);
                        break;
@@ -561,7 +1356,7 @@ static void REGPARAM2 toccata_lput(uaecptr addr, uae_u32 b)
 
 static uae_u32 REGPARAM2 toccata_bget(uaecptr addr)
 {
-       struct toccata_data *data = &toccata;
+       struct toccata_data *data = &toccata[0];
        uae_u8 v = 0;
        addr &= BOARD_MASK;
        if (!data->configured) {
@@ -593,26 +1388,25 @@ static uae_u32 REGPARAM2 toccata_lget(uaecptr addr)
 addrbank toccata_bank = {
        toccata_lget, toccata_wget, toccata_bget,
        toccata_lput, toccata_wput, toccata_bput,
-       default_xlate, default_check, NULL, NULL, _T("Toccata"),
+       default_xlate, default_check, NULL, _T("*"), _T("Toccata"),
        dummy_lgeti, dummy_wgeti,
        ABFLAG_IO, S_READ, S_WRITE
 };
 
-static void ew (uae_u8 *acmemory, int addr, uae_u32 value)
+bool sndboard_init(struct autoconfig_info *aci)
 {
-       addr &= 0xffff;
-       if (addr == 00 || addr == 02 || addr == 0x40 || addr == 0x42) {
-               acmemory[addr] = (value & 0xf0);
-               acmemory[addr + 2] = (value & 0x0f) << 4;
-       } else {
-               acmemory[addr] = ~(value & 0xf0);
-               acmemory[addr + 2] = ~((value & 0x0f) << 4);
+       const struct expansionromtype *ert = get_device_expansion_rom(ROMTYPE_TOCCATA);
+       if (!ert)
+               return false;
+
+       aci->addrbank = &toccata_bank;
+
+       if (!aci->doinit) {
+               aci->autoconfigp = ert->autoconfig;
+               return true;
        }
-}
 
-addrbank *sndboard_init(int devnum)
-{
-       struct toccata_data *data = &toccata;
+       struct toccata_data *data = &toccata[0];
        memset(data->ad1848_regs, 0, sizeof data->ad1848_regs);
        data->ad1848_regs[2] = 0x80;
        data->ad1848_regs[3] = 0x80;
@@ -623,30 +1417,38 @@ addrbank *sndboard_init(int devnum)
        data->ad1848_regs[9] = 0x10;
        data->ad1848_status = 0xcc;
        data->ad1848_index = 0x40;
-       calculate_volume_toccata();
 
        data->configured = 0;
+       data->streamid = 0;
        memset(data->acmemory, 0xff, sizeof data->acmemory);
+       data->rc = aci->rc;
+       data->enabled = true;
        for (int i = 0; i < 16; i++) {
-               uae_u8 b = toccata_autoconfig[i];
+               uae_u8 b = ert->autoconfig[i];
                ew(data->acmemory, i * 4, b);
        }
-       return &toccata_bank;
+       mapped_malloc(&toccata_bank);
+       calculate_volume_toccata();
+       return true;
 }
 
 void sndboard_free(void)
 {
-       struct toccata_data *data = &toccata;
+       struct toccata_data *data = &toccata[0];
+       data->enabled = false;
        data->toccata_irq = 0;
-       atomic_and(&uae_int_requested, ~0x200);
+       data->rc = NULL;
+       sndboard_rethink();
+       mapped_free(&toccata_bank);
 }
 
 void sndboard_reset(void)
 {
-       struct toccata_data *data = &toccata;
+       struct toccata_data *data = &toccata[0];
        data->ch_sample[0] = 0;
        data->ch_sample[1] = 0;
-       audio_enable_sndboard(false);
+       audio_enable_stream(false, data->streamid, 0);
+       data->streamid = 0;
 }
 
 struct fm801_data
@@ -666,6 +1468,7 @@ struct fm801_data
        int left_volume, right_volume;
        int ch_sample[2];
        int event_time;
+       int streamid;
 };
 static struct fm801_data fm801;
 static bool fm801_active;
@@ -688,7 +1491,8 @@ static void fm801_stop(struct fm801_data *data)
 {
        write_log(_T("FM801 STOP\n"));
        data->play_on = false;
-       audio_enable_sndboard(false);
+       audio_enable_stream(false, data->streamid, 0);
+       data->streamid = 0;
 }
 
 static void fm801_swap_buffers(struct fm801_data *data)
@@ -710,37 +1514,29 @@ static void fm801_interrupt(struct fm801_data *data)
        }
 }
 
-static void audio_state_sndboard_fm801(int ch)
+static void audio_state_sndboard_fm801(int streamid)
 {
        struct fm801_data *data = &fm801;
 
-       if (data->play_on && ch == 0) {
+       if (data->streamid != streamid)
+               return;
+       if (data->play_on) {
                uae_u8 sample[2 * 6] = { 0 };
-               uae_s16 l, r;
                pci_read_dma(data->pcibs, data->play_dma2[data->dmach], sample, data->bytesperframe);
-               if (data->bits == 8) {
-                       if (data->ch == 1) {
-                               sample[1] = sample[0];
-                               sample[2] = sample[0];
-                               sample[3] = sample[0];
-                       } else {
-                               sample[2] = sample[1];
-                               sample[3] = sample[1];
-                               sample[1] = sample[0];
-                       }
-               } else {
-                       if (data->ch == 1) {
-                               sample[2] = sample[0];
-                               sample[3] = sample[1];
-                       }
+               for (int i = 0; i < data->ch; i++) {
+                       int smp, vol;
+                       if (data->bits == 8)
+                               smp = (sample[i] << 8) | (sample[i]);
+                       else
+                               smp = (sample[i * 2 + 1] << 8) | sample[i *2 + 0];
+                       if (i == 0 || i == 4)
+                               vol = data->left_volume;
+                       else if (i == 1 || i == 5)
+                               vol = data->right_volume;
+                       else
+                               vol = (data->left_volume + data->right_volume) / 2;
+                       data->ch_sample[i] = smp * vol / 32768;
                }
-               l = (sample[1] << 8) | sample[0];
-               r = (sample[3] << 8) | sample[2];
-               data->ch_sample[0] = l;
-               data->ch_sample[1] = r;
-               data->ch_sample[0] = data->ch_sample[0] * data->left_volume / 32768;
-               data->ch_sample[1] = data->ch_sample[1] * data->right_volume / 32768;
-
                data->play_len2 -= data->bytesperframe;
                data->play_dma2[data->dmach] += data->bytesperframe;
                if (data->play_len2 == 0xffff) {
@@ -749,7 +1545,7 @@ static void audio_state_sndboard_fm801(int ch)
                        fm801_interrupt(data);
                }
        }
-       audio_state_sndboard_state(ch, data->ch_sample[ch], data->event_time);
+       audio_state_stream_state(data->streamid, data->ch_sample, data->ch, data->event_time);
 }
 
 static void fm801_hsync_handler(struct pci_board_state *pcibs)
@@ -791,13 +1587,14 @@ static void fm801_play(struct fm801_data *data)
 
        write_log(_T("FM801 PLAY: freq=%d ch=%d bits=%d\n"), data->freq, data->ch, data->bits);
 
-       audio_enable_sndboard(true);
+       data->streamid = audio_enable_stream(true, -1, data->ch);
 }
 
 static void fm801_pause(struct fm801_data *data, bool pause)
 {
        write_log(_T("FM801 PAUSED %d\n"), pause);
 }
+
 static void fm801_control(struct fm801_data *data, uae_u16 control)
 {
        uae_u16 old_control = data->play_control;
@@ -892,9 +1689,9 @@ static uae_u32 REGPARAM2 fm801_lget(struct pci_board_state *pcibs, uaecptr addr)
                case 0x0c:
                v = data->play_dma2[data->dmach];
                break;
+               break;
                case 0x10:
                v = data->play_dma2[data->dmach];
-               break;
        }
        return v;
 }
@@ -1085,7 +1882,7 @@ void AUD_set_active_out(SWVoiceOut *sw, int on)
        sw->samplebuf_index = 0;
        sw->samplebuf_total = 0;
        calculate_volume_qemu();
-       audio_enable_sndboard(sw->active);
+       sw->streamid = audio_enable_stream(sw->active, -1, 2);
 }
 void AUD_set_active_in(SWVoiceIn *sw, int on)
 {
@@ -1097,7 +1894,8 @@ int  AUD_is_active_in(SWVoiceIn *sw)
 void AUD_close_out(QEMUSoundCard *card, SWVoiceOut *sw)
 {
        qemu_voice_out = NULL;
-       audio_enable_sndboard(false);
+       audio_enable_stream(false, sw->streamid, 0);
+       sw->streamid = 0;
        xfree(sw);
 }
 SWVoiceIn *AUD_open_in(
@@ -1145,13 +1943,15 @@ SWVoiceOut *AUD_open_out(
        return out;
 }
 
-static void audio_state_sndboard_qemu(int ch)
+static void audio_state_sndboard_qemu(int streamid)
 {
        SWVoiceOut *out = qemu_voice_out;
 
        if (!out)
                return;
-       if (out->active && ch == 0) {
+       if (streamid != out->streamid)
+               return;
+       if (out->active) {
                uae_s16 l, r;
                if (out->samplebuf_index >= out->samplebuf_total) {
                        int maxsize = sizeof(out->samplebuf);
@@ -1186,29 +1986,29 @@ static void audio_state_sndboard_qemu(int ch)
                out->ch_sample[1] = out->ch_sample[1] * out->right_volume / 32768;
                out->samplebuf_index += out->bytesperframe;
        }
-       audio_state_sndboard_state(ch, out->ch_sample[ch], out->event_time);
+       audio_state_stream_state(out->streamid, out->ch_sample, out->ch, out->event_time);
 }
 
-
 static void sndboard_vsync_qemu(void)
 {
        audio_activate();
 }
 
-
-void audio_state_sndboard(int ch)
+void audio_state_stream(int streamid)
 {
-       if (toccata.toccata_active)
-               audio_state_sndboard_toccata(ch);
+       if (toccata[0].toccata_active)
+               audio_state_sndboard_toccata(streamid);
        if (fm801_active)
-               audio_state_sndboard_fm801(ch);
+               audio_state_sndboard_fm801(streamid);
        if (qemu_voice_out && qemu_voice_out->active)
-               audio_state_sndboard_qemu(ch);
+               audio_state_sndboard_qemu(streamid);
+       if (uaesnd_active)
+               audio_state_sndboard_uae(streamid);
 }
 
 void sndboard_vsync(void)
 {
-       if (toccata.toccata_active)
+       if (toccata[0].toccata_active)
                sndboard_vsync_toccata();
        if (fm801_active)
                sndboard_vsync_fm801();
@@ -1218,7 +2018,7 @@ void sndboard_vsync(void)
 
 void sndboard_ext_volume(void)
 {
-       if (toccata.toccata_active)
+       if (toccata[0].toccata_active)
                calculate_volume_toccata();
        if (fm801_active)
                calculate_volume_fm801();
index 4f0c6c7012c6d96e39458b928b6afeb1285e49fc..0cb4e07b4f3662b8189f351e386c081378ac9a1c 100755 (executable)
@@ -954,7 +954,7 @@ static void REGPARAM2 sm_bput(uaecptr addr, uae_u32 b)
        if (!sm_configured) {
                switch (addr) {
                        case 0x48:
-                       map_banks_z2(&specialmonitors_bank, expamem_z2_pointer >> 16, 65536 >> 16);
+                       map_banks_z2(&specialmonitors_bank, expamem_board_pointer >> 16, 65536 >> 16);
                        sm_configured = 1;
                        expamem_next(&specialmonitors_bank, NULL);
                        break;
@@ -1065,7 +1065,7 @@ static void ew(int addr, uae_u32 value)
 
 static const uae_u8 firecracker24_autoconfig[16] = { 0xc1, 0, 0, 0, 2104 >> 8, 2104 & 255 };
 
-addrbank *specialmonitor_autoconfig_init(int devnum)
+bool specialmonitor_autoconfig_init(struct autoconfig_info *aci)
 {
        sm_configured = 0;
        memset(sm_acmemory, 0xff, sizeof sm_acmemory);
@@ -1073,7 +1073,10 @@ addrbank *specialmonitor_autoconfig_init(int devnum)
                uae_u8 b = firecracker24_autoconfig[i];
                ew(i * 4, b);
        }
-       return &specialmonitors_bank;
+       aci->addrbank = &specialmonitors_bank;
+       aci->autoconfigp = firecracker24_autoconfig;
+       aci->label = _T("FireCracker 24");
+       return true;
 }
 
 static bool do_firecracker24(struct vidbuffer *src, struct vidbuffer *dst)
index ec953d87a747a602a29d60711a3e4e8d8a7fd9a0..9e96917df508967a913d280fa3cb78d377f3355e 100644 (file)
@@ -210,7 +210,7 @@ void draw_status_line_single (uae_u8 *buf, int bpp, int y, int totalwidth, uae_u
                                num4 = num1 == 0 ? 13 : -1;
                                am = 3;
                        }
-               } else if (led == LED_SND) {
+               } else if (led == LED_SND && gui_data.sndbuf_avail) {
                        int snd = abs(gui_data.sndbuf + 5) / 10;
                        if (snd > 99)
                                snd = 99;
index f232490f7fefd34155150b456bd9bbfa5cdcf9d6..8bcbc198acd75afc51354fa5f1a7c669843b4812 100644 (file)
@@ -247,7 +247,7 @@ void tabletlib_install (void)
        dw (0x000E); /* LIB_FLAGS */
        dw (0x0600); /* LIBF_SUMUSED | LIBF_CHANGED */
        dw (0xD000); /* INITWORD */
-       dw (0x0027); /* LIB_VERSION */
+       dw (0x0014); /* LIB_VERSION */
        dw (UAEMAJOR);
        dw (0xD000); /* INITWORD */
        dw (0x0016); /* LIB_REVISION */
index 3ff8f5aeeae1cbf6a00f77e8e2415e5bc02c7798..99c23e8b8ee2780391bb813015547cc3e8547d13 100644 (file)
@@ -174,7 +174,7 @@ static uae_u32 REGPARAM2 emulib_ChgFMemSize(TrapContext *ctx, uae_u32 memsize)
                        write_log (_T("Unsupported fastmem size!\n"));
        }
        trap_set_dreg(ctx, 0, 0);
-       changed_prefs.fastmem_size = memsize;
+       changed_prefs.fastmem[0].size = memsize;
        uae_reset (1, 1);
        return 0;
 }
@@ -217,7 +217,7 @@ static uae_u32 emulib_GetUaeConfig(TrapContext *ctx, uaecptr place)
        trap_put_long(ctx, place, version);
        trap_put_long(ctx, place + 4, chipmem_bank.allocated);
        trap_put_long(ctx, place + 8, bogomem_bank.allocated);
-       trap_put_long(ctx, place + 12, fastmem_bank.allocated);
+       trap_put_long(ctx, place + 12, fastmem_bank[0].allocated);
        trap_put_long(ctx, place + 16, currprefs.gfx_framerate);
        trap_put_long(ctx, place + 20, currprefs.produce_sound);
        trap_put_long(ctx, place + 24, currprefs.jports[0].id | (currprefs.jports[1].id << 8));
diff --git a/vm.cpp b/vm.cpp
index c78f33debb686d4ba0f2b80907661b3b5a50bc23..a01feba93ddc4c4e902400242e3bd6100f805fb0 100644 (file)
--- a/vm.cpp
+++ b/vm.cpp
@@ -10,6 +10,7 @@
 #include "sysdeps.h"
 #include "uae/vm.h"
 #include "uae/log.h"
+#include "options.h"
 #include "memory.h"
 #ifdef _WIN32
 
diff --git a/x86.cpp b/x86.cpp
index 1acd447f8044bf39021cb6723db7e0dcedf3ec4a..42ce3188a7aac7d7baad16a66ec11ee565064a3c 100644 (file)
--- a/x86.cpp
+++ b/x86.cpp
@@ -114,6 +114,7 @@ int x86_cmos_bank;
 int x86_xrom_start[2];
 int x86_xrom_end[2];
 int x86_vga_mode;
+int x86_vga_board;
 
 struct x86_bridge
 {
@@ -149,6 +150,7 @@ struct x86_bridge
        float dosbox_vpos_tick;
        float dosbox_tick_vpos_cnt;
        struct romconfig *rc;
+       int vgaboard;
 };
 static int x86_found;
 
@@ -171,7 +173,7 @@ static int x86_found;
 #define IO_KEYBOARD_REGISTER_A2000 0x1fff
 #define IO_A2386_CONFIG 0x1f9f
 
-#define ISVGA() (currprefs.rtgboards[0].rtgmem_type == GFXBOARD_VGA)
+#define ISVGA() (bridges[0]->vgaboard >= 0)
 
 static struct x86_bridge *bridges[X86_BRIDGE_MAX];
 
@@ -1947,7 +1949,7 @@ void portout(uint16_t portnum, uint8_t v)
                case 0x3cf:
                case 0x3b9:
                if (ISVGA()) {
-                       vga_io_put(portnum, v);
+                       vga_io_put(xb->vgaboard, portnum, v);
                }
                break;
 
@@ -1960,7 +1962,7 @@ void portout(uint16_t portnum, uint8_t v)
                        aio = 0x1ff;
                } else if (ISVGA()) {
                        if (x86_vga_mode == 0)
-                               vga_io_put(portnum, v);
+                               vga_io_put(xb->vgaboard, portnum, v);
                }
                break;
                case 0x3b1:
@@ -1971,7 +1973,7 @@ void portout(uint16_t portnum, uint8_t v)
                        aio = 0x2a1 + (xb->amiga_io[0x1ff] & 15) * 2;
                } else if (ISVGA()) {
                        if (x86_vga_mode == 0)
-                               vga_io_put(portnum, v);
+                               vga_io_put(xb->vgaboard, portnum, v);
                }
                break;
                case 0x3b8:
@@ -1989,7 +1991,7 @@ void portout(uint16_t portnum, uint8_t v)
                        aio = 0x21f;
                } else if (ISVGA()) {
                        if (x86_vga_mode == 1)
-                               vga_io_put(portnum, v);
+                               vga_io_put(xb->vgaboard, portnum, v);
                }
                break;
                case 0x3d1:
@@ -2000,7 +2002,7 @@ void portout(uint16_t portnum, uint8_t v)
                        aio = 0x2c1 + (xb->amiga_io[0x21f] & 15) * 2;
                } else if (ISVGA()) {
                        if (x86_vga_mode == 1)
-                               vga_io_put(portnum, v);
+                               vga_io_put(xb->vgaboard, portnum, v);
                }
                break;
                case 0x3d8:
@@ -2024,7 +2026,7 @@ void portout(uint16_t portnum, uint8_t v)
                        aio = 0x1f;
                } else if (ISVGA()) {
                        if (x86_vga_mode == 0)
-                               vga_io_put(portnum, v);
+                               vga_io_put(xb->vgaboard, portnum, v);
                }
                break;
                case 0x3da:
@@ -2032,7 +2034,7 @@ void portout(uint16_t portnum, uint8_t v)
                        aio = 0x1f;
                } else if (ISVGA()) {
                        if (x86_vga_mode == 1)
-                               vga_io_put(portnum, v);
+                               vga_io_put(xb->vgaboard, portnum, v);
                }
                break;
 
@@ -2380,7 +2382,7 @@ uint8_t portin(uint16_t portnum)
                case 0x3cf:
                case 0x3b9:
                if (ISVGA()) {
-                       v = vga_io_get(portnum);
+                       v = vga_io_get(xb->vgaboard, portnum);
                }
                break;
 
@@ -2396,7 +2398,7 @@ uint8_t portin(uint16_t portnum)
                        aio = 0x1ff;
                } else if (ISVGA()) {
                        if (x86_vga_mode == 0)
-                               v = vga_io_get(portnum);
+                               v = vga_io_get(xb->vgaboard, portnum);
                }
                break;
                case 0x3b1:
@@ -2407,7 +2409,7 @@ uint8_t portin(uint16_t portnum)
                        aio = 0x2a1 + (xb->amiga_io[0x1ff] & 15) * 2;
                } else if (ISVGA()) {
                        if (x86_vga_mode == 0)
-                               v = vga_io_get(portnum);
+                               v = vga_io_get(xb->vgaboard, portnum);
                }
                break;
                case 0x3b8:
@@ -2425,7 +2427,7 @@ uint8_t portin(uint16_t portnum)
                        aio = 0x21f;
                } else if (ISVGA()) {
                        if (x86_vga_mode == 1)
-                               v = vga_io_get(portnum);
+                               v = vga_io_get(xb->vgaboard, portnum);
                }
                break;
                case 0x3d1:
@@ -2436,7 +2438,7 @@ uint8_t portin(uint16_t portnum)
                        aio = 0x2c1 + (xb->amiga_io[0x21f] & 15) * 2;
                } else if (ISVGA()) {
                        if (x86_vga_mode == 1)
-                               v = vga_io_get(portnum);
+                               v = vga_io_get(xb->vgaboard, portnum);
                }
                break;
                case 0x3d8:
@@ -2455,7 +2457,7 @@ uint8_t portin(uint16_t portnum)
                        v = get0x3da(xb);
                } else if (ISVGA()) {
                        if (x86_vga_mode == 0)
-                               v = vga_io_get(portnum);
+                               v = vga_io_get(xb->vgaboard, portnum);
                }
                break;
                case 0x3da:
@@ -2463,7 +2465,7 @@ uint8_t portin(uint16_t portnum)
                        v = get0x3da(xb);
                } else if (ISVGA()) {
                        if (x86_vga_mode == 1)
-                               v = vga_io_get(portnum);
+                               v = vga_io_get(xb->vgaboard, portnum);
                }
                break;
                case 0x3dd:
@@ -2886,7 +2888,7 @@ static void REGPARAM2 x86_bridge_bput(uaecptr addr, uae_u32 b)
                switch (offset)
                {
                        case 0x48:
-                       map_banks_z2(xb->bank, b, expamem_z2_size >> 16);
+                       map_banks_z2(xb->bank, b, expamem_board_size >> 16);
                        xb->baseaddress = b << 16;
                        xb->configured = 1;
                        expamem_next(xb->bank, NULL);
@@ -3267,12 +3269,29 @@ void x86_xt_ide_bios(struct zfile *z, struct romconfig *rc)
 static const uae_u8 a1060_autoconfig[16] = { 0xc4, 0x01, 0x80, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
 static const uae_u8 a2386_autoconfig[16] = { 0xc4, 0x67, 0x80, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
 
-addrbank *x86_bridge_init(struct romconfig *rc, uae_u32 romtype, int type)
+bool x86_bridge_init(struct autoconfig_info *aci, uae_u32 romtype, int type)
 {
-       struct x86_bridge *xb = x86_bridge_alloc();
        const uae_u8 *ac;
-       if (!xb)
-               return &expamem_null;
+       struct romconfig *rc = aci->rc;
+
+       if (type >= TYPE_2286) {
+               ac = type >= TYPE_2386 ? a2386_autoconfig : a1060_autoconfig;
+       } else {
+               ac = a1060_autoconfig;
+       }       
+               
+       for (int i = 0; i < 16; i++) {
+               ew(aci->autoconfig_raw, i * 4, ac[i]);
+       }
+       if (!aci->doinit)
+               return true;
+
+       struct x86_bridge *xb = x86_bridge_alloc();
+       if (!xb) {
+               aci->addrbank = &expamem_null;
+               return true;
+       }
+       memcpy(xb->acmemory, aci->autoconfig_raw, sizeof aci->autoconfig_raw);
        bridges[0] = xb;
        xb->rc = rc;
 
@@ -3288,13 +3307,11 @@ addrbank *x86_bridge_init(struct romconfig *rc, uae_u32 romtype, int type)
                xb->dosbox_cpu = ((xb->settings >> 19) & 3) + 1;
                xb->dosbox_cpu_arch = (xb->settings >> 23) & 7;
                xb->settings |= 0xff;
-               ac = xb->type >= TYPE_2386 ? a2386_autoconfig : a1060_autoconfig;
                xb->pc_maxram = (1024 * 1024) << ((xb->settings >> 16) & 7);
                xb->bios_size = 65536;
        } else {
                xb->dosbox_cpu = (xb->settings >> 19) & 7;
                xb->dosbox_cpu_arch = (xb->settings >> 23) & 7;
-               ac = a1060_autoconfig;
                xb->pc_maxram = 1 * 1024 * 1024;
                xb->bios_size = 32768;
        }
@@ -3334,11 +3351,17 @@ addrbank *x86_bridge_init(struct romconfig *rc, uae_u32 romtype, int type)
                        }
                }
        }
-       if (ISVGA()) {
-               if (xb->dosbox_cpu) {
-                       MEM_SetVGAHandler();
+       xb->vgaboard = -1;
+       for (int i = 0; i < MAX_RTG_BOARDS; i++) {
+               if (currprefs.rtgboards[i].rtgmem_type == GFXBOARD_VGA) {
+                       xb->vgaboard = i;
+                       x86_vga_board = i;
+                       if (xb->dosbox_cpu) {
+                               MEM_SetVGAHandler();
+                       }
+                       load_vga_bios();
+                       break;
                }
-               load_vga_bios();
        }
 
        xb->pc_jumpers = (xb->settings & 0xff) ^ ((0x80 | 0x40) | (0x20 | 0x10 | 0x01 | 0x02));
@@ -3371,32 +3394,30 @@ addrbank *x86_bridge_init(struct romconfig *rc, uae_u32 romtype, int type)
        setrombank(xb, 0x100000 - xb->bios_size, xb->bios_size);
 
        xb->bank = &x86_bridge_bank;
-       for (int i = 0; i < 16; i++) {
-               ew(xb->acmemory, i * 4, ac[i]);
-       }
 
-       return xb->bank;
+       aci->addrbank = xb->bank;
+       return true;
 }
 
-addrbank *a1060_init(struct romconfig *rc)
+bool a1060_init(struct autoconfig_info *aci)
 {
-       return x86_bridge_init(rc, ROMTYPE_A1060, TYPE_SIDECAR);
+       return x86_bridge_init(aci, ROMTYPE_A1060, TYPE_SIDECAR);
 }
-addrbank *a2088xt_init(struct romconfig *rc)
+bool a2088xt_init(struct autoconfig_info *aci)
 {
-       return x86_bridge_init(rc, ROMTYPE_A2088, TYPE_2088);
+       return x86_bridge_init(aci, ROMTYPE_A2088, TYPE_2088);
 }
-addrbank *a2088t_init(struct romconfig *rc)
+bool a2088t_init(struct autoconfig_info *aci)
 {
-       return x86_bridge_init(rc, ROMTYPE_A2088T, TYPE_2088T);
+       return x86_bridge_init(aci, ROMTYPE_A2088T, TYPE_2088T);
 }
-addrbank *a2286_init(struct romconfig *rc)
+bool a2286_init(struct autoconfig_info *aci)
 {
-       return x86_bridge_init(rc, ROMTYPE_A2286, TYPE_2286);
+       return x86_bridge_init(aci, ROMTYPE_A2286, TYPE_2286);
 }
-addrbank *a2386_init(struct romconfig *rc)
+bool a2386_init(struct autoconfig_info *aci)
 {
-       return x86_bridge_init(rc, ROMTYPE_A2386, TYPE_2386);
+       return x86_bridge_init(aci, ROMTYPE_A2386, TYPE_2386);
 }
 
 /* dosbox cpu core support stuff */
index 234a77365c021b1c6a9e8affa1fd43a689a03eef..22fe3d6588349ad5d0cc9092b452e7e02b5cc039 100644 (file)
--- a/zfile.cpp
+++ b/zfile.cpp
@@ -1714,44 +1714,26 @@ static struct zfile *zfile_fopen_2 (const TCHAR *name, const TCHAR *mode, int ma
        return l;
 }
 
-#ifdef _WIN32
-#include "win32.h"
-
-#define AF _T("%AMIGAFOREVERDATA%")
-
-static void manglefilename (TCHAR *out, const TCHAR *in)
+static void manglefilename(const TCHAR *in, TCHAR *out, int outsize)
 {
-       int i;
-
-       out[0] = 0;
-       if (!strncasecmp (in, AF, _tcslen (AF)))
-               _tcscpy (out, start_path_data);
-       if ((in[0] == '/' || in[0] == '\\') || (_tcslen(in) > 3 && in[1] == ':' && in[2] == '\\'))
-               out[0] = 0;
-       _tcscat (out, in);
-       for (i = 0; i < _tcslen (out); i++) {
+       if (!target_expand_environment(in, out, outsize))
+               _tcscpy(out, in);
+       for (int i = 0; i < _tcslen(out); i++) {
                // remove \\ or // in the middle of path
                if ((out[i] == '/' || out[i] == '\\') && (out[i + 1] == '/' || out[i + 1] == '\\') && i > 0) {
-                       memmove (out + i, out + i + 1, (_tcslen (out + i) + 1) * sizeof (TCHAR));
+                       memmove(out + i, out + i + 1, (_tcslen(out + i) + 1) * sizeof(TCHAR));
                        i--;
                        continue;
                }
        }
 }
-#else
-static void manglefilename(TCHAR *out, const TCHAR *in)
-{
-       _tcscpy (out, in);
-}
-#endif
-
 int zfile_zopen (const TCHAR *name, zfile_callback zc, void *user)
 {
        struct zfile *l;
        int ztype;
        TCHAR path[MAX_DPATH];
 
-       manglefilename (path, name);
+       manglefilename (name, path, sizeof path / sizeof(TCHAR));
        l = zfile_fopen_2 (path, _T("rb"), ZFD_NORMAL);
        if (!l)
                return 0;
@@ -1775,7 +1757,7 @@ static struct zfile *zfile_fopen_x (const TCHAR *name, const TCHAR *mode, int ma
 
        if (_tcslen (name) == 0)
                return NULL;
-       manglefilename (path, name);
+       manglefilename(name, path, sizeof(path) / sizeof TCHAR);
        l = zfile_fopen_2 (path, mode, mask);
        if (!l)
                return 0;
@@ -1810,6 +1792,7 @@ static int isinternetfile (const TCHAR *name)
        return 0;
 }
 #include <wininet.h>
+#include "win32.h"
 #define INETBUFFERLEN 1000000
 static struct zfile *zfile_fopen_internet (const TCHAR *name, const TCHAR *mode, int mask)
 {