]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
3300b1
authorToni Wilen <twilen@winuae.net>
Sat, 9 Jan 2016 16:11:20 +0000 (18:11 +0200)
committerToni Wilen <twilen@winuae.net>
Sat, 9 Jan 2016 16:11:20 +0000 (18:11 +0200)
55 files changed:
akiko.cpp
audio.cpp
blitter.cpp
cfgfile.cpp
cia.cpp
cpuboard.cpp
custom.cpp
debug.cpp
devices.cpp
disk.cpp
drawing.cpp
expansion.cpp
gencpu.cpp
gfxboard.cpp
include/autoconf.h
include/cpu_prefetch.h
include/cpuboard.h
include/debug.h
include/disk.h
include/gfxboard.h
include/inputdevice.h
include/keyboard.h
include/memory.h
include/newcpu.h
include/options.h
include/rommgr.h
include/uae.h
include/uae/ppc.h
inputdevice.cpp
inputevents.def
jit/compemu_prefs.cpp
jit/compemu_support.cpp
jit/exception_handler.cpp
main.cpp
mame/a2410.cpp
memory.cpp
newcpu.cpp
od-win32/dinput.cpp
od-win32/hardfile_win32.cpp
od-win32/keyboard_win32.cpp
od-win32/mman.cpp
od-win32/parser.cpp
od-win32/picasso96_win.cpp
od-win32/resources/winuae.rc
od-win32/rp.cpp
od-win32/srcrelease.cmd
od-win32/win32.cpp
od-win32/win32.h
od-win32/win32gfx.cpp
od-win32/win32gui.cpp
od-win32/winuaechangelog.txt
od-win32/writelog.cpp
ppc/ppc.cpp
rommgr.cpp
uaelib.cpp

index a973564bea16a50d19e4731ea7f4eb80a8146cd3..eab39bb4d7a8f6d028b1ba3bd3ed68dd8831216e 100644 (file)
--- a/akiko.cpp
+++ b/akiko.cpp
@@ -602,7 +602,7 @@ static bool is_valid_data_sector(int sector)
 /* open device */
 static int sys_cddev_open (void)
 {
-       struct device_info di;
+       struct device_info di = { 0 };
        unitnum = get_standard_cd_unit (CD_STANDARD_UNIT_CD32);
        sys_command_info (unitnum, &di, 0);
        write_log (_T("using drive %s (unit %d, media %d)\n"), di.label, unitnum, di.media_inserted);
index e279844945d3fff434410a1ef0dbd67e826b17a8..daaf9ad714fc0c6ae8ea19a8231edcc510e9a822 100644 (file)
--- a/audio.cpp
+++ b/audio.cpp
@@ -887,12 +887,12 @@ void sample16ss_handler (void)
        get_extra_channels_sample(&data2, &data3, 0);
 
        set_sound_buffers ();
-       put_sound_word_left (data0);
-       put_sound_word_right (data1);
+       put_sound_word_right(data0);
+       put_sound_word_left (data1);
        if (currprefs.sound_stereo == SND_6CH)
                make6ch (data0, data1, data2, data3);
-       put_sound_word_left2 (data3);
-       put_sound_word_right2 (data2);
+       put_sound_word_right2(data3);
+       put_sound_word_left2 (data2);
        check_sound_buffers ();
 }
 
@@ -919,12 +919,12 @@ static void sample16ss_anti_handler (void)
        get_extra_channels_sample(&data3, &data2, 1);
 
        set_sound_buffers ();
-       put_sound_word_left (data0);
-       put_sound_word_right (data1);
+       put_sound_word_right(data0);
+       put_sound_word_left (data1);
        if (currprefs.sound_stereo == SND_6CH)
                make6ch (data0, data1, data2, data3);
-       put_sound_word_left2 (data3);
-       put_sound_word_right2 (data2);
+       put_sound_word_right2(data3);
+       put_sound_word_left2 (data2);
        check_sound_buffers ();
 }
 
@@ -944,8 +944,8 @@ static void sample16si_anti_handler (void)
        get_extra_channels_sample(&data1, &data2, 1);
 
        set_sound_buffers ();
-       put_sound_word_left (data1);
-       put_sound_word_right (data2);
+       put_sound_word_right(data1);
+       put_sound_word_left (data2);
        check_sound_buffers ();
 }
 
@@ -969,12 +969,12 @@ static void sample16ss_sinc_handler (void)
        get_extra_channels_sample(&data3, &data2, 2);
 
        set_sound_buffers ();
-       put_sound_word_left (data0);
-       put_sound_word_right (data1);
+       put_sound_word_right(data0);
+       put_sound_word_left (data1);
        if (currprefs.sound_stereo == SND_6CH)
                make6ch (data0, data1, data2, data3);
-       put_sound_word_left2 (data3);
-       put_sound_word_right2 (data2);
+       put_sound_word_right2(data3);
+       put_sound_word_left2 (data2);
        check_sound_buffers ();
 }
 
@@ -994,8 +994,8 @@ static void sample16si_sinc_handler (void)
        get_extra_channels_sample(&data1, &data2, 2);
 
        set_sound_buffers ();
-       put_sound_word_left (data1);
-       put_sound_word_right (data2);
+       put_sound_word_right(data1);
+       put_sound_word_left(data2);
        check_sound_buffers ();
 }
 
@@ -1028,8 +1028,8 @@ void sample16s_handler (void)
        get_extra_channels_sample(&data2, &data3, 0);
 
        set_sound_buffers ();
-       put_sound_word_left (data2);
-       put_sound_word_right (data3);
+       put_sound_word_right(data2);
+       put_sound_word_left(data3);
        check_sound_buffers ();
 }
 
@@ -1107,8 +1107,8 @@ static void sample16si_crux_handler (void)
        get_extra_channels_sample(&data2, &data3, 0);
 
        set_sound_buffers ();
-       put_sound_word_left (data2);
-       put_sound_word_right (data3);
+       put_sound_word_right(data2);
+       put_sound_word_left (data3);
        check_sound_buffers ();
 }
 
@@ -1167,8 +1167,8 @@ static void sample16si_rh_handler (void)
        get_extra_channels_sample(&data2, &data3, 0);
 
        set_sound_buffers ();
-       put_sound_word_left (data2);
-       put_sound_word_right (data3);
+       put_sound_word_right(data2);
+       put_sound_word_left (data3);
        check_sound_buffers ();
 }
 
index 15fd314ed45b6c5f61dc39e58da1a6b76b5824d8..4c8ab2c7e6cdfbb23e6a5522e1827a4472e6ea78 100644 (file)
@@ -274,14 +274,20 @@ STATIC_INLINE void record_dma_blit (uae_u16 reg, uae_u16 dat, uae_u32 addr, int
        if (debug_dma)
                record_dma (reg, dat, addr, hpos, vpos, type);
        if (memwatch_enabled) {
-               if (reg == 0)
-                       debug_wputpeekdma_chipram(addr, dat, MW_MASK_BLITTER_D, reg);
-               else if (reg == 0x70)
+               if (reg == 0) {
+                       uae_u32 mask = MW_MASK_BLITTER_D_N;
+                       if (blitfill)
+                               mask = MW_MASK_BLITTER_D_F;
+                       if (blitline)
+                               mask = MW_MASK_BLITTER_D_L;
+                       debug_wputpeekdma_chipram(addr, dat, mask, reg);
+               } else if (reg == 0x70) {
                        debug_wgetpeekdma_chipram(addr, dat, MW_MASK_BLITTER_C, reg);
-               else if (reg == 0x72)
+               } else if (reg == 0x72) {
                        debug_wgetpeekdma_chipram(addr, dat, MW_MASK_BLITTER_B, reg);
-               else if (reg == 0x74)
+               } else if (reg == 0x74) {
                        debug_wgetpeekdma_chipram(addr, dat, MW_MASK_BLITTER_A, reg);
+               }
        }
 #endif
 }
@@ -392,6 +398,7 @@ static void check_channel_mods (int hpos, int ch)
        if (ch == bltptxc) {
                bltptxpos = -1;
                write_log (_T("BLITTER: %08X write to %cPT ignored! %08x\n"), bltptx, ch + 'A' - 1, m68k_getpc ());
+               //activate_debugger();
        }
 }
 
@@ -436,7 +443,7 @@ STATIC_INLINE void chipmem_agnus_wput2 (uaecptr addr, uae_u32 w)
        //last_custom_value1 = w; blitter writes are not stored
        if (!(log_blitter & 4)) {
                chipmem_wput_indirect (addr, w);
-               debug_wputpeekdma_chipram (addr, w, MW_MASK_BLITTER_D, 0x000);
+               debug_wputpeekdma_chipram (addr, w, MW_MASK_BLITTER_D_N, 0x000);
        }
 }
 
@@ -661,7 +668,7 @@ STATIC_INLINE void blitter_write (void)
                        return;
                //last_custom_value1 = blt_info.bltddat; blitter writes are not stored
                chipmem_wput_indirect (bltdpt, blt_info.bltddat);
-               debug_wputpeekdma_chipram (bltdpt, blt_info.bltddat, MW_MASK_BLITTER_D, 0x000);
+               debug_wputpeekdma_chipram (bltdpt, blt_info.bltddat, MW_MASK_BLITTER_D_N, 0x000);
        }
        bltstate = BLT_next;
 }
index 9b6a110125581b2aadeb2a14f4b7817b2422179b..28cf70d49b51e6edda4e5b0fcaa7c37e985d7148 100644 (file)
@@ -291,7 +291,6 @@ static const TCHAR *obsolete[] = {
        _T("gfx_filter_vert_zoom"),_T("gfx_filter_horiz_zoom"),
        _T("gfx_filter_vert_zoom_mult"), _T("gfx_filter_horiz_zoom_mult"),
        _T("gfx_filter_vert_offset"), _T("gfx_filter_horiz_offset"),
-       _T("rtg_vert_zoom_multf"), _T("rtg_horiz_zoom_multf"),
        
        // created by some buggy beta
        _T("uaehf0%s,%s"),
@@ -1234,6 +1233,7 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
        cfgfile_write (f, _T("config_version"), _T("%d.%d.%d"), UAEMAJOR, UAEMINOR, UAESUBREV);
        cfgfile_write_str (f, _T("config_hardware_path"), p->config_hardware_path);
        cfgfile_write_str (f, _T("config_host_path"), p->config_host_path);
+       cfgfile_write_str (f, _T("config_all_path"), p->config_all_path);
        if (p->config_window_title[0])
                cfgfile_write_str (f, _T("config_window_title"), p->config_window_title);
 
@@ -1420,12 +1420,12 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
                struct jport *jp = &p->jports[i];
                int v = jp->id;
                TCHAR tmp1[MAX_DPATH], tmp2[MAX_DPATH];
-               if (v == JPORT_CUSTOM) {
-                       _tcscpy (tmp2, _T("custom"));
-               } else if (v == JPORT_NONE) {
+               if (v == JPORT_NONE) {
                        _tcscpy (tmp2, _T("none"));
+               } else if (v < JSEM_CUSTOM) {
+                       _stprintf(tmp2, _T("kbd%d"), v + 1);
                } else if (v < JSEM_JOYS) {
-                       _stprintf (tmp2, _T("kbd%d"), v + 1);
+                       _stprintf(tmp2, _T("custom%d"), v - JSEM_CUSTOM);
                } else if (v < JSEM_MICE) {
                        _stprintf (tmp2, _T("joy%d"), v - JSEM_JOYS);
                } else {
@@ -1456,6 +1456,15 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
                        }
                }
        }
+       for (i = 0; i < MAX_JPORTS_CUSTOM; i++) {
+               struct jport_custom *jp = &p->jports_custom[i];
+               if (jp->custom[0]) {
+                       TCHAR tmp1[MAX_DPATH];
+                       _stprintf(tmp1, _T("joyportcustom%d"), i);
+                       cfgfile_write(f, tmp1, jp->custom);
+               }
+       }
+
        if (p->dongle) {
                if (p->dongle + 1 >= sizeof (dongles) / sizeof (TCHAR*))
                        cfgfile_write (f, _T("dongle"), _T("%d"), p->dongle);
@@ -2998,28 +3007,41 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value)
                return 1;
        }
 
+       if (cfgfile_string(option, value, _T("joyportcustom0"), p->jports_custom[0].custom, sizeof p->jports_custom[0].custom / sizeof(TCHAR)))
+               return 1;
+       if (cfgfile_string(option, value, _T("joyportcustom1"), p->jports_custom[1].custom, sizeof p->jports_custom[1].custom / sizeof(TCHAR)))
+               return 1;
+       if (cfgfile_string(option, value, _T("joyportcustom2"), p->jports_custom[2].custom, sizeof p->jports_custom[2].custom / sizeof(TCHAR)))
+               return 1;
+       if (cfgfile_string(option, value, _T("joyportcustom3"), p->jports_custom[3].custom, sizeof p->jports_custom[3].custom / sizeof(TCHAR)))
+               return 1;
+       if (cfgfile_string(option, value, _T("joyportcustom4"), p->jports_custom[4].custom, sizeof p->jports_custom[4].custom / sizeof(TCHAR)))
+               return 1;
+       if (cfgfile_string(option, value, _T("joyportcustom5"), p->jports_custom[5].custom, sizeof p->jports_custom[5].custom / sizeof(TCHAR)))
+               return 1;
+
        if (_tcscmp (option, _T("joyportfriendlyname0")) == 0 || _tcscmp (option, _T("joyportfriendlyname1")) == 0) {
-               inputdevice_joyport_config (p, value, _tcscmp (option, _T("joyportfriendlyname0")) == 0 ? 0 : 1, -1, 2, true);
+               inputdevice_joyport_config_store(p, value, _tcscmp (option, _T("joyportfriendlyname0")) == 0 ? 0 : 1, -1, 2);
                return 1;
        }
        if (_tcscmp (option, _T("joyportfriendlyname2")) == 0 || _tcscmp (option, _T("joyportfriendlyname3")) == 0) {
-               inputdevice_joyport_config (p, value, _tcscmp (option, _T("joyportfriendlyname2")) == 0 ? 2 : 3, -1, 2, true);
+               inputdevice_joyport_config_store(p, value, _tcscmp (option, _T("joyportfriendlyname2")) == 0 ? 2 : 3, -1, 2);
                return 1;
        }
        if (_tcscmp (option, _T("joyportname0")) == 0 || _tcscmp (option, _T("joyportname1")) == 0) {
-               inputdevice_joyport_config (p, value, _tcscmp (option, _T("joyportname0")) == 0 ? 0 : 1, -1, 1, true);
+               inputdevice_joyport_config_store(p, value, _tcscmp (option, _T("joyportname0")) == 0 ? 0 : 1, -1, 1);
                return 1;
        }
        if (_tcscmp (option, _T("joyportname2")) == 0 || _tcscmp (option, _T("joyportname3")) == 0) {
-               inputdevice_joyport_config (p, value, _tcscmp (option, _T("joyportname2")) == 0 ? 2 : 3, -1, 1, true);
+               inputdevice_joyport_config_store(p, value, _tcscmp (option, _T("joyportname2")) == 0 ? 2 : 3, -1, 1);
                return 1;
        }
        if (_tcscmp (option, _T("joyport0")) == 0 || _tcscmp (option, _T("joyport1")) == 0) {
-               inputdevice_joyport_config (p, value, _tcscmp (option, _T("joyport0")) == 0 ? 0 : 1, -1, 0, true);
+               inputdevice_joyport_config_store(p, value, _tcscmp (option, _T("joyport0")) == 0 ? 0 : 1, -1, 0);
                return 1;
        }
        if (_tcscmp (option, _T("joyport2")) == 0 || _tcscmp (option, _T("joyport3")) == 0) {
-               inputdevice_joyport_config (p, value, _tcscmp (option, _T("joyport2")) == 0 ? 2 : 3, -1, 0, true);
+               inputdevice_joyport_config_store(p, value, _tcscmp (option, _T("joyport2")) == 0 ? 2 : 3, -1, 0);
                return 1;
        }
        if (cfgfile_strval (option, value, _T("joyport0mode"), &p->jports[0].mode, joyportmodes, 0))
@@ -3038,6 +3060,7 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value)
                return 1;
        if (cfgfile_strval (option, value, _T("joyport3autofire"), &p->jports[3].autofire, joyaf, 0))
                return 1;
+
        if (cfgfile_yesno (option, value, _T("joyport0keyboardoverride"), &vb)) {
                p->jports[0].nokeyboardoverride = !vb;
                return 1;
@@ -4726,9 +4749,11 @@ int cfgfile_parse_option (struct uae_prefs *p, const TCHAR *option, TCHAR *value
                return 1;
        if (!_tcscmp (option, _T("config_host")))
                return 1;
+       if (cfgfile_path (option, value, _T("config_all_path"), p->config_all_path, sizeof p->config_all_path / sizeof(TCHAR)))
+               return 1;
        if (cfgfile_path (option, value, _T("config_hardware_path"), p->config_hardware_path, sizeof p->config_hardware_path / sizeof (TCHAR)))
                return 1;
-       if (cfgfile_path (option, value, _T("config_host_path"), p->config_host_path, sizeof p->config_host_path / sizeof (TCHAR)))
+       if (cfgfile_path (option, value, _T("config_host_path"), p->config_host_path, sizeof p->config_host_path / sizeof(TCHAR)))
                return 1;
        if (type == 0 || (type & CONFIG_TYPE_HARDWARE)) {
                if (cfgfile_parse_hardware (p, option, value))
@@ -5017,7 +5042,7 @@ static int cfgfile_load_2 (struct uae_prefs *p, const TCHAR *filename, bool real
        if (real) {
                p->config_version = 0;
                config_newfilesystem = 0;
-               store_inputdevice_config (p);
+               inputdevice_config_load_start(p);
                //reset_inputdevice_config (p);
        }
 
@@ -5057,7 +5082,8 @@ static int cfgfile_load_2 (struct uae_prefs *p, const TCHAR *filename, bool real
                        } else {
                                cfgfile_string (line1b, line2b, _T("config_description"), p->description, sizeof p->description / sizeof (TCHAR));
                                cfgfile_path (line1b, line2b, _T("config_hardware_path"), p->config_hardware_path, sizeof p->config_hardware_path / sizeof (TCHAR));
-                               cfgfile_path (line1b, line2b, _T("config_host_path"), p->config_host_path, sizeof p->config_host_path / sizeof (TCHAR));
+                               cfgfile_path (line1b, line2b, _T("config_host_path"), p->config_host_path, sizeof p->config_host_path / sizeof(TCHAR));
+                               cfgfile_path (line1b, line2b, _T("config_all_path"), p->config_all_path, sizeof p->config_all_path / sizeof(TCHAR));
                                cfgfile_string (line1b, line2b, _T("config_window_title"), p->config_window_title, sizeof p->config_window_title / sizeof (TCHAR));
                        }
                }
@@ -5109,6 +5135,12 @@ int cfgfile_load (struct uae_prefs *p, const TCHAR *filename, int *type, int ign
        if (userconfig)
                target_addtorecent (filename, 0);
        if (!ignorelink) {
+               if (p->config_all_path[0]) {
+                       fetch_configurationpath(tmp, sizeof(tmp) / sizeof(TCHAR));
+                       _tcsncat(tmp, p->config_all_path, sizeof(tmp) / sizeof(TCHAR) - _tcslen(tmp) - 1);
+                       type2 = CONFIG_TYPE_HOST | CONFIG_TYPE_HARDWARE;
+                       cfgfile_load(p, tmp, &type2, 1, 0);
+               }
                if (p->config_hardware_path[0]) {
                        fetch_configurationpath (tmp, sizeof (tmp) / sizeof (TCHAR));
                        _tcsncat (tmp, p->config_hardware_path, sizeof (tmp) / sizeof (TCHAR) - _tcslen(tmp) - 1);
@@ -6463,7 +6495,7 @@ static void set_68020_compa (struct uae_prefs *p, int compa, int cd32)
        case 3:
                p->cpu_compatible = 0;
                p->address_space_24 = 0;
-               p->cachesize = 8192;
+               p->cachesize = MAX_JIT_CACHE;
                break;
        }
 }
@@ -6513,7 +6545,7 @@ static int bip_a3000 (struct uae_prefs *p, int config, int compa, int romcheck)
        if (compa == 0)
                p->mmu_model = 68030;
        else
-               p->cachesize = 8192;
+               p->cachesize = MAX_JIT_CACHE;
        p->chipset_mask = CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE;
        p->cpu_compatible = p->address_space_24 = 0;
        p->m68k_speed = -1;
@@ -6564,7 +6596,7 @@ static int bip_a4000 (struct uae_prefs *p, int config, int compa, int romcheck)
        p->m68k_speed = -1;
        p->immediate_blits = 0;
        p->produce_sound = 2;
-       p->cachesize = 8192;
+       p->cachesize = MAX_JIT_CACHE;
        p->floppyslots[0].dfxtype = DRV_35_HD;
        p->floppyslots[1].dfxtype = DRV_35_HD;
        p->floppy_speed = 0;
@@ -6598,7 +6630,7 @@ static int bip_a4000t (struct uae_prefs *p, int config, int compa, int romcheck)
        p->m68k_speed = -1;
        p->immediate_blits = 0;
        p->produce_sound = 2;
-       p->cachesize = 8192;
+       p->cachesize = MAX_JIT_CACHE;
        p->floppyslots[0].dfxtype = DRV_35_HD;
        p->floppyslots[1].dfxtype = DRV_35_HD;
        p->floppy_speed = 0;
@@ -6943,7 +6975,7 @@ static int bip_super (struct uae_prefs *p, int config, int compa, int romcheck)
        p->m68k_speed = -1;
        p->immediate_blits = 1;
        p->produce_sound = 2;
-       p->cachesize = 8192;
+       p->cachesize = MAX_JIT_CACHE;
        p->floppyslots[0].dfxtype = DRV_35_HD;
        p->floppyslots[1].dfxtype = DRV_35_HD;
        p->floppy_speed = 0;
diff --git a/cia.cpp b/cia.cpp
index 8443d5cf735982499d571ca4e017f8f91dd8fe02..98593ddbbf4cdcc8827e03ddd44fd3fbc3eefa91 100644 (file)
--- a/cia.cpp
+++ b/cia.cpp
@@ -1733,7 +1733,7 @@ addrbank cia_bank = {
        cia_lput, cia_wput, cia_bput,
        default_xlate, default_check, NULL, NULL, _T("CIA"),
        cia_lgeti, cia_wgeti,
-       ABFLAG_IO, S_READ, S_WRITE, NULL, 0x3f01, 0xbfc000
+       ABFLAG_IO | ABFLAG_CIA, S_READ, S_WRITE, NULL, 0x3f01, 0xbfc000
 };
 
 // Gayle or Fat Gary does not enable CIA /CS lines if both CIAs are selected
index ecb538d43d5b5956344ab92cc956ffe9c5155bbe..3c4200ed7013271c9f0d28a4d91b7c6b9b651e1f 100644 (file)
@@ -33,6 +33,9 @@
 #include "scsi.h"
 #include "cpummu030.h"
 
+// 00F83B7C 3.1 ROM expansion board diagrom
+
+#define PPC_IRQ_DEBUG 0
 #define CPUBOARD_IO_LOG 0
 #define CPUBOARD_IRQ_LOG 0
 
@@ -165,6 +168,9 @@ static void set_ppc_interrupt(void)
 {
        if (ppc_irq_pending)
                return;
+#if PPC_IRQ_DEBUG
+       write_log(_T("set_ppc_interrupt\n"));
+#endif
        uae_ppc_interrupt(true);
        ppc_irq_pending = true;
 }
@@ -172,6 +178,9 @@ static void clear_ppc_interrupt(void)
 {
        if (!ppc_irq_pending)
                return;
+#if PPC_IRQ_DEBUG
+       write_log(_T("clear_ppc_interrupt\n"));
+#endif
        uae_ppc_interrupt(false);
        ppc_irq_pending = false;
 }
@@ -299,6 +308,10 @@ static bool is_kupke(void)
 {
        return ISCPUBOARD(BOARD_KUPKE, 0);
 }
+static bool is_sx32pro(void)
+{
+       return ISCPUBOARD(BOARD_DCE, 0);
+}
 static bool is_aca500(void)
 {
        return ISCPUBOARD(BOARD_IC, BOARD_IC_ACA500);
@@ -855,13 +868,33 @@ static void cyberstormmk1_copymaprom(void)
        }
 }
 
+bool cpuboard_is_ppcboard_irq(void)
+{
+       if (is_csmk3() || is_blizzardppc()) {
+               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))) {
+                       return true;
+               }
+       }
+       return false;
+}
+
 void cpuboard_rethink(void)
 {
        if (is_csmk3() || is_blizzardppc()) {
                if (!(io_reg[CSIII_REG_IRQ] & (P5_IRQ_SCSI_EN | P5_IRQ_SCSI))) {
                        INTREQ_0(0x8000 | 0x0008);
+                       if (currprefs.cachesize)
+                               uae_int_requested |= 0x010000;
+                       uae_ppc_wakeup_main();
                } else if (!(io_reg[CSIII_REG_IRQ] & (P5_IRQ_PPC_1 | P5_IRQ_PPC_2))) {
                        INTREQ_0(0x8000 | 0x0008);
+                       if (currprefs.cachesize)
+                               uae_int_requested |= 0x010000;
+                       uae_ppc_wakeup_main();
+               } else {
+                       uae_int_requested &= ~0x010000;
                }
                check_ppc_int_lvl();
                ppc_interrupt(intlev());
@@ -1185,6 +1218,11 @@ static void REGPARAM2 blizzardio_bput(uaecptr addr, uae_u32 v)
 #if CPUBOARD_IRQ_LOG > 0
                                        if (regval != oldval)
                                                write_log(_T("CS: interrupt level: %02x\n"), regval);
+#endif
+                               } else if (addr == CSIII_REG_IRQ) {
+#if CPUBOARD_IRQ_LOG > 0
+                                       if (regval != oldval)
+                                               write_log(_T("CS: IRQ: %02x\n"), regval);
 #endif
                                } else if (addr == CSIII_REG_SHADOW) {
                                        if (is_csmk3() && ((oldval ^ regval) & 1)) {
@@ -1447,7 +1485,13 @@ void cpuboard_init(void)
 
        cpuboard_size = currprefs.cpuboardmem1_size;
 
-       if (is_aca500()) {
+       if (is_kupke() || is_mtec_ematrix530() || is_sx32pro()) {
+               // plain 64k autoconfig, nothing else.
+               blizzardea_bank.allocated = 65536;
+               blizzardea_bank.mask = blizzardea_bank.allocated - 1;
+               mapped_malloc(&blizzardea_bank);
+
+       } else if (is_aca500()) {
 
                blizzardf0_bank.start = 0x00f00000;
                blizzardf0_bank.allocated = 524288;
@@ -1482,12 +1526,6 @@ void cpuboard_init(void)
                blizzardf0_bank.mask = blizzardf0_bank.allocated - 1;
                mapped_malloc(&blizzardf0_bank);
 
-       } else if (is_kupke() || is_mtec_ematrix530()) {
-
-               blizzardea_bank.allocated = 65536;
-               blizzardea_bank.mask = blizzardea_bank.allocated - 1;
-               mapped_malloc(&blizzardea_bank);
-
        } else if (is_apollo()) {
 
                blizzardf0_bank.start = 0x00f00000;
@@ -1710,42 +1748,30 @@ void cpuboard_clear(void)
                memset(blizzardf0_bank.baseaddr + 0x40000, 0, 0x10000);
 }
 
-static uaecptr cpuboardfakeres_init, cpuboardfakeres_name, cpuboardfakeres_id, base;
-
-#if 0
-uaecptr cpuboardfakeresident_startup (uaecptr resaddr)
-{
-       if (!cpuboardfakeres_name)
-               return resaddr;
-       put_word (resaddr + 0x0, 0x4AFC);
-       put_long (resaddr + 0x2, resaddr);
-       put_long (resaddr + 0x6, resaddr + 0x1A);
-       put_word (resaddr + 0xA, 0x0201);
-       put_word (resaddr + 0xC, 0x0078);
-       put_long (resaddr + 0xE, cpuboardfakeres_name);
-       put_long (resaddr + 0x12, cpuboardfakeres_id);
-       put_long (resaddr + 0x16, cpuboardfakeres_init);
-       resaddr += 0x1A;
-       return resaddr;
-}
+// Adds resource resident that CSPPC/BPPC flash updater checks.
+
+#define FAKEPPCROM_OFFSET 32
+static const uae_u8 fakeppcrom[] = {
+       // struct Resident
+       0x4a, 0xfc,
+       0x00, 0xf0, 0x00, FAKEPPCROM_OFFSET,
+       0x00, 0xf0, 0x01, 0x00,
+       0x02, 0x01, 0x00, 0x78,
+       0x00, 0xf0, 0x00, FAKEPPCROM_OFFSET + 30,
+       0x00, 0xf0, 0x00, FAKEPPCROM_OFFSET + 30,
+       0x00, 0xf0, 0x00, FAKEPPCROM_OFFSET + 26,
+       // moveq #0,d0; rts
+       0x70, 0x00, 0x4e, 0x75
+};
+static const char fakeppcromtxt_cs[] = { "CyberstormPPC.IDTag" };
+static const char fakeppcromtxt_bz[] = { "BlizzardPPC.IDTag" };
 
-void cpuboardfakeres_install (void)
+static void makefakeppcrom(uae_u8 *rom, int type)
 {
-       cpuboardfakeres_name = NULL;
-       if (ISCPUBOARD(BOARD_CYBERSTORM, BOARD_CYBERSTORM_SUB_PPC)) {
-               cpuboardfakeres_name = ds (_T("CyberstormMK3.IDTag"));
-       } else if (ISCPUBOARD(BOARD_CYBERSTORM, BOARD_CYBERSTORM_SUB_MK3)) {
-               cpuboardfakeres_name = ds (_T("CyberstormPPC.IDTag"));
-       }
-       if (cpuboardfakeres_name) {
-               cpuboardfakeres_init = here();
-               dw(0x4e71);
-               dw(0x7000);
-               dw(0x4e75);
-               cpuboardfakeres_id = cpuboardfakeres_name;
-       }
+       memcpy(rom + FAKEPPCROM_OFFSET, fakeppcrom, sizeof fakeppcrom);
+       const char *txt = type ? fakeppcromtxt_bz : fakeppcromtxt_cs;
+       memcpy(rom + FAKEPPCROM_OFFSET + sizeof fakeppcrom, txt, strlen(txt) + 1);
 }
-#endif
 
 bool is_ppc_cpu(struct uae_prefs *p)
 {
@@ -1883,10 +1909,7 @@ static void fixserial(uae_u8 *rom, int size)
        int seroffset = 17, longseroffset = 24;
        uae_u32 serialnum = 0x1234;
        char serial[10];
-
-#if 0
-       return;
-#endif
+       int type = -1;
 
        if (ISCPUBOARD(BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_PPC)) {
                value1 = 'I';
@@ -1899,12 +1922,14 @@ static void fixserial(uae_u8 *rom, int size)
                        value3 = 'A';
                seroffset = 19;
                sprintf(serial, "%04X", serialnum);
+               type = 1;
        } else if (ISCPUBOARD(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)) {
                value1 = 'F';
                sprintf(serial, "%05X", serialnum);
@@ -1927,6 +1952,9 @@ static void fixserial(uae_u8 *rom, int size)
                        rom[longseroffset + 3] = serialnum >>  0;
                }
        }
+
+       if (type >= 0 && rom[0] == 0 && rom[1] == 0)
+               makefakeppcrom(rom, type);
 }
 
 static struct zfile *flashfile_open(const TCHAR *name)
@@ -2153,6 +2181,10 @@ addrbank *cpuboard_autoconfig_init(struct romconfig *rc)
                        roms[0] = 126;
                break;
 
+               case BOARD_DCE:
+                       roms[0] = 160;
+               break;
+
                default:
                        return &expamem_null;
        }
@@ -2215,7 +2247,15 @@ addrbank *cpuboard_autoconfig_init(struct romconfig *rc)
 
        protect_roms(false);
        cpuboard_non_byte_ea = true;
-       if (is_mtec_ematrix530()) {
+       if (is_sx32pro()) {
+               earom_size = 65536;
+               for (int i = 0; i < 32768; i++) {
+                       uae_u8 b = 0xff;
+                       zfile_fread(&b, 1, 1, autoconfig_rom);
+                       blizzardea_bank.baseaddr[i * 2 + 0] = b;
+                       blizzardea_bank.baseaddr[i * 2 + 1] = 0xff;
+               }
+       } else if (is_mtec_ematrix530()) {
                earom_size = 65536;
                for (int i = 0; i < 32768; i++) {
                        uae_u8 b = 0xff;
index 878d86420399fc26bcc41749af35e383dc0ca870..10dd3884c4bace016d8e2588c1ec5d82c0616040 100644 (file)
@@ -518,7 +518,8 @@ void alloc_cycle_blitter (int hpos, uaecptr *ptr, int chnum)
                        warned--;
                        //activate_debugger ();
                }
-               if ((currprefs.cs_hacks & 1) && currprefs.cpu_model == 68000)
+               //if ((currprefs.cs_hacks & 1) && currprefs.cpu_model == 68000)
+               if (currprefs.cpu_model == 68000 && currprefs.cpu_cycle_exact && currprefs.blitter_cycle_exact)
                        *ptr = srcptr;
        }
        alloc_cycle (hpos, CYCLE_BLITTER);
@@ -2185,7 +2186,7 @@ static void maybe_finish_last_fetch (int pos, int fm)
        static int warned = 20;
        bool done = false;
 
-       if (plf_state != plf_passed_stop2 || (fetch_state != fetch_started && fetch_state != fetch_started_first) || !dmaen (DMA_BITPLANE)) {
+       if (plf_state != plf_passed_stop2 || (fetch_state != fetch_started && fetch_state != fetch_started_first) || aga_plf_passed_stop2 || !dmaen (DMA_BITPLANE)) {
                finish_last_fetch (pos, fm, true);
                return;
        }
@@ -3746,7 +3747,7 @@ static void reset_decisions (void)
        }
 
        memset (outword, 0, sizeof outword);
-       // fetched must not be cleared (Sony VX-90 / Royal Amiga Force)
+       // fetched[] must not be cleared (Sony VX-90 / Royal Amiga Force)
        todisplay_fetched[0] = todisplay_fetched[1] = false;
        memset (todisplay, 0, sizeof todisplay);
        memset (todisplay2, 0, sizeof todisplay2);
@@ -4809,7 +4810,7 @@ static void COPJMP (int num, int vblank)
 
        if (!oldstrobe)
                cop_state.state_prev = cop_state.state;
-       if ((cop_state.state == COP_wait || cop_state.state == COP_waitforever) && !vblank) {
+       if ((cop_state.state == COP_wait || cop_state.state == COP_waitforever) && !vblank && dmaen(DMA_COPPER)) {
                cop_state.state = COP_strobe_delay1x;
        } else {
                cop_state.state = vblank ? COP_start_delay : (copper_access ? COP_strobe_delay1 : COP_strobe_extra);
@@ -6326,12 +6327,12 @@ static void update_copper (int until_hpos)
                case COP_strobe_delay1x:
                        // First cycle after COPJMP and Copper was waiting. This is the buggy one.
                        // Cycle can be free and copper won't allocate it.
-                       // If Blitter uses this cycle = Copper's address gets copied blitter DMA pointer..
+                       // If Blitter uses this cycle = Copper's PC gets copied to blitter DMA pointer..
                        cop_state.state = COP_strobe_delay2x;
                        break;
                case COP_strobe_delay2x:
                        // Second cycle fetches following word and tosses it away. Must be free cycle
-                       // but is not allocated, blitter or cpu can still use it.
+                       // but it is not allocated, blitter or cpu can still use it.
                        if (copper_cant_read (old_hpos, 1))
                                continue;
                        cycle_line[old_hpos] |= CYCLE_COPPER_SPECIAL;
@@ -8181,7 +8182,7 @@ static void hsync_handler_post (bool onvsync)
        if (uae_int_requested) {
                if (uae_int_requested & 0xff00)
                        INTREQ(0x8000 | 0x2000);
-               if (uae_int_requested & 0x0ff)
+               if (uae_int_requested & 0x00ff)
                        INTREQ(0x8000 | 0x0008);
        }
 
@@ -9863,16 +9864,28 @@ uae_u32 wait_cpu_cycle_read (uaecptr addr, int mode)
                        reg |= 2;
                else
                        reg |= 1;
-               dr = record_dma (reg, v, addr, hpos, vpos, DMARECORD_CPU);
+               dr = record_dma (reg, v, addr, hpos, vpos, mode == -2 || mode == 2 ? DMARECORD_CPU_I : DMARECORD_CPU_D);
                checknasty (hpos, vpos);
        }
 #endif
-       if (mode < 0)
-               v = get_long (addr);
-       else if (mode > 0)
-               v = get_word (addr);
-       else if (mode == 0)
-               v = get_byte (addr);
+       switch(mode)
+       {
+               case -1:
+               v = get_long(addr);
+               break;
+               case -2:
+               v = get_longi(addr);
+               break;
+               case 1:
+               v = get_word(addr);
+               break;
+               case 2:
+               v = get_wordi(addr);
+               break;
+               case 0:
+               v = get_byte(addr);
+               break;
+       }
 
 #ifdef DEBUGGER
        if (debug_dma)
@@ -9905,16 +9918,27 @@ uae_u32 wait_cpu_cycle_read_ce020 (uaecptr addr, int mode)
                        reg |= 2;
                else
                        reg |= 1;
-               dr = record_dma (reg, v, addr, hpos, vpos, DMARECORD_CPU);
+               dr = record_dma (reg, v, addr, hpos, vpos, mode == -2 || mode == 2 ? DMARECORD_CPU_I : DMARECORD_CPU_D);
                checknasty (hpos, vpos);
        }
 #endif
-       if (mode < 0)
-               v = get_long (addr);
-       else if (mode > 0)
-               v = get_word (addr);
-       else if (mode == 0)
-               v = get_byte (addr);
+       switch (mode) {
+               case -1:
+               v = get_long(addr);
+               break;
+               case -2:
+               v = get_longi(addr);
+               break;
+               case 1:
+               v = get_word(addr);
+               break;
+               case 2:
+               v = get_wordi(addr);
+               break;
+               case 0:
+               v = get_byte(addr);
+               break;
+       }
 
 #ifdef DEBUGGER
        if (debug_dma)
@@ -9944,7 +9968,7 @@ void wait_cpu_cycle_write (uaecptr addr, int mode, uae_u32 v)
                        reg |= 2;
                else
                        reg |= 1;
-               record_dma (reg, v, addr, hpos, vpos, DMARECORD_CPU);
+               record_dma (reg, v, addr, hpos, vpos, DMARECORD_CPU_D);
                checknasty (hpos, vpos);
        }
 #endif
@@ -9979,7 +10003,7 @@ void wait_cpu_cycle_write_ce020 (uaecptr addr, int mode, uae_u32 v)
                        reg |= 2;
                else
                        reg |= 1;
-               record_dma (reg, v, addr, hpos, vpos, DMARECORD_CPU);
+               record_dma (reg, v, addr, hpos, vpos, DMARECORD_CPU_D);
                checknasty (hpos, vpos);
        }
 #endif
index 584f940fd5b37c43f9cd6f562b202aaf51c46063..e8e71c067d256e44beb579605748b8e6c276da77 100644 (file)
--- a/debug.cpp
+++ b/debug.cpp
@@ -57,7 +57,7 @@ int debugging;
 int exception_debugging;
 int no_trace_exceptions;
 int debug_copper = 0;
-int debug_dma = 0;
+int debug_dma = 0, debug_heatmap = 0;
 int debug_sprite_mask = 0xff;
 int debug_illegal = 0;
 uae_u64 debug_illegal_mask;
@@ -163,7 +163,8 @@ static TCHAR help[] = {
        _T("  dm                    Dump current address space map.\n")
        _T("  v <vpos> [<hpos>]     Show DMA data (accurate only in cycle-exact mode).\n")
        _T("                        v [-1 to -4] = enable visual DMA debugger.\n")
-       _T("  ?<value>              Hex ($ and 0x)/Bin (%)/Dec (!) converter.\n")
+       _T("  vh [<ratio> <lines>]  \"Heat map\"\n")
+       _T("  ?<value>              Hex ($ and 0x)/Bin (%)/Dec (!) converter and calculator.\n")
 #ifdef _WIN32
        _T("  x                     Close debugger.\n")
        _T("  xx                    Switch between console and GUI debugger.\n")
@@ -178,6 +179,80 @@ void debug_help (void)
        console_out (help);
 }
 
+
+struct mw_acc {
+       uae_u32 mask;
+       const TCHAR *name;
+};
+
+static const struct mw_acc memwatch_access_masks[] =
+{
+       { MW_MASK_ALL, _T("ALL") },
+       { MW_MASK_NONE, _T("NONE") },
+       { MW_MASK_ALL & ~(MW_MASK_CPU_I | MW_MASK_CPU_D_R | MW_MASK_CPU_D_W), _T("DMA") },
+
+       { MW_MASK_BLITTER_A | MW_MASK_BLITTER_B | MW_MASK_BLITTER_C | MW_MASK_BLITTER_D_N | MW_MASK_BLITTER_D_L | MW_MASK_BLITTER_D_F, _T("BLT") },
+       { MW_MASK_BLITTER_D_N | MW_MASK_BLITTER_D_L | MW_MASK_BLITTER_D_F, _T("BLTD") },
+
+       { MW_MASK_AUDIO_0 | MW_MASK_AUDIO_1 | MW_MASK_AUDIO_2 | MW_MASK_AUDIO_3, _T("AUD") },
+
+       { MW_MASK_BPL_0 | MW_MASK_BPL_1 | MW_MASK_BPL_2 | MW_MASK_BPL_3 |
+               MW_MASK_BPL_4 | MW_MASK_BPL_5 | MW_MASK_BPL_6 | MW_MASK_BPL_7, _T("BPL") },
+
+       { MW_MASK_SPR_0 | MW_MASK_SPR_1 | MW_MASK_SPR_2 | MW_MASK_SPR_3 |
+               MW_MASK_SPR_4 | MW_MASK_SPR_5 | MW_MASK_SPR_6 | MW_MASK_SPR_7, _T("SPR") },
+
+       { MW_MASK_CPU_I | MW_MASK_CPU_D_R | MW_MASK_CPU_D_W, _T("CPU") },
+       { MW_MASK_CPU_D_R | MW_MASK_CPU_D_W, _T("CPUD") },
+       { MW_MASK_CPU_I, _T("CPUI") },
+       { MW_MASK_CPU_D_R, _T("CPUDR") },
+       { MW_MASK_CPU_D_W, _T("CPUDW") },
+
+       { MW_MASK_COPPER, _T("COP") },
+
+       { MW_MASK_BLITTER_A, _T("BLTA") },
+       { MW_MASK_BLITTER_B, _T("BLTB") },
+       { MW_MASK_BLITTER_C, _T("BLTC") },
+       { MW_MASK_BLITTER_D_N, _T("BLTDN") },
+       { MW_MASK_BLITTER_D_L, _T("BLTDL") },
+       { MW_MASK_BLITTER_D_F, _T("BLTDF") },
+
+       { MW_MASK_DISK, _T("DSK") },
+
+       { MW_MASK_AUDIO_0, _T("AUD0") },
+       { MW_MASK_AUDIO_1, _T("AUD1") },
+       { MW_MASK_AUDIO_2, _T("AUD2") },
+       { MW_MASK_AUDIO_3, _T("AUD3") },
+
+       { MW_MASK_BPL_0, _T("BPL0") },
+       { MW_MASK_BPL_1, _T("BPL1") },
+       { MW_MASK_BPL_2, _T("BPL2") },
+       { MW_MASK_BPL_3, _T("BPL3") },
+       { MW_MASK_BPL_4, _T("BPL4") },
+       { MW_MASK_BPL_5, _T("BPL5") },
+       { MW_MASK_BPL_6, _T("BPL6") },
+       { MW_MASK_BPL_7, _T("BPL7") },
+
+       { MW_MASK_SPR_0, _T("SPR0") },
+       { MW_MASK_SPR_1, _T("SPR1") },
+       { MW_MASK_SPR_2, _T("SPR2") },
+       { MW_MASK_SPR_3, _T("SPR3") },
+       { MW_MASK_SPR_4, _T("SPR4") },
+       { MW_MASK_SPR_5, _T("SPR5") },
+       { MW_MASK_SPR_6, _T("SPR6") },
+       { MW_MASK_SPR_7, _T("SPR7") },
+
+       { 0, NULL },
+};
+
+static void mw_help(void)
+{
+       for (int i = 0; memwatch_access_masks[i].mask; i++) {
+               console_out_f(_T("%s "), memwatch_access_masks[i].name);
+       }
+       console_out_f(_T("\n"));
+}
+
 static int debug_linecounter;
 #define MAX_LINECOUNTER 1000
 
@@ -1047,13 +1122,38 @@ STATIC_INLINE void putpixel (uae_u8 *buf, int bpp, int x, xcolnr c8)
 #define lc(x) ledcolor (x, xredcolors, xgreencolors, xbluecolors, NULL)
 
 static uae_u32 intlevc[] = { 0x000000, 0x444444, 0x008800, 0xffff00, 0x000088, 0x880000, 0xff0000, 0xffffff };
+static uae_u8 debug_colors_rgb[DMARECORD_MAX * 4];
+static uae_u32 debug_colors_l[DMARECORD_MAX];
+
+static void set_dbg_color(int index, uae_u8 r, uae_u8 g, uae_u8 b)
+{
+       debug_colors_rgb[index * 4 + 0] = r;
+       debug_colors_rgb[index * 4 + 1] = g;
+       debug_colors_rgb[index * 4 + 2] = b;
+       debug_colors_l[index] = lc((r << 16) | (g << 8) | (b << 0));
+}
+
+static void set_debug_colors(uae_u32 *xredcolors, uae_u32 *xgreencolors, uae_u32 *xbluescolors)
+{
+       set_dbg_color(0,                                                0x22, 0x22, 0x22);
+       set_dbg_color(DMARECORD_REFRESH,                0x44, 0x44, 0x44);
+       set_dbg_color(DMARECORD_CPU_D,                  0xa2, 0x53, 0x42);
+       set_dbg_color(DMARECORD_CPU_I,                  0xad, 0x98, 0xd6);
+       set_dbg_color(DMARECORD_COPPER,                 0xee, 0xee, 0x00);
+       set_dbg_color(DMARECORD_AUDIO,                  0xff, 0x00, 0x00);
+       set_dbg_color(DMARECORD_BLITTER,                0x00, 0x88, 0x88);
+       set_dbg_color(DMARECORD_BLITTER_FILL,   0x00, 0x88, 0xff);
+       set_dbg_color(DMARECORD_BLITTER_LINE,   0x00, 0xff, 0x00);
+       set_dbg_color(DMARECORD_BITPLANE,               0x00, 0x00, 0xff);
+       set_dbg_color(DMARECORD_SPRITE,                 0xff, 0x00, 0xff);
+       set_dbg_color(DMARECORD_DISK,                   0xff, 0xff, 0xff);
+}
 
-void debug_draw_cycles (uae_u8 *buf, int bpp, int line, int width, int height, uae_u32 *xredcolors, uae_u32 *xgreencolors, uae_u32 *xbluescolors)
+static void debug_draw_cycles (uae_u8 *buf, int bpp, int line, int width, int height, uae_u32 *xredcolors, uae_u32 *xgreencolors, uae_u32 *xbluescolors)
 {
        int y, x, xx, dx, xplus, yplus;
        struct dma_rec *dr;
        int t;
-       uae_u32 cc[DMARECORD_MAX];
 
        if (debug_dma >= 4)
                yplus = 2;
@@ -1076,25 +1176,13 @@ void debug_draw_cycles (uae_u8 *buf, int bpp, int line, int width, int height, u
 
        dx = width - xplus * ((maxhpos + 1) & ~1) - 16;
 
-       cc[0] = lc(0x222222);
-       cc[DMARECORD_REFRESH] = lc(0x444444);
-       cc[DMARECORD_CPU] = lc(0x888888);
-       cc[DMARECORD_COPPER] = lc(0xeeee00);
-       cc[DMARECORD_AUDIO] = lc(0xff0000);
-       cc[DMARECORD_BLITTER] = lc(0x008888);
-       cc[DMARECORD_BLITTER_FILL] = lc(0x0088ff);
-       cc[DMARECORD_BLITTER_LINE] = lc(0x00ff00);
-       cc[DMARECORD_BITPLANE] = lc(0x0000ff);
-       cc[DMARECORD_SPRITE] = lc(0xff00ff);
-       cc[DMARECORD_DISK] = lc(0xffffff);
-
        uae_s8 intlev = 0;
        for (x = 0; x < maxhpos; x++) {
-               uae_u32 c = cc[0];
+               uae_u32 c = debug_colors_l[0];
                xx = x * xplus + dx;
                dr = &dma_record[t][y * NR_DMA_REC_HPOS + x];
                if (dr->reg != 0xffff) {
-                       c = cc[dr->type];
+                       c = debug_colors_l[dr->type];
                }
                if (dr->intlev > intlev)
                        intlev = dr->intlev;
@@ -1108,25 +1196,319 @@ void debug_draw_cycles (uae_u8 *buf, int bpp, int line, int width, int height, u
        putpixel (buf, bpp, dx + 3, 0);
 }
 
-#define HEATMAP_COUNT 50
+#define HEATMAP_WIDTH 256
+#define HEATMAP_HEIGHT 256
+#define HEATMAP_COUNT 32
+#define HEATMAP_DIV 8
+static const int max_heatmap = 16 * 1048576; // 16M
+static uae_u32 *heatmap_debug_colors;
+
 static struct memory_heatmap *heatmap;
 struct memory_heatmap
 {
+       uae_u32 mask;
+       uae_u32 cpucnt;
        uae_u16 cnt;
        uae_u16 type;
 };
 
-static void memwatch_heatmap (uaecptr addr, int rwi, int size)
+static void debug_draw_heatmap(uae_u8 *buf, int bpp, int line, int width, int height, uae_u32 *xredcolors, uae_u32 *xgreencolors, uae_u32 *xbluescolors)
+{
+       struct memory_heatmap *mht = heatmap;
+       int dx = 16;
+       int y = line;
+
+       if (y < 0 || y >= HEATMAP_HEIGHT)
+               return;
+
+       mht += y * HEATMAP_WIDTH;
+
+       for (int x = 0; x < HEATMAP_WIDTH; x++) {
+               uae_u32 c = heatmap_debug_colors[mht->cnt * DMARECORD_MAX + mht->type];
+               //c = heatmap_debug_colors[(HEATMAP_COUNT - 1) * DMARECORD_MAX + DMARECORD_CPU_I];
+               int xx = x + dx;
+               putpixel(buf, bpp, xx, c);
+               if (mht->cnt > 0)
+                       mht->cnt--;
+               mht++;
+       }
+}
+
+void debug_draw(uae_u8 *buf, int bpp, int line, int width, int height, uae_u32 *xredcolors, uae_u32 *xgreencolors, uae_u32 *xbluescolors)
+{
+       if (!heatmap_debug_colors) {
+               heatmap_debug_colors = xcalloc(uae_u32, DMARECORD_MAX * HEATMAP_COUNT);
+               set_debug_colors(xredcolors, xgreencolors, xbluecolors);
+               for (int i = 0; i < HEATMAP_COUNT; i++) {
+                       uae_u32 *cp = heatmap_debug_colors + i * DMARECORD_MAX;
+                       for (int j = 0; j < DMARECORD_MAX; j++) {
+                               uae_u8 r = debug_colors_rgb[j * 4 + 0];
+                               uae_u8 g = debug_colors_rgb[j * 4 + 1];
+                               uae_u8 b = debug_colors_rgb[j * 4 + 2];
+                               r = r * i / HEATMAP_COUNT;
+                               g = g * i / HEATMAP_COUNT;
+                               b = b * i / HEATMAP_COUNT;
+                               cp[j] = lc((r << 16) | (g << 8) | (b << 0));
+                       }
+               }
+       }
+
+       if (heatmap) {
+               debug_draw_heatmap(buf, bpp, line, width, height, xredcolors, xgreencolors, xbluecolors);
+       } else {
+               debug_draw_cycles(buf, bpp, line, width, height, xredcolors, xgreencolors, xbluecolors);
+       }
+}
+
+struct heatmapstore
+{
+       TCHAR *s;
+       double v;
+};
+
+static void heatmap_stats(TCHAR **c)
+{
+       int range = 95;
+       int maxlines = 30;
+       double max;
+       int maxcnt;
+       uae_u32 mask = MW_MASK_CPU_I;
+       const TCHAR *maskname = NULL;
+
+       if (more_params(c)) {
+               if (**c == 'c' && peek_next_char(c) == 0) {
+                       for (int i = 0; i < max_heatmap / HEATMAP_DIV; i++) {
+                               struct memory_heatmap *hm = &heatmap[i];
+                               memset(hm, 0, sizeof(struct memory_heatmap));
+                       }
+                       console_out(_T("heatmap data cleared\n"));
+                       return;
+               }
+               if (!isdigit(peek_next_char(c))) {
+                       TCHAR str[100];
+                       if (next_string(c, str, sizeof str / sizeof (TCHAR), true)) {
+                               for (int j = 0; memwatch_access_masks[j].mask; j++) {
+                                       if (!_tcsicmp(str, memwatch_access_masks[j].name)) {
+                                               mask = memwatch_access_masks[j].mask;
+                                               maskname = memwatch_access_masks[j].name;
+                                               console_out_f(_T("Mask %08x Name %s\n"), mask, maskname);
+                                               break;
+                                       }
+                               }
+                       }
+                       if (more_params(c)) {
+                               maxlines = readint(c);
+                       }
+               } else {
+                       range = readint(c);
+                       if (more_params(c)) {
+                               maxlines = readint(c);
+                       }
+               }
+       }
+       if (maxlines <= 0)
+               maxlines = 10000;
+
+       if (mask != MW_MASK_CPU_I) {
+
+               int found = -1;
+               int firstaddress = 0;
+               for (int lines = 0; lines < maxlines; lines++) {
+
+                       for (; firstaddress < max_heatmap / HEATMAP_DIV; firstaddress++) {
+                               struct memory_heatmap *hm = &heatmap[firstaddress];
+                               if (hm->mask & mask)
+                                       break;
+                       }
+
+                       if (firstaddress == max_heatmap / HEATMAP_DIV)
+                               return;
+
+                       int lastaddress;
+                       for (lastaddress = firstaddress; lastaddress < max_heatmap / HEATMAP_DIV; lastaddress++) {
+                               struct memory_heatmap *hm = &heatmap[lastaddress];
+                               if (!(hm->mask & mask))
+                                       break;
+                       }
+                       lastaddress--;
+
+                       console_out_f(_T("%03d: %08x - %08x %08x (%d) %s\n"), 
+                               lines,
+                               firstaddress * HEATMAP_DIV, lastaddress * HEATMAP_DIV + HEATMAP_DIV - 1,
+                               lastaddress * HEATMAP_DIV - firstaddress * HEATMAP_DIV + HEATMAP_DIV - 1,
+                               lastaddress * HEATMAP_DIV - firstaddress * HEATMAP_DIV + HEATMAP_DIV - 1, 
+                               maskname);
+
+                       firstaddress = lastaddress + 1;
+               }
+
+       } else {
+#define MAX_HEATMAP_LINES 1000
+               struct heatmapstore linestore[MAX_HEATMAP_LINES] = { 0 };
+               int storecnt = 0;
+               uae_u32 maxlimit = 0xffffffff;
+
+               max = 0;
+               maxcnt = 0;
+               for (int i = 0; i < max_heatmap / HEATMAP_DIV; i++) {
+                       struct memory_heatmap *hm = &heatmap[i];
+                       if (hm->cpucnt > 0) {
+                               max += hm->cpucnt;
+                               maxcnt++;
+                       }
+               }
+
+               if (!maxcnt) {
+                       console_out(_T("No CPU accesses found\n"));
+                       return;
+               }
+
+               for (int lines = 0; lines < maxlines; lines++) {
+
+                       int found = -1;
+                       int foundcnt = 0;
+
+                       for (int i = 0; i < max_heatmap / HEATMAP_DIV; i++) {
+                               struct memory_heatmap *hm = &heatmap[i];
+                               if (hm->cpucnt > 0 && hm->cpucnt > foundcnt && hm->cpucnt < maxlimit) {
+                                       foundcnt = hm->cpucnt;
+                                       found = i;
+                               }
+                       }
+                       if (found < 0)
+                               break;
+
+                       int totalcnt = 0;
+                       int cntrange = foundcnt * range / 100;
+                       if (cntrange <= 0)
+                               cntrange = 1;
+
+                       int lastaddress;
+                       for (lastaddress = found; lastaddress < max_heatmap / HEATMAP_DIV; lastaddress++) {
+                               struct memory_heatmap *hm = &heatmap[lastaddress];
+                               if (hm->cpucnt == 0 || hm->cpucnt < cntrange || hm->cpucnt >= maxlimit)
+                                       break;
+                               totalcnt += hm->cpucnt;
+                       }
+                       lastaddress--;
+
+                       int firstaddress;
+                       for (firstaddress = found - 1; firstaddress >= 0; firstaddress--) {
+                               struct memory_heatmap *hm = &heatmap[firstaddress];
+                               if (hm->cpucnt == 0 || hm->cpucnt < cntrange || hm->cpucnt >= maxlimit)
+                                       break;
+                               totalcnt += hm->cpucnt;
+                       }
+                       firstaddress--;
+
+                       firstaddress *= HEATMAP_DIV;
+                       lastaddress *= HEATMAP_DIV;
+
+                       TCHAR tmp[100];
+                       double pct = totalcnt / max * 100.0;
+                       _stprintf(tmp, _T("%03d: %08x - %08x %08x (%d) %.5f%%\n"), lines + 1,
+                               firstaddress, lastaddress + HEATMAP_DIV - 1,
+                               lastaddress - firstaddress + HEATMAP_DIV - 1,
+                               lastaddress - firstaddress + HEATMAP_DIV - 1,
+                               pct);
+                       linestore[storecnt].s = my_strdup(tmp);
+                       linestore[storecnt].v = pct;
+
+                       storecnt++;
+                       if (storecnt >= MAX_HEATMAP_LINES)
+                               break;
+
+                       maxlimit = foundcnt;
+               }
+
+               for (int lines1 = 0; lines1 < storecnt; lines1++) {
+                       for (int lines2 = lines1 + 1; lines2 < storecnt; lines2++) {
+                               if (linestore[lines1].v < linestore[lines2].v) {
+                                       struct heatmapstore hms;
+                                       memcpy(&hms, &linestore[lines1], sizeof(struct heatmapstore));
+                                       memcpy(&linestore[lines1], &linestore[lines2], sizeof(struct heatmapstore));
+                                       memcpy(&linestore[lines2], &hms, sizeof(struct heatmapstore));
+                               }
+                       }
+               }
+               for (int lines1 = 0; lines1 < storecnt; lines1++) {
+                       console_out(linestore[lines1].s);
+                       xfree(linestore[lines1].s);
+               }
+
+       }
+
+}
+
+static void free_heatmap(void)
 {
+       xfree(heatmap);
+       heatmap = NULL;
+       debug_heatmap = 0;
 }
 
-static void record_dma_heatmap (uaecptr addr, int type)
+static void init_heatmap(void)
 {
-       if (addr >= 0x01000000 || !heatmap)
+       if (!heatmap)
+               heatmap = xcalloc(struct memory_heatmap, max_heatmap / HEATMAP_DIV);
+}
+
+static void memwatch_heatmap (uaecptr addr, int rwi, int size, uae_u32 accessmask)
+{
+       if (addr >= max_heatmap || !heatmap)
                return;
-       struct memory_heatmap *hp = &heatmap[addr / 2];
-       hp->cnt = HEATMAP_COUNT;
-       hp->type = type;
+       struct memory_heatmap *hm = &heatmap[addr / HEATMAP_DIV];
+       if (accessmask & MW_MASK_CPU_I) {
+               hm->cpucnt++;
+       }
+       hm->cnt = HEATMAP_COUNT - 1;
+       int type = 0;
+       for (int i = 0; i < 32; i++) {
+               if (accessmask & (1 << i)) {
+                       switch (1 << i)
+                       {
+                               case MW_MASK_BPL_0:
+                               case MW_MASK_BPL_1:
+                               case MW_MASK_BPL_2:
+                               case MW_MASK_BPL_3:
+                               case MW_MASK_BPL_4:
+                               case MW_MASK_BPL_5:
+                               case MW_MASK_BPL_6:
+                               case MW_MASK_BPL_7:
+                               type = DMARECORD_BITPLANE;
+                               break;
+                               case MW_MASK_AUDIO_0:
+                               case MW_MASK_AUDIO_1:
+                               case MW_MASK_AUDIO_2:
+                               case MW_MASK_AUDIO_3:
+                               type = DMARECORD_AUDIO;
+                               break;
+                               case MW_MASK_BLITTER_A:
+                               case MW_MASK_BLITTER_B:
+                               case MW_MASK_BLITTER_C:
+                               case MW_MASK_BLITTER_D_N:
+                               case MW_MASK_BLITTER_D_F:
+                               case MW_MASK_BLITTER_D_L:
+                               type = DMARECORD_BLITTER;
+                               break;
+                               case MW_MASK_COPPER:
+                               type = DMARECORD_COPPER;
+                               break;
+                               case MW_MASK_DISK:
+                               type = DMARECORD_DISK;
+                               break;
+                               case MW_MASK_CPU_I:
+                               type = DMARECORD_CPU_I;
+                               break;
+                               case MW_MASK_CPU_D_R:
+                               case MW_MASK_CPU_D_W:
+                               type = DMARECORD_CPU_D;
+                               break;
+                       }
+               }
+       }
+       hm->type = type;
+       hm->mask |= accessmask;
 }
 
 void record_dma_event (int evt, int hpos, int vpos)
@@ -1145,8 +1527,6 @@ struct dma_rec *record_dma (uae_u16 reg, uae_u16 dat, uae_u32 addr, int hpos, in
 {
        struct dma_rec *dr;
 
-       if (!heatmap)
-               heatmap = xcalloc (struct memory_heatmap, 16 * 1024 * 1024 / 2);
        if (!dma_record[0]) {
                dma_record[0] = xmalloc (struct dma_rec, NR_DMA_REC_HPOS * NR_DMA_REC_VPOS);
                dma_record[1] = xmalloc (struct dma_rec, NR_DMA_REC_HPOS * NR_DMA_REC_VPOS);
@@ -1156,8 +1536,6 @@ struct dma_rec *record_dma (uae_u16 reg, uae_u16 dat, uae_u32 addr, int hpos, in
        if (hpos >= NR_DMA_REC_HPOS || vpos >= NR_DMA_REC_VPOS)
                return NULL;
 
-       record_dma_heatmap (addr, type);
-
        dr = &dma_record[dma_record_toggle][vpos * NR_DMA_REC_HPOS + hpos];
        if (dr->reg != 0xffff) {
                write_log (_T("DMA conflict: v=%d h=%d OREG=%04X NREG=%04X\n"), vpos, hpos, dr->reg, reg);
@@ -1768,7 +2146,6 @@ static addrbank **debug_mem_banks;
 static addrbank *debug_mem_area;
 struct memwatch_node mwnodes[MEMWATCH_TOTAL];
 static struct memwatch_node mwhit;
-static int addressspaceheatmap;
 
 static uae_u8 *illgdebug, *illghdebug;
 static int illgdebug_break;
@@ -2088,8 +2465,8 @@ static int memwatch_func (uaecptr addr, int rwi, int size, uae_u32 *valp, uae_u3
        if (illgdebug)
                illg_debug_do (addr, rwi, size, val);
 
-       if (addressspaceheatmap)
-               memwatch_heatmap (addr, rwi, size);
+       if (heatmap)
+               memwatch_heatmap (addr, rwi, size, accessmask);
 
        addr = munge24 (addr);
        if (smc_table && (rwi >= 2))
@@ -2272,7 +2649,7 @@ static uae_u32 REGPARAM2 debug_lget (uaecptr addr)
        uae_u32 off = debug_mem_off (&addr);
        uae_u32 v;
        v = debug_mem_banks[off]->lget (addr);
-       memwatch_func (addr, 1, 4, &v, MW_MASK_CPU, 0);
+       memwatch_func (addr, 1, 4, &v, MW_MASK_CPU_D_R, 0);
        return v;
 }
 static uae_u32 REGPARAM2 mmu_lgeti (uaecptr addr)
@@ -2297,7 +2674,7 @@ static uae_u32 REGPARAM2 debug_wget (uaecptr addr)
        int off = debug_mem_off (&addr);
        uae_u32 v;
        v = debug_mem_banks[off]->wget (addr);
-       memwatch_func (addr, 1, 2, &v, MW_MASK_CPU, 0);
+       memwatch_func (addr, 1, 2, &v, MW_MASK_CPU_D_R, 0);
        return v;
 }
 static uae_u32 REGPARAM2 debug_bget (uaecptr addr)
@@ -2305,7 +2682,7 @@ static uae_u32 REGPARAM2 debug_bget (uaecptr addr)
        int off = debug_mem_off (&addr);
        uae_u32 v;
        v = debug_mem_banks[off]->bget (addr);
-       memwatch_func (addr, 1, 1, &v, MW_MASK_CPU, 0);
+       memwatch_func (addr, 1, 1, &v, MW_MASK_CPU_D_R, 0);
        return v;
 }
 static uae_u32 REGPARAM2 debug_lgeti (uaecptr addr)
@@ -2313,7 +2690,7 @@ static uae_u32 REGPARAM2 debug_lgeti (uaecptr addr)
        int off = debug_mem_off (&addr);
        uae_u32 v;
        v = debug_mem_banks[off]->lgeti (addr);
-       memwatch_func (addr, 4, 4, &v, MW_MASK_CPU, 0);
+       memwatch_func (addr, 4, 4, &v, MW_MASK_CPU_I, 0);
        return v;
 }
 static uae_u32 REGPARAM2 debug_wgeti (uaecptr addr)
@@ -2321,25 +2698,25 @@ static uae_u32 REGPARAM2 debug_wgeti (uaecptr addr)
        int off = debug_mem_off (&addr);
        uae_u32 v;
        v = debug_mem_banks[off]->wgeti (addr);
-       memwatch_func (addr, 4, 2, &v, MW_MASK_CPU, 0);
+       memwatch_func (addr, 4, 2, &v, MW_MASK_CPU_I, 0);
        return v;
 }
 static void REGPARAM2 debug_lput (uaecptr addr, uae_u32 v)
 {
        int off = debug_mem_off (&addr);
-       if (memwatch_func (addr, 2, 4, &v, MW_MASK_CPU, 0))
+       if (memwatch_func (addr, 2, 4, &v, MW_MASK_CPU_D_W, 0))
                debug_mem_banks[off]->lput (addr, v);
 }
 static void REGPARAM2 debug_wput (uaecptr addr, uae_u32 v)
 {
        int off = debug_mem_off (&addr);
-       if (memwatch_func (addr, 2, 2, &v, MW_MASK_CPU, 0))
+       if (memwatch_func (addr, 2, 2, &v, MW_MASK_CPU_D_W, 0))
                debug_mem_banks[off]->wput (addr, v);
 }
 static void REGPARAM2 debug_bput (uaecptr addr, uae_u32 v)
 {
        int off = debug_mem_off (&addr);
-       if (memwatch_func (addr, 2, 1, &v, MW_MASK_CPU, 0))
+       if (memwatch_func (addr, 2, 1, &v, MW_MASK_CPU_D_W, 0))
                debug_mem_banks[off]->bput (addr, v);
 }
 static int REGPARAM2 debug_check (uaecptr addr, uae_u32 size)
@@ -2388,40 +2765,40 @@ static void debug_putlpeek (uaecptr addr, uae_u32 v)
 {
        if (!memwatch_enabled)
                return;
-       memwatch_func (addr, 2, 4, &v, MW_MASK_CPU, 0);
+       memwatch_func (addr, 2, 4, &v, MW_MASK_CPU_D_W, 0);
 }
 void debug_wputpeek (uaecptr addr, uae_u32 v)
 {
        if (!memwatch_enabled)
                return;
-       memwatch_func (addr, 2, 2, &v, MW_MASK_CPU, 0);
+       memwatch_func (addr, 2, 2, &v, MW_MASK_CPU_D_W, 0);
 }
 void debug_bputpeek (uaecptr addr, uae_u32 v)
 {
        if (!memwatch_enabled)
                return;
-       memwatch_func (addr, 2, 1, &v, MW_MASK_CPU, 0);
+       memwatch_func (addr, 2, 1, &v, MW_MASK_CPU_D_W, 0);
 }
 void debug_bgetpeek (uaecptr addr, uae_u32 v)
 {
        uae_u32 vv = v;
        if (!memwatch_enabled)
                return;
-       memwatch_func (addr, 1, 1, &vv, MW_MASK_CPU, 0);
+       memwatch_func (addr, 1, 1, &vv, MW_MASK_CPU_D_R, 0);
 }
 void debug_wgetpeek (uaecptr addr, uae_u32 v)
 {
        uae_u32 vv = v;
        if (!memwatch_enabled)
                return;
-       memwatch_func (addr, 1, 2, &vv, MW_MASK_CPU, 0);
+       memwatch_func (addr, 1, 2, &vv, MW_MASK_CPU_D_R, 0);
 }
 void debug_lgetpeek (uaecptr addr, uae_u32 v)
 {
        uae_u32 vv = v;
        if (!memwatch_enabled)
                return;
-       memwatch_func (addr, 1, 4, &vv, MW_MASK_CPU, 0);
+       memwatch_func (addr, 1, 4, &vv, MW_MASK_CPU_D_R, 0);
 }
 
 struct membank_store
@@ -2623,54 +3000,6 @@ addrbank *get_mem_bank_real(uaecptr addr)
        return ab;
 }
 
-struct mw_acc
-{
-       uae_u32 mask;
-       const TCHAR *name;
-};
-
-static const struct mw_acc memwatch_access_masks[] =
-{
-       { MW_MASK_ALL, _T("ALL") },
-       { MW_MASK_NONE, _T("NONE") },
-       { MW_MASK_ALL & ~MW_MASK_CPU, _T("DMA") },
-       { MW_MASK_BLITTER_A | MW_MASK_BLITTER_B | MW_MASK_BLITTER_C | MW_MASK_BLITTER_D, _T("BLT") },
-       { MW_MASK_AUDIO_0 | MW_MASK_AUDIO_1 | MW_MASK_AUDIO_2 | MW_MASK_AUDIO_3, _T("AUD") },
-       { MW_MASK_BPL_0 | MW_MASK_BPL_1 | MW_MASK_BPL_2 | MW_MASK_BPL_3 |
-         MW_MASK_BPL_4 | MW_MASK_BPL_5 | MW_MASK_BPL_6 | MW_MASK_BPL_7 , _T("BPL") },
-       { MW_MASK_SPR_0 | MW_MASK_SPR_1 | MW_MASK_SPR_2 | MW_MASK_SPR_3 |
-         MW_MASK_SPR_4 | MW_MASK_SPR_5 | MW_MASK_SPR_6 | MW_MASK_SPR_7, _T("SPR") },
-
-       { MW_MASK_CPU, _T("CPU") },
-       { MW_MASK_COPPER, _T("COP") },
-       { MW_MASK_BLITTER_A, _T("BLTA") },
-       { MW_MASK_BLITTER_B, _T("BLTB") },
-       { MW_MASK_BLITTER_C, _T("BLTC") },
-       { MW_MASK_BLITTER_D, _T("BLTD") },
-       { MW_MASK_DISK, _T("DSK") },
-       { MW_MASK_AUDIO_0, _T("AUD0") },
-       { MW_MASK_AUDIO_1, _T("AUD1") },
-       { MW_MASK_AUDIO_2, _T("AUD2") },
-       { MW_MASK_AUDIO_3, _T("AUD3") },
-       { MW_MASK_BPL_0, _T("BPL0") },
-       { MW_MASK_BPL_1, _T("BPL1") },
-       { MW_MASK_BPL_2, _T("BPL2") },
-       { MW_MASK_BPL_3, _T("BPL3") },
-       { MW_MASK_BPL_4, _T("BPL4") },
-       { MW_MASK_BPL_5, _T("BPL5") },
-       { MW_MASK_BPL_6, _T("BPL6") },
-       { MW_MASK_BPL_7, _T("BPL7") },
-       { MW_MASK_SPR_0, _T("SPR0") },
-       { MW_MASK_SPR_1, _T("SPR1") },
-       { MW_MASK_SPR_2, _T("SPR2") },
-       { MW_MASK_SPR_3, _T("SPR3") },
-       { MW_MASK_SPR_4, _T("SPR4") },
-       { MW_MASK_SPR_5, _T("SPR5") },
-       { MW_MASK_SPR_6, _T("SPR6") },
-       { MW_MASK_SPR_7, _T("SPR7") },
-       { 0, NULL },
-};
-
 static const TCHAR *getsizechar (int size)
 {
        if (size == 4)
@@ -2865,7 +3194,7 @@ static void memwatch (TCHAR **c)
                }
        }
        if (!mwn->access_mask)
-               mwn->access_mask = MW_MASK_CPU;
+               mwn->access_mask = MW_MASK_CPU_D_R | MW_MASK_CPU_D_W | MW_MASK_CPU_I;
        if (mwn->frozen && mwn->rwi == 0)
                mwn->rwi = 3;
        memwatch_setup ();
@@ -4278,7 +4607,7 @@ static bool debug_line (TCHAR *input)
 
        switch (cmd)
        {
-               case 'c': dumpcia (); dumpdisk (); dumpcustom (); break;
+               case 'c': dumpcia (); dumpdisk (_T("DEBUG")); dumpcustom (); break;
                case 'i':
                {
                        if (*inptr == 'l') {
@@ -4574,15 +4903,57 @@ static bool debug_line (TCHAR *input)
                case 'V':
                        {
                                int v1 = vpos, v2 = 0;
-                               if (more_params (&inptr))
-                                       v1 = readint (&inptr);
-                               if (more_params (&inptr))
-                                       v2 = readint (&inptr);
-                               if (debug_dma) {
-                                       decode_dma_record (v2, v1, cmd == 'v', false);
+                               if (*inptr == 'h') {
+                                       inptr++;
+                                       if (more_params(&inptr) && *inptr == '?') {
+                                               mw_help();
+                                       } else if (!heatmap) {
+                                               debug_heatmap = 1;
+                                               init_heatmap();
+                                               if (more_params(&inptr)) {
+                                                       v1 = readint(&inptr);
+                                                       if (v1 < 0) {
+                                                               debug_heatmap = 2;
+                                                       }
+                                               }
+                                               TCHAR buf[200];
+                                               TCHAR *pbuf;
+                                               _stprintf(buf, _T("0 dff000 200 NONE"));
+                                               pbuf = buf;
+                                               memwatch(&pbuf);
+                                               _stprintf(buf, _T("1 0 %08x NONE"), currprefs.chipmem_size);
+                                               pbuf = buf;
+                                               memwatch(&pbuf);
+                                               if (currprefs.bogomem_size) {
+                                                       _stprintf(buf, _T("2 c00000 %08x NONE"), currprefs.bogomem_size);
+                                                       pbuf = buf;
+                                                       memwatch(&pbuf);
+                                               }
+                                               console_out_f(_T("Heatmap enabled\n"));
+                                       } else {
+                                               if (*inptr == 'd') {
+                                                       console_out_f(_T("Heatmap disabled\n"));
+                                                       free_heatmap();
+                                               } else {
+                                                       heatmap_stats(&inptr);
+                                               }
+                                       }
                                } else {
-                                       debug_dma = v1 < 0 ? -v1 : 1;
-                                       console_out_f (_T("DMA debugger enabled, mode=%d.\n"), debug_dma);
+                                       if (more_params(&inptr) && *inptr == '?') {
+                                               mw_help();
+                                       } else {
+                                               free_heatmap();
+                                               if (more_params (&inptr))
+                                                       v1 = readint (&inptr);
+                                               if (more_params (&inptr))
+                                                       v2 = readint (&inptr);
+                                               if (debug_dma) {
+                                                       decode_dma_record (v2, v1, cmd == 'v', false);
+                                               } else {
+                                                       debug_dma = v1 < 0 ? -v1 : 1;
+                                                       console_out_f (_T("DMA debugger enabled, mode=%d.\n"), debug_dma);
+                                               }
+                                       }
                                }
                        }
                        break;
index f3342b0b5a755a4e9b5808b436cce61f73aa594c..2a82df1672f196ac68b9ba45c131d29f9d13eca4 100644 (file)
@@ -99,6 +99,7 @@ void devices_reset(int hardreset)
 #ifdef AUTOCONFIG
        expamem_reset ();
 #endif
+       uae_int_requested = 0;
 }
 
 
@@ -285,6 +286,7 @@ void reset_all_systems (void)
        native2amiga_reset ();
        dongle_reset ();
        sampler_init ();
+       uae_int_requested = 0;
 }
 
 void do_leave_program (void)
index 7a9ed264637d2bd201d8459f319eba8fef4d91e1..c860c6a16cfd15fea1b875ee8aaca5e23591eb98 100644 (file)
--- a/disk.cpp
+++ b/disk.cpp
@@ -1493,7 +1493,7 @@ static void drive_step (drive * drv, int step_direction)
 #endif
        }
        rand_shifter (drv);
-       if (disk_debug_logging > 1)
+       if (disk_debug_logging > 2)
                write_log (_T(" ->step %d"), drv->cyl);
 }
 
@@ -1535,7 +1535,7 @@ static void drive_motor (drive * drv, bool off)
                if (isfloppysound (drv))
                        driveclick_motor (drv - floppy, drv->dskready_down_time == 0 ? 2 : 1);
 #endif
-               if (disk_debug_logging > 1)
+               if (disk_debug_logging > 2)
                        write_log (_T(" ->motor on"));
        }
        if (!drv->motoroff && off) {
@@ -1547,7 +1547,7 @@ static void drive_motor (drive * drv, bool off)
 #ifdef DEBUG_DRIVE_ID
                write_log (_T("drive_motor: Selected DF%d: reset id shift reg.\n"),drv-floppy);
 #endif
-               if (disk_debug_logging > 1)
+               if (disk_debug_logging > 2)
                        write_log (_T(" ->motor off"));
                if (currprefs.cpu_model <= 68010 && currprefs.m68k_speed == 0) {
                        drv->motordelay = 1;
@@ -1993,7 +1993,7 @@ static void drive_fill_bigbuf (drive * drv, int force)
                        uae_u8 *data = (uae_u8 *) mfm;
                        *mfm = 256 * *data + *(data + 1);
                }
-               if (disk_debug_logging > 1)
+               if (disk_debug_logging > 2)
                        write_log (_T("rawtrack %d image offset=%x\n"), tr, ti->offs);
        }
        drv->buffered_side = side;
@@ -2909,7 +2909,7 @@ void DISK_select (uae_u8 data)
        fetch_DISK_select (data);
        step_pulse = data & 1;
 
-       if (disk_debug_logging > 1) {
+       if (disk_debug_logging > 2) {
                if (velvet) {
                        write_log (_T("%08X %02X->%02X %s drvmask=%x"), M68K_GETPC, prev_data, data, tobin(data), selected ^ 3);
                } else {
@@ -2932,14 +2932,14 @@ void DISK_select (uae_u8 data)
                        for (dr = 0; dr < 4; dr++) {
                                if (floppy[dr].indexhackmode > 1 && !((selected | disabled) & (1 << dr))) {
                                        floppy[dr].indexhack = 1;
-                                       if (disk_debug_logging > 1)
+                                       if (disk_debug_logging > 2)
                                                write_log (_T(" indexhack!"));
                                }
                        }
                }
        }
 
-       if (disk_debug_logging > 1) {
+       if (disk_debug_logging > 2) {
                if (velvet) {
                        write_log (_T(" %d%d "), (selected & 1) ? 0 : 1, (selected & 2) ? 0 : 1);
                        if ((prev_data & 0x08) != (data & 0x08))
@@ -2967,7 +2967,7 @@ void DISK_select (uae_u8 data)
 
        // step goes high and drive was selected when step pulse changes: step
        if (prev_step != step_pulse) {
-               if (disk_debug_logging > 1)
+               if (disk_debug_logging > 2)
                        write_log (_T(" dskstep %d "), step_pulse);
                prev_step = step_pulse;
                if (prev_step && !savestate_state) {
@@ -3030,7 +3030,7 @@ void DISK_select (uae_u8 data)
                update_drive_gui (dr, false);
        }
        prev_data = data;
-       if (disk_debug_logging > 1)
+       if (disk_debug_logging > 2)
                write_log (_T("\n"));
 }
 
@@ -3045,7 +3045,7 @@ uae_u8 DISK_status_ciab(uae_u8 st)
                                        st &= ~0x80;
                        }
                }
-               if (disk_debug_logging > 1) {
+               if (disk_debug_logging > 2) {
                        write_log(_T("DISK_STATUS_CIAB %08x %02x\n"), M68K_GETPC, st);
                }
        }
@@ -3067,7 +3067,7 @@ uae_u8 DISK_status_ciaa(void)
                                        st &= ~0x10;
                        }
                }
-               if (disk_debug_logging > 1) {
+               if (disk_debug_logging > 2) {
                        write_log(_T("DISK_STATUS_CIAA %08x %02x\n"), M68K_GETPC, st);
                }
                return st;
@@ -3145,7 +3145,7 @@ STATIC_INLINE uae_u32 getonebit (uae_u16 * mfmbuf, int mfmpos)
        return (buf[0] & (1 << (15 - (mfmpos & 15)))) ? 1 : 0;
 }
 
-void dumpdisk (void)
+void dumpdisk (const TCHAR *name)
 {
        int i, j, k;
        uae_u16 w;
@@ -3153,17 +3153,20 @@ void dumpdisk (void)
        for (i = 0; i < MAX_FLOPPY_DRIVES; i++) {
                drive *drv = &floppy[i];
                if (!(disabled & (1 << i))) {
-                       console_out_f (_T("Drive %d: motor %s cylinder %2d sel %s %s mfmpos %d/%d\n"),
-                               i, drv->motoroff ? _T("off") : _T(" on"), drv->cyl, (selected & (1 << i)) ? _T("no") : _T("yes"),
+                       console_out_f (_T("%s: drive %d motor %s cylinder %2d sel %s %s mfmpos %d/%d\n"),
+                               name, i, drv->motoroff ? _T("off") : _T(" on"), drv->cyl, (selected & (1 << i)) ? _T("no") : _T("yes"),
                                drive_writeprotected (drv) ? _T("ro") : _T("rw"), drv->mfmpos, drv->tracklen);
                        if (drv->motoroff == 0) {
-                               w = word;
-                               for (j = 0; j < 15; j++) {
-                                       console_out_f (_T("%04X "), w);
+                               w = 0;
+                               for (j = -4; j < 13; j++) {
                                        for (k = 0; k < 16; k++) {
+                                               int pos = drv->mfmpos + j * 16 + k;
+                                               if (pos < 0)
+                                                       pos += drv->tracklen;
                                                w <<= 1;
-                                               w |= getonebit (drv->bigmfmbuf, drv->mfmpos + j * 16 + k);
+                                               w |= getonebit (drv->bigmfmbuf, pos);
                                        }
+                                       console_out_f(_T("%04X%c"), w, j == -1 ? '|' : ' ');
                                }
                                console_out (_T("\n"));
                        }
@@ -3179,6 +3182,7 @@ static void disk_dmafinished (void)
        longwritemode = 0;
        dskdmaen = DSKDMA_OFF;
        dsklength = 0;
+       dsklen = 0;
        if (disk_debug_logging > 0) {
                int dr;
                write_log (_T("disk dma finished %08X MFMpos="), dskpt);
@@ -3480,13 +3484,24 @@ static void wordsync_detected(bool startup)
 {
        dsksync_cycles = get_cycles() + WORDSYNC_TIME * CYCLE_UNIT;
        if (dskdmaen != DSKDMA_OFF) {
-               if (disk_debug_logging && dma_enable == 0)
-                       write_log(_T("Sync match %04x\n"), dsksync);
+               if (disk_debug_logging && dma_enable == 0) {
+                       int pos = -1;
+                       for (int i = 0; i < MAX_FLOPPY_DRIVES; i++) {
+                               drive *drv = &floppy[i];
+                               if (!(disabled & (1 << i)) && !drv->motoroff) {
+                                       pos = drv->mfmpos;
+                                       break;
+                               }
+                       }
+                       write_log(_T("Sync match %04x mfmpos %d enable %d wordsync %d\n"), dsksync, pos, dma_enable, (adkcon & 0x0400) != 0);
+                       if (disk_debug_logging > 1)
+                               dumpdisk(_T("SYNC"));
+               }
                if (!startup)
                        dma_enable = 1;
                INTREQ(0x8000 | 0x1000);
        }
-       if (adkcon & 0x400) {
+       if (adkcon & 0x0400) {
                bitoffset = 15;
        }
 }
@@ -3516,7 +3531,6 @@ static void disk_doupdate_read (drive * drv, int floppybits)
                        updatetrackspeed (drv, drv->mfmpos);
                word <<= 1;
 
-
                if (!drive_empty (drv)) {
                        if (unformatted (drv))
                                word |= (uaerand () & 0x1000) ? 1 : 0;
@@ -3531,7 +3545,7 @@ static void disk_doupdate_read (drive * drv, int floppybits)
                drv->mfmpos++;
                drv->mfmpos %= drv->tracklen;
                if (drv->mfmpos == drv->indexoffset) {
-                       if (disk_debug_logging > 1 && drv->indexhack)
+                       if (disk_debug_logging > 2 && drv->indexhack)
                                write_log (_T("indexhack cleared\n"));
                        drv->indexhack = 0;
                        do_disk_index ();
@@ -3548,7 +3562,7 @@ static void disk_doupdate_read (drive * drv, int floppybits)
                                drv->mfmpos++;
                                drv->mfmpos %= drv->tracklen;
                                if (drv->mfmpos == drv->indexoffset) {
-                                       if (disk_debug_logging > 1 && drv->indexhack)
+                                       if (disk_debug_logging > 2 && drv->indexhack)
                                                write_log (_T("indexhack cleared\n"));
                                        drv->indexhack = 0;
                                        do_disk_index ();
@@ -3588,13 +3602,17 @@ uae_u16 DSKBYTR (int hpos)
        DISK_update (hpos);
        v = dskbytr_val;
        dskbytr_val &= ~0x8000;
-       if (word == dsksync && cycles_in_range (dsksync_cycles))
+       if (word == dsksync && cycles_in_range (dsksync_cycles)) {
                v |= 0x1000;
+               if (disk_debug_logging > 1) {
+                       dumpdisk(_T("DSKBYTR SYNC"));
+               }
+       }
        if (dskdmaen != DSKDMA_OFF && dmaen (DMA_DISK))
                v |= 0x4000;
        if (dsklen & 0x4000)
                v |= 0x2000;
-       if (disk_debug_logging > 1)
+       if (disk_debug_logging > 2)
                write_log (_T("DSKBYTR=%04X hpos=%d\n"), v, hpos);
        for (int dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) {
                drive *drv = &floppy[dr];
@@ -3624,10 +3642,14 @@ static void DISK_start (void)
 {
        int dr;
 
+       if (disk_debug_logging > 1) {
+               dumpdisk(_T("DSKLEN"));
+       }
+
        for (int i = 0; i < 3; i++)
                fifo_inuse[i] = false;
        fifo_filled = 0;
-       word = 0;
+
        for (dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) {
                drive *drv = &floppy[dr];
                if (!((selected | disabled) & (1 << dr))) {
@@ -3635,6 +3657,7 @@ static void DISK_start (void)
                        trackid *ti = drv->trackdata + tr;
 
                        if (dskdmaen == DSKDMA_WRITE) {
+                               word = 0;
                                drv->tracklen = longwritemode ? FLOPPY_WRITE_MAXLEN : FLOPPY_WRITE_LEN * drv->ddhd * 8 * 2;
                                drv->trackspeed = get_floppy_speed ();
                                drv->skipoffset = -1;
@@ -3645,12 +3668,16 @@ static void DISK_start (void)
                        if (ti->type == TRACK_RAW1) {
                                drv->mfmpos = 0;
                                bitoffset = 0;
+                               word = 0;
                        }
-                       if (drv->catweasel)
+                       if (drv->catweasel) {
+                               word = 0;
                                drive_fill_bigbuf (drv, 1);
+                       }
                }
                drv->floppybitcounter = 0;
        }
+
        dma_enable = (adkcon & 0x400) ? 0 : 1;
        if (word == dsksync)
                wordsync_detected(true);
@@ -3788,7 +3815,7 @@ void DSKLEN (uae_u16 v, int hpos)
        if ((v & 0x8000) && (prev & 0x8000)) {
                if (dskdmaen == DSKDMA_READ) {
                        // update only currently active DMA length, don't change DMA state
-                       write_log(_T("warning: Disk read DMA length rewrite %d -> %d\n"), prev & 0x3fff, v & 0x3fff);
+                       write_log(_T("warning: Disk read DMA length rewrite %d -> %d. (%04x) PC=%08x\n"), prev & 0x3fff, v & 0x3fff, v, M68K_GETPC);
                        return;
                }
                dskdmaen = DSKDMA_READ;
index faf2a947a1fa37f870baf52ee214d1db38f2392b..5c1448c6b0d03130d2df67654b24e610c09fb030 100644 (file)
@@ -3389,7 +3389,7 @@ static void draw_debug_status_line (int line)
        if (xlinebuffer == 0)
                xlinebuffer = row_map[line];
        xlinebuffer_genlock = row_map_genlock[line];
-       debug_draw_cycles(xlinebuffer, gfxvidinfo.drawbuffer.pixbytes, line, gfxvidinfo.drawbuffer.outwidth, gfxvidinfo.drawbuffer.outheight, xredcolors, xgreencolors, xbluecolors);
+       debug_draw(xlinebuffer, gfxvidinfo.drawbuffer.pixbytes, line, gfxvidinfo.drawbuffer.outwidth, gfxvidinfo.drawbuffer.outheight, xredcolors, xgreencolors, xbluecolors);
 }
 
 #define LIGHTPEN_HEIGHT 12
@@ -3667,7 +3667,7 @@ static void finish_drawing_frame (void)
                        do_flush_line (vb, line);
                }
        }
-       if (debug_dma > 1) {
+       if (debug_dma > 1 || debug_heatmap > 1) {
                for (i = 0; i < vb->outheight; i++) {
                        int line = i;
                        draw_debug_status_line (line);
index 1c9e7bf5fe681e0fbee7b7045ebd98e5bec790b5..2f34fec21b2b9a647bd754b192cbf67637db1051 100644 (file)
@@ -315,7 +315,7 @@ addrbank expamem_bank = {
        expamem_lput, expamem_wput, expamem_bput,
        default_xlate, default_check, NULL, NULL, _T("Autoconfig Z2"),
        dummy_lgeti, dummy_wgeti,
-       ABFLAG_IO | ABFLAG_SAFE, S_READ, S_WRITE
+       ABFLAG_IO | ABFLAG_SAFE | ABFLAG_PPCIOSPACE, S_READ, S_WRITE
 };
 DECLARE_MEMORY_FUNCTIONS(expamemz3);
 static addrbank expamemz3_bank = {
@@ -323,7 +323,7 @@ static addrbank expamemz3_bank = {
        expamemz3_lput, expamemz3_wput, expamemz3_bput,
        default_xlate, default_check, NULL, NULL, _T("Autoconfig Z3"),
        dummy_lgeti, dummy_wgeti,
-       ABFLAG_IO | ABFLAG_SAFE, S_READ, S_WRITE
+       ABFLAG_IO | ABFLAG_SAFE | ABFLAG_PPCIOSPACE, S_READ, S_WRITE
 };
 
 static addrbank *expamem_map_clear (void)
@@ -1006,7 +1006,7 @@ addrbank filesys_bank = {
        filesys_lput, filesys_wput, filesys_bput,
        default_xlate, default_check, NULL, _T("filesys"), _T("Filesystem autoconfig"),
        dummy_lgeti, dummy_wgeti,
-       ABFLAG_IO | ABFLAG_SAFE | ABFLAG_INDIRECT, S_READ, S_WRITE
+       ABFLAG_IO | ABFLAG_SAFE | ABFLAG_PPCIOSPACE, S_READ, S_WRITE
 };
 
 static uae_u32 filesys_start; /* Determined by the OS */
@@ -1072,12 +1072,17 @@ addrbank uaeboard_bank = {
        uaeboard_lput, uaeboard_wput, uaeboard_bput,
        default_xlate, default_check, NULL, _T("uaeboard"), _T("uae x autoconfig board"),
        dummy_lgeti, dummy_wgeti,
-       ABFLAG_IO | ABFLAG_SAFE | ABFLAG_INDIRECT, S_READ, S_WRITE
+       ABFLAG_IO | ABFLAG_SAFE | ABFLAG_PPCIOSPACE, S_READ, S_WRITE
 };
 
 static uae_u32 uaeboard_start; /* Determined by the OS */
+#define UAEBOARD_RAM_SIZE 16384
+#define UAEBOARD_RAM_OFFSET (65536 - UAEBOARD_RAM_SIZE)
+#define UAEBOARD_IO_INTERFACE (UAEBOARD_RAM_OFFSET - 16)
+static uae_u8 uaeboard_io_state;
+static uae_u32 uaeboard_io_size, uaeboard_mem_ptr, uaeboard_mem_use;
 
-static uae_u32 REGPARAM2 uaeboard_lget(uaecptr addr)
+static uae_u32 REGPARAM2 uaeboard_wget(uaecptr addr)
 {
        uae_u8 *m;
        addr -= uaeboard_start & 65535;
@@ -1087,24 +1092,41 @@ static uae_u32 REGPARAM2 uaeboard_lget(uaecptr addr)
        }
        m = uaeboard_bank.baseaddr + addr;
 #if EXP_DEBUG
-       write_log(_T("uaeboard_lget %x %x\n"), addr, do_get_mem_long((uae_u32 *)m));
+       write_log(_T("uaeboard_wget %x %x\n"), addr, do_get_mem_word((uae_u16 *)m));
 #endif
-       return do_get_mem_long((uae_u32 *)m);
+       uae_u16 v = do_get_mem_word((uae_u16 *)m);
+
+       if (addr >= UAEBOARD_IO_INTERFACE) {
+               if (uaeboard_io_state & 16) {
+                       uaeboard_mem_ptr &= (UAEBOARD_RAM_SIZE - 1);
+                       if (uaeboard_mem_ptr + uaeboard_io_size > UAEBOARD_RAM_SIZE)
+                               uaeboard_mem_ptr = 0;
+                       if (addr == UAEBOARD_IO_INTERFACE + 8) {
+                               uaeboard_io_state |= 32;
+                               uaeboard_mem_use = uaeboard_mem_ptr + UAEBOARD_RAM_OFFSET;
+                               v = uaeboard_mem_use >> 16;
+                       } else if (addr == UAEBOARD_IO_INTERFACE + 8 + 2) {
+                               uaeboard_io_state |= 64;
+                               uaeboard_mem_use = uaeboard_mem_ptr + UAEBOARD_RAM_OFFSET;
+                               v = uaeboard_mem_use >> 0;
+                       }
+                       if ((uaeboard_io_state & (32 | 64 | 128)) == (32 | 64)) {
+                               uaeboard_mem_ptr += uaeboard_io_size;
+                               uaeboard_io_state |= 128;
+                       }
+               }
+       }
+
+       return v;
 }
 
-static uae_u32 REGPARAM2 uaeboard_wget(uaecptr addr)
+static uae_u32 REGPARAM2 uaeboard_lget(uaecptr addr)
 {
-       uae_u8 *m;
        addr -= uaeboard_start & 65535;
        addr &= 65535;
-       if (addr == 0x200 || addr == 0x201) {
-               mousehack_wakeup();
-       }
-       m = uaeboard_bank.baseaddr + addr;
-#if EXP_DEBUG
-       write_log(_T("uaeboard_wget %x %x\n"), addr, do_get_mem_word((uae_u16 *)m));
-#endif
-       return do_get_mem_word((uae_u16 *)m);
+       uae_u32 v = uaeboard_wget(addr) << 16;
+       v |= uaeboard_wget(addr + 2);
+       return v;
 }
 
 static uae_u32 REGPARAM2 uaeboard_bget(uaecptr addr)
@@ -1113,6 +1135,19 @@ static uae_u32 REGPARAM2 uaeboard_bget(uaecptr addr)
        addr &= 65535;
        if (addr == 0x200 || addr == 0x201) {
                mousehack_wakeup();
+       } else if (addr == UAEBOARD_IO_INTERFACE) {
+               uaeboard_bank.baseaddr[UAEBOARD_IO_INTERFACE] = uaeboard_io_state == 0;
+               if (!uaeboard_io_state) {
+                       // mark allocated
+                       uaeboard_io_state = 1;
+               }
+       } else if (addr == UAEBOARD_IO_INTERFACE + 2) {
+               if (uaeboard_io_state & 8) {
+                       uaeboard_bank.baseaddr[addr] = 1;
+                       uaeboard_io_state |= 16;
+               }
+       } else if (addr == uaeboard_mem_use) {
+               uaeboard_bank.baseaddr[addr] = 1;
        }
 #if EXP_DEBUG
        write_log(_T("uaeboard_bget %x %x\n"), addr, uaeboard_bank.baseaddr[addr]);
@@ -1120,30 +1155,74 @@ static uae_u32 REGPARAM2 uaeboard_bget(uaecptr addr)
        return uaeboard_bank.baseaddr[addr];
 }
 
+static void REGPARAM2 uaeboard_wput(uaecptr addr, uae_u32 w)
+{
+       addr -= uaeboard_start & 65535;
+       addr &= 65535;
+       if (addr >= 0x200 + 0x20 && addr < 0x200 + 0x24) {
+               mousehack_write(addr - 0x200, w);
+       } else if (addr >= UAEBOARD_IO_INTERFACE) {
+               uae_u16 *m = (uae_u16 *)(uaeboard_bank.baseaddr + addr);
+               do_put_mem_word(m, w);
+               if (uaeboard_io_state) {
+                       if (addr == UAEBOARD_IO_INTERFACE + 4)
+                               uaeboard_io_state |= 2;
+                       if (addr == UAEBOARD_IO_INTERFACE + 6)
+                               uaeboard_io_state |= 4;
+                       if (uaeboard_io_state == (1 | 2 | 4)) {
+                               uae_u32 *m2 = (uae_u32 *)(uaeboard_bank.baseaddr + UAEBOARD_IO_INTERFACE + 4);
+                               // size received
+                               uaeboard_io_state |= 8;
+                               uaeboard_io_size = do_get_mem_long(m2);
+                       }
+               }
+               // writing command byte executes it
+               if (addr == uaeboard_mem_use) {
+                       w &= 0xffff;
+                       if (w != 0xffff && w != 0) {
+                               uae_u32 *m2 = (uae_u32 *)(uaeboard_bank.baseaddr + addr);
+                               do_put_mem_long(m2 + 1, uaeboard_demux(m2));
+                       }
+               }
+       }
+#if EXP_DEBUG
+       write_log(_T("uaeboard_wput %08x = %04x PC=%08x\n"), addr, w, M68K_GETPC);
+#endif
+}
+
 static void REGPARAM2 uaeboard_lput(uaecptr addr, uae_u32 l)
 {
+       addr -= uaeboard_start & 65535;
+       addr &= 65535;
        if (addr >= 0x200 + 0x20 && addr < 0x200 + 0x24) {
                mousehack_write(addr - 0x200, l >> 16);
                mousehack_write(addr - 0x200 + 2, l);
+       } else if (addr >= UAEBOARD_IO_INTERFACE) {
+               uaeboard_wput(addr, l >> 16);
+               uaeboard_wput(addr + 2, l);
        }
+#if EXP_DEBUG
        write_log(_T("uaeboard_lput %08x = %08x PC=%08x\n"), addr, l, M68K_GETPC);
-}
-
-static void REGPARAM2 uaeboard_wput(uaecptr addr, uae_u32 w)
-{
-       if (addr >= 0x200 + 0x20 && addr < 0x200 + 0x24)
-               mousehack_write(addr - 0x200, w);
-       write_log(_T("uaeboard_wput %08x = %04x PC=%08x\n"), addr, w, M68K_GETPC);
+#endif
 }
 
 static void REGPARAM2 uaeboard_bput(uaecptr addr, uae_u32 b)
 {
+       addr -= uaeboard_start & 65535;
+       addr &= 65535;
+       if (addr == uaeboard_mem_use) {
+               uaeboard_io_size = 0;
+               uaeboard_mem_use = 0;
+               uaeboard_io_state = 0;
+       }
+       if (addr >= UAEBOARD_RAM_OFFSET) {
+               uaeboard_bank.baseaddr[addr] = b;
+       }
 #if EXP_DEBUG
        write_log(_T("uaeboard_bput %x %x\n"), addr, b);
 #endif
 }
 
-
 static addrbank *expamem_map_uaeboard(void)
 {
        uaeboard_start = expamem_z2_pointer;
@@ -1155,7 +1234,7 @@ static addrbank* expamem_init_uaeboard(int devnum)
        uae_u8 *p = uaeboard_bank.baseaddr;
 
        expamem_init_clear();
-       expamem_write(0x00, Z2_MEM_64KB | zorroII);
+       expamem_write(0x00, (currprefs.uaeboard > 1 ? Z2_MEM_128KB : Z2_MEM_64KB) | zorroII);
 
        expamem_write(0x08, no_shutup);
 
@@ -1175,10 +1254,18 @@ static addrbank* expamem_init_uaeboard(int devnum)
        memcpy(p, expamem, 0x100);
 
        p += 0x100;
+
        p[0] = 0x00;
        p[1] = 0x00;
        p[2] = 0x02;
        p[3] = 0x00;
+
+       p[4] = (uae_u8)(UAEBOARD_IO_INTERFACE >> 24);
+       p[5] = (uae_u8)(UAEBOARD_IO_INTERFACE >> 16);
+       p[6] = (uae_u8)(UAEBOARD_IO_INTERFACE >> 8);
+       p[7] = (uae_u8)(UAEBOARD_IO_INTERFACE >> 0);
+       uaeboard_io_state = 0;
+
        return NULL;
 }
 
@@ -1295,7 +1382,7 @@ static void fastmem_autoconfig(int boardnum, int zorro, uae_u8 type, uae_u32 ser
        ac[0x04 / 4] = pid;
        ac[0x08 / 4] = flags;
        ac[0x10 / 4] = mid >> 8;
-       ac[0x14 / 4] = mid;
+       ac[0x14 / 4] = (uae_u8)mid;
        ac[0x18 / 4] = serial >> 24;
        ac[0x1c / 4] = serial >> 16;
        ac[0x20 / 4] = serial >> 8;
@@ -1451,7 +1538,7 @@ static void add_ks12_boot_hack(void)
        dl(addr);
        dl(addr + 26);
        db(1); // RTF_COLDSTART
-       db(kickstart_version); // version
+       db((uae_u8)kickstart_version); // version
        db(0); // NT_UNKNOWN
        db(1); // priority
        dl(name);
@@ -2184,19 +2271,20 @@ void expamem_reset (void)
                add_cpu_expansions(BOARD_AUTOCONFIG_Z3);
 
                if (z3fastmem_bank.baseaddr != NULL) {
+                       bool alwaysmapz3 = currprefs.z3_mapping_mode != Z3MAPPING_REAL;
                        z3num = 0;
                        cards[cardno].flags = 2 | 1;
                        cards[cardno].name = _T("Z3Fast");
                        cards[cardno].initnum = expamem_init_z3fastmem;
                        cards[cardno++].map = expamem_map_z3fastmem;
-                       if (expamem_z3hack(&currprefs))
+                       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 = 2 | 1;
                                cards[cardno].name = _T("Z3Fast2");
                                cards[cardno].initnum = expamem_init_z3fastmem2;
                                cards[cardno++].map = expamem_map_z3fastmem2;
-                               if (expamem_z3hack(&currprefs))
+                               if (alwaysmapz3 || expamem_z3hack(&currprefs))
                                        map_banks_z3(&z3fastmem2_bank, z3fastmem2_bank.start >> 16, currprefs.z3fastmem2_size >> 16);
                        }
                }
@@ -3582,6 +3670,19 @@ static const struct cpuboardsubtype icboard_sub[] = {
                NULL
        }
 };
+static const struct cpuboardsubtype dceboard_sub[] = {
+       {
+               _T("SX32 Pro"),
+               _T("sx32pro"),
+               ROMTYPE_CB_SX32PRO, 0,
+               NULL, 0,
+               BOARD_MEMORY_EMATRIX,
+               64 * 1024 * 1024
+       },
+       {
+               NULL
+       }
+};
 
 static const struct cpuboardsubtype dummy_sub[] = {
        { NULL }
@@ -3603,6 +3704,11 @@ const struct cpuboardtype cpuboards[] = {
                _T("Commodore"),
                commodore_sub, 0
        },
+       {
+               BOARD_DCE,
+               _T("DCE"),
+               dceboard_sub, 0
+       },
        {
                BOARD_DKB,
                _T("DKB"),
index e52660e3cbbcc247c7d6ae60232a7e1ac1f001c3..e5c6dd32a005fc3a9508b12dc25da57ba863ff92 100644 (file)
@@ -2978,15 +2978,15 @@ static void resetvars (void)
                getpc = "m68k_getpci ()";
        } else if (using_prefetch) {
                // 68000 prefetch
-               prefetch_word = "get_word_prefetch";
-               prefetch_long = "get_long_prefetch";
-               srcwi = "get_wordi_prefetch";
-               srcl = "get_long_prefetch";
-               dstl = "put_long_prefetch";
-               srcw = "get_word_prefetch";
-               dstw = "put_word_prefetch";
-               srcb = "get_byte_prefetch";
-               dstb = "put_byte_prefetch";
+               prefetch_word = "get_word_000_prefetch";
+               prefetch_long = "get_long_000_prefetch";
+               srcwi = "get_wordi_000";
+               srcl = "get_long_000";
+               dstl = "put_long_000";
+               srcw = "get_word_000";
+               dstw = "put_word_000";
+               srcb = "get_byte_000";
+               dstb = "put_byte_000";
                getpc = "m68k_getpci ()";
        } else {
                // generic + direct
index 63bf6cd85653123de8da74088d92afb2d92da7a3..003bfaf5e71dbde7ab4fd221bd8dbca2dcefcd1e 100644 (file)
@@ -104,7 +104,7 @@ struct gfxboard
 // Picasso II: 8* 4x256 (1M) or 16* 4x256 (2M)
 // Piccolo: 8* 4x256 + 2* 16x256 (2M)
 
-static struct gfxboard boards[] =
+static const struct gfxboard boards[] =
 {
        {
                _T("Picasso II"), _T("Village Tronic"), _T("PicassoII"),
@@ -175,49 +175,54 @@ static struct gfxboard boards[] =
        }
 };
 
-static TCHAR memorybankname[40];
-static TCHAR wbsmemorybankname[40];
-static TCHAR lbsmemorybankname[40];
-static TCHAR regbankname[40];
-
-static int configured_mem, configured_regs;
-static struct gfxboard *board;
-static uae_u8 expamem_lo;
-static uae_u8 *automemory;
-static uae_u32 banksize_mask;
-
-static uae_u8 picassoiv_bank, picassoiv_flifi;
-static uae_u8 p4autoconfig[256];
-static struct zfile *p4rom;
-static bool p4z2;
-static uae_u32 p4_mmiobase;
-static uae_u32 p4_special_mask;
-static uae_u32 p4_vram_bank[2];
-
-static CirrusVGAState vga;
-static uae_u8 *vram, *vramrealstart;
-static int vram_start_offset;
-static uae_u32 gfxboardmem_start;
-static bool monswitch_current, monswitch_new;
-static bool monswitch_reset;
-static int monswitch_delay;
-static int fullrefresh;
-static bool modechanged;
-static uae_u8 *gfxboard_surface, *fakesurface_surface;
-static bool gfxboard_vblank;
-static bool gfxboard_intena;
-static bool vram_enabled, vram_offset_enabled;
-static hwaddr vram_offset[2];
-static uae_u8 cirrus_pci[0x44];
-static uae_u8 p4_pci[0x44];
-static int vga_width, vga_height;
-static bool vga_refresh_active;
-static bool vga_changed;
-
-static uae_u32 vgaioregionptr, vgavramregionptr, vgabank0regionptr, vgabank1regionptr;
-
-static const MemoryRegionOps *vgaio, *vgaram, *vgalowram, *vgammio;
-static MemoryRegion vgaioregion, vgavramregion;
+struct rtggfxboard
+{
+       TCHAR memorybankname[40];
+       TCHAR wbsmemorybankname[40];
+       TCHAR lbsmemorybankname[40];
+       TCHAR regbankname[40];
+
+       int configured_mem, configured_regs;
+       const struct gfxboard *board;
+       uae_u8 expamem_lo;
+       uae_u8 *automemory;
+       uae_u32 banksize_mask;
+
+       uae_u8 picassoiv_bank, picassoiv_flifi;
+       uae_u8 p4autoconfig[256];
+       struct zfile *p4rom;
+       bool p4z2;
+       uae_u32 p4_mmiobase;
+       uae_u32 p4_special_mask;
+       uae_u32 p4_vram_bank[2];
+
+       CirrusVGAState vga;
+       uae_u8 *vram, *vramrealstart;
+       int vram_start_offset;
+       uae_u32 gfxboardmem_start;
+       bool monswitch_current, monswitch_new;
+       bool monswitch_reset;
+       int monswitch_delay;
+       int fullrefresh;
+       bool modechanged;
+       uae_u8 *gfxboard_surface, *fakesurface_surface;
+       bool gfxboard_vblank;
+       bool gfxboard_intena;
+       bool vram_enabled, vram_offset_enabled;
+       hwaddr vram_offset[2];
+       uae_u8 cirrus_pci[0x44];
+       uae_u8 p4_pci[0x44];
+       int vga_width, vga_height;
+       bool vga_refresh_active;
+       bool vga_changed;
+
+       uae_u32 vgaioregionptr, vgavramregionptr, vgabank0regionptr, vgabank1regionptr;
+
+       const MemoryRegionOps *vgaio, *vgaram, *vgalowram, *vgammio;
+       MemoryRegion vgaioregion, vgavramregion;
+};
+
+static struct rtggfxboard rtggfxboards[1];
 
 DECLARE_MEMORY_FUNCTIONS(gfxboard);
 DECLARE_MEMORY_FUNCTIONS_WITH_SUFFIX(gfxboard, mem);
@@ -285,89 +290,91 @@ static addrbank gfxboard_bank_special = {
        ABFLAG_IO | ABFLAG_SAFE, S_READ, S_WRITE
 };
 
-static void init_board (void)
+static void init_board (struct rtggfxboard *gb)
 {
-       int vramsize = board->vrammax;
+       int vramsize = gb->board->vrammax;
 
-       vga_width = 0;
+       gb->vga_width = 0;
        mapped_free(&gfxmem_bank);
-       vram_start_offset = 0;
-       if (ISP4() && !p4z2) // JIT direct compatibility hack
-               vram_start_offset = 0x01000000;
-       vramsize += vram_start_offset;
-       xfree (fakesurface_surface);
-       fakesurface_surface = xmalloc (uae_u8, 4 * 10000);
-       vram_offset[0] = vram_offset[1] = 0;
-       vram_enabled = true;
-       vram_offset_enabled = false;
-       if (board->manufacturer) {
-               gfxmem_bank.label = board->configtype == 3 ? _T("z3_gfx") : _T("z2_gfx");
+       gb->vram_start_offset = 0;
+       if (ISP4() && !gb->p4z2) // JIT direct compatibility hack
+               gb->vram_start_offset = 0x01000000;
+       vramsize += gb->vram_start_offset;
+       xfree (gb->fakesurface_surface);
+       gb->fakesurface_surface = xmalloc (uae_u8, 4 * 10000);
+       gb->vram_offset[0] = gb->vram_offset[1] = 0;
+       gb->vram_enabled = true;
+       gb->vram_offset_enabled = false;
+       if (gb->board->manufacturer) {
+               gfxmem_bank.label = gb->board->configtype == 3 ? _T("z3_gfx") : _T("z2_gfx");
        } else {
                gfxmem_bank.label = _T("ram_a8");
        }
        gfxmem_bank.allocated = vramsize;
        mapped_malloc (&gfxmem_bank);
-       vram = gfxmem_bank.baseaddr;
-       vramrealstart = vram;
-       vram += vram_start_offset;
-       gfxmem_bank.baseaddr = vram;
+       gb->vram = gfxmem_bank.baseaddr;
+       gb->vramrealstart = gb->vram;
+       gb->vram += gb->vram_start_offset;
+       gfxmem_bank.baseaddr = gb->vram;
        gfxmem_bank.allocated = currprefs.rtgmem_size;
-       vga.vga.vram_size_mb = currprefs.rtgmem_size >> 20;
-       vgaioregion.opaque = &vgaioregionptr;
-       vgavramregion.opaque = &vgavramregionptr;
-       vga.vga.vram.opaque = &vgavramregionptr;
-       vga_common_init(&vga.vga);
-       cirrus_init_common(&vga, board->chiptype, 0,  NULL, NULL, board->manufacturer == 0);
+       gb->vga.vga.vram_size_mb = currprefs.rtgmem_size >> 20;
+       gb->vgaioregion.opaque = &gb->vgaioregionptr;
+       gb->vgavramregion.opaque = &gb->vgavramregionptr;
+       gb->vga.vga.vram.opaque = &gb->vgavramregionptr;
+       vga_common_init(&gb->vga.vga);
+       cirrus_init_common(&gb->vga, gb->board->chiptype, 0,  NULL, NULL, gb->board->manufacturer == 0);
        picasso_allocatewritewatch (currprefs.rtgmem_size);
 }
 
-static void vga_update_size(void)
+static void vga_update_size(struct rtggfxboard *gb)
 {
        // this forces qemu_console_resize() call
-       vga.vga.graphic_mode = -1;
-       vga.vga.hw_ops->gfx_update(&vga);
+       gb->vga.vga.graphic_mode = -1;
+       gb->vga.vga.hw_ops->gfx_update(&gb->vga);
 }
 
-static bool gfxboard_setmode(void)
+static bool gfxboard_setmode(struct rtggfxboard *gb)
 {
-       int bpp = vga.vga.get_bpp(&vga.vga);
+       int bpp = gb->vga.vga.get_bpp(&gb->vga.vga);
        if (bpp == 0)
                bpp = 8;
-       vga_update_size();
-       if (vga_width <= 16 || vga_height <= 16)
+       vga_update_size(gb);
+       if (gb->vga_width <= 16 || gb->vga_height <= 16)
                return false;
-       picasso96_state.Width = vga_width;
-       picasso96_state.Height = vga_height;
+       picasso96_state.Width = gb->vga_width;
+       picasso96_state.Height = gb->vga_height;
        picasso96_state.BytesPerPixel = bpp / 8;
        picasso96_state.RGBFormat = RGBFB_CLUT;
-       write_log(_T("GFXBOARD %dx%dx%d\n"), vga_width, vga_height, bpp);
-       gfx_set_picasso_modeinfo(vga_width, vga_height, bpp, RGBFB_NONE);
-       fullrefresh = 2;
-       vga_changed = false;
+       write_log(_T("GFXBOARD %dx%dx%d\n"), gb->vga_width, gb->vga_height, bpp);
+       gfx_set_picasso_modeinfo(gb->vga_width, gb->vga_height, bpp, RGBFB_NONE);
+       gb->fullrefresh = 2;
+       gb->vga_changed = false;
        return true;
 }
 
 bool gfxboard_toggle (int mode)
 {
+       struct rtggfxboard *gb = &rtggfxboards[0];
+
        if (currprefs.rtgmem_type == GFXBOARD_A2410) {
                return tms_toggle(mode);
        }
 
-       if (vram == NULL)
+       if (gb->vram == NULL)
                return false;
-       if (monswitch_current) {
-               vga_width = 0;
-               monswitch_new = false;
-               monswitch_delay = 1;
+       if (gb->monswitch_current) {
+               gb->vga_width = 0;
+               gb->monswitch_new = false;
+               gb->monswitch_delay = 1;
                picasso_requested_on = 0;
                return true;
        } else {
-               vga_update_size();
-               if (vga_width > 16 && vga_height > 16) {
-                       if (!gfxboard_setmode())
+               vga_update_size(gb);
+               if (gb->vga_width > 16 && gb->vga_height > 16) {
+                       if (!gfxboard_setmode(gb))
                                return false;
-                       monswitch_new = true;
-                       monswitch_delay = 1;
+                       gb->monswitch_new = true;
+                       gb->monswitch_delay = 1;
                        picasso_requested_on = 1;
                        return true;
                }
@@ -375,15 +382,15 @@ bool gfxboard_toggle (int mode)
        return false;
 }
 
-static bool gfxboard_checkchanged (void)
+static bool gfxboard_checkchanged (struct rtggfxboard *gb)
 {
-       int bpp = vga.vga.get_bpp (&vga.vga);
+       int bpp = gb->vga.vga.get_bpp (&gb->vga.vga);
        if (bpp == 0)
                bpp = 8;
-       if (vga_width <= 16 || vga_height <= 16)
+       if (gb->vga_width <= 16 || gb->vga_height <= 16)
                return false;
-       if (picasso96_state.Width != vga_width ||
-               picasso96_state.Height != vga_height ||
+       if (picasso96_state.Width != gb->vga_width ||
+               picasso96_state.Height != gb->vga_height ||
                picasso96_state.BytesPerPixel != bpp / 8)
                return true;
        return false;
@@ -392,18 +399,20 @@ static bool gfxboard_checkchanged (void)
 static DisplaySurface gfxsurface, fakesurface;
 DisplaySurface *qemu_console_surface(QemuConsole *con)
 {
+       struct rtggfxboard *gb = &rtggfxboards[0];
        if (picasso_on)
                return &gfxsurface;
-       modechanged = true;
+       gb->modechanged = true;
        return &fakesurface;
 }
 
 void qemu_console_resize(QemuConsole *con, int width, int height)
 {
-       if (width != vga_width || vga_height != height)
-               vga_changed = true;
-       vga_width = width;
-       vga_height = height;
+       struct rtggfxboard *gb = &rtggfxboards[0];
+       if (width != gb->vga_width || gb->vga_height != height)
+               gb->vga_changed = true;
+       gb->vga_width = width;
+       gb->vga_height = height;
 }
 
 void linear_memory_region_set_dirty(MemoryRegion *mr, hwaddr addr, hwaddr size)
@@ -412,10 +421,11 @@ void linear_memory_region_set_dirty(MemoryRegion *mr, hwaddr addr, hwaddr size)
 
 void vga_memory_region_set_dirty(MemoryRegion *mr, hwaddr addr, hwaddr size)
 {
-       if (vga.vga.graphic_mode != 1)
+       struct rtggfxboard *gb = &rtggfxboards[0];
+       if (gb->vga.vga.graphic_mode != 1)
                return;
-       if (!fullrefresh)
-               fullrefresh = 1;
+       if (!gb->fullrefresh)
+               gb->fullrefresh = 1;
 }
 
 #if 0
@@ -430,7 +440,8 @@ DisplaySurface* qemu_create_displaysurface_from(int width, int height, int bpp,
                                                 int linesize, uint8_t *data,
                                                 bool byteswap)
 {
-       modechanged = true;
+       struct rtggfxboard *gb = &rtggfxboards[0];
+       gb->modechanged = true;
        return &fakesurface;
 }
 
@@ -449,110 +460,118 @@ int surface_bytes_per_pixel(DisplaySurface *s)
 
 int surface_stride(DisplaySurface *s)
 {
-       if (s == &fakesurface || !vga_refresh_active)
+       struct rtggfxboard *gb = &rtggfxboards[0];
+       if (s == &fakesurface || !gb->vga_refresh_active)
                return 0;
-       if (gfxboard_surface == NULL)
-               gfxboard_surface = gfx_lock_picasso (false, false);
+       if (gb->gfxboard_surface == NULL)
+               gb->gfxboard_surface = gfx_lock_picasso (false, false);
        return picasso_vidinfo.rowbytes;
 }
 uint8_t *surface_data(DisplaySurface *s)
 {
-       if (vga_changed)
+       struct rtggfxboard *gb = &rtggfxboards[0];
+       if (gb->vga_changed)
                return NULL;
-       if (s == &fakesurface || !vga_refresh_active)
-               return fakesurface_surface;
-       if (gfxboard_surface == NULL)
-               gfxboard_surface = gfx_lock_picasso (false, false);
-       return gfxboard_surface;
+       if (s == &fakesurface || !gb->vga_refresh_active)
+               return gb->fakesurface_surface;
+       if (gb->gfxboard_surface == NULL)
+               gb->gfxboard_surface = gfx_lock_picasso (false, false);
+       return gb->gfxboard_surface;
 }
 
 void gfxboard_refresh (void)
 {
-       fullrefresh = 2;
+       struct rtggfxboard *gb = &rtggfxboards[0];
+       gb->fullrefresh = 2;
 }
 
 void gfxboard_hsync_handler(void)
 {
+       struct rtggfxboard *gb = &rtggfxboards[0];
        if (currprefs.rtgmem_type == GFXBOARD_A2410) {
                tms_hsync_handler();
        }
 }
 
-void gfxboard_vsync_handler (void)
+bool gfxboard_vsync_handler (void)
 {
+       struct rtggfxboard *gb = &rtggfxboards[0];
+       bool flushed = false;
+
        if (currprefs.rtgmem_type == GFXBOARD_A2410) {
-               tms_vsync_handler();
-               return;
+               return tms_vsync_handler();
        }
 
-       if (!configured_mem || !configured_regs)
-               return;
+       if (!gb->configured_mem || !gb->configured_regs)
+               return false;
 
-       if (monswitch_current && (modechanged || gfxboard_checkchanged ())) {
-               modechanged = false;
-               if (!gfxboard_setmode ()) {
+       if (gb->monswitch_current && (gb->modechanged || gfxboard_checkchanged(gb))) {
+               gb->modechanged = false;
+               if (!gfxboard_setmode (gb)) {
                        picasso_requested_on = 0;
-                       return;
+                       return false;
                }
                init_hz_p96 ();
                picasso_requested_on = 1;
-               return;
+               return false;
        }
 
-       if (monswitch_new != monswitch_current) {
-               if (monswitch_delay > 0)
-                       monswitch_delay--;
-               if (monswitch_delay == 0) {
-                       if (!monswitch_new)
+       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;
-                       monswitch_current = monswitch_new;
-                       vga_update_size();
-                       write_log (_T("GFXBOARD ACTIVE=%d\n"), monswitch_current);
+                       gb->monswitch_current = gb->monswitch_new;
+                       vga_update_size(gb);
+                       write_log (_T("GFXBOARD ACTIVE=%d\n"), gb->monswitch_current);
                }
        } else {
-               monswitch_delay = 0;
+               gb->monswitch_delay = 0;
        }
 
-       if (!monswitch_delay && monswitch_current && picasso_on && picasso_requested_on && !vga_changed) {
-               picasso_getwritewatch (vram_start_offset);
-               if (fullrefresh)
-                       vga.vga.graphic_mode = -1;
-               vga_refresh_active = true;
-               vga.vga.hw_ops->gfx_update(&vga);
-               vga_refresh_active = false;
+       if (!gb->monswitch_delay && gb->monswitch_current && picasso_on && picasso_requested_on && !gb->vga_changed) {
+               picasso_getwritewatch (gb->vram_start_offset);
+               if (gb->fullrefresh)
+                       gb->vga.vga.graphic_mode = -1;
+               gb->vga_refresh_active = true;
+               gb->vga.vga.hw_ops->gfx_update(&gb->vga);
+               gb->vga_refresh_active = false;
        }
 
-       if (picasso_on && !vga_changed) {
+       if (picasso_on && !gb->vga_changed) {
                if (currprefs.leds_on_screen & STATUSLINE_RTG) {
-                       if (gfxboard_surface == NULL) {
-                               gfxboard_surface = gfx_lock_picasso (false, false);
+                       if (gb->gfxboard_surface == NULL) {
+                               gb->gfxboard_surface = gfx_lock_picasso (false, false);
                        }
-                       if (gfxboard_surface) {
+                       if (gb->gfxboard_surface) {
                                if (!(currprefs.leds_on_screen & STATUSLINE_TARGET))
-                                       picasso_statusline (gfxboard_surface);
+                                       picasso_statusline (gb->gfxboard_surface);
                        }
                }
-               if (fullrefresh > 0)
-                       fullrefresh--;
+               if (gb->fullrefresh > 0)
+                       gb->fullrefresh--;
        }
 
-       if (gfxboard_surface)
+       if (gb->gfxboard_surface) {
+               flushed = true;
                gfx_unlock_picasso (true);
-       gfxboard_surface = NULL;
+       }
+       gb->gfxboard_surface = NULL;
 
        // Vertical Sync End Register, 0x20 = Disable Vertical Interrupt, 0x10 = Clear Vertical Interrupt.
-       if (board->irq) {
-               if ((!(vga.vga.cr[0x11] & 0x20) && (vga.vga.cr[0x11] & 0x10) && !(vga.vga.gr[0x17] & 4))) {
-                       if (gfxboard_intena) {
-                               gfxboard_vblank = true;
-                               if (board->irq == 2)
+       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;
 }
 
 double gfxboard_get_vsync (void)
@@ -571,10 +590,11 @@ void memory_region_init_alias(MemoryRegion *mr,
                               hwaddr offset,
                               uint64_t size)
 {
+       struct rtggfxboard *gb = &rtggfxboards[0];
        if (!stricmp(name, "vga.bank0")) {
-               mr->opaque = &vgabank0regionptr;
+               mr->opaque = &gb->vgabank0regionptr;
        } else if (!stricmp(name, "vga.bank1")) {
-               mr->opaque = &vgabank1regionptr;
+               mr->opaque = &gb->vgabank1regionptr;
        }
 }
 
@@ -587,42 +607,42 @@ static void jit_reset (void)
 #endif
 }
 
-static void remap_vram (hwaddr offset0, hwaddr offset1, bool enabled)
+static void remap_vram (struct rtggfxboard *gb, hwaddr offset0, hwaddr offset1, bool enabled)
 {
        jit_reset ();
-       vram_offset[0] = offset0;
-       vram_offset[1] = offset1;
+       gb->vram_offset[0] = offset0;
+       gb->vram_offset[1] = offset1;
 #if VRAMLOG
        if (vram_enabled != enabled)
                write_log (_T("VRAM state=%d\n"), enabled);
        bool was_vram_offset_enabled = vram_offset_enabled;
 #endif
-       vram_enabled = enabled && (vga.vga.sr[0x07] & 0x01);
+       gb->vram_enabled = enabled && (gb->vga.vga.sr[0x07] & 0x01);
 #if 0
        vram_enabled = false;
 #endif
        // offset==0 and offset1==0x8000: linear vram mapping
-       vram_offset_enabled = offset0 != 0 || offset1 != 0x8000;
+       gb->vram_offset_enabled = offset0 != 0 || offset1 != 0x8000;
 #if VRAMLOG
-       if (vram_offset_enabled || was_vram_offset_enabled)
+       if (gb->vram_offset_enabled || gb->was_vram_offset_enabled)
                write_log (_T("VRAM offset %08x and %08x\n"), offset0, offset1);
 #endif
 }
 
-void memory_region_set_alias_offset(MemoryRegion *mr,
-                                    hwaddr offset)
+void memory_region_set_alias_offset(MemoryRegion *mr, hwaddr offset)
 {
-       if (mr->opaque == &vgabank0regionptr) {
-               if (offset != vram_offset[0]) {
+       struct rtggfxboard *gb = &rtggfxboards[0];
+       if (mr->opaque == &gb->vgabank0regionptr) {
+               if (offset != gb->vram_offset[0]) {
                        //write_log (_T("vgavramregion0 %08x\n"), offset);
-                       remap_vram (offset, vram_offset[1], vram_enabled);
+                       remap_vram (gb, offset, gb->vram_offset[1], gb->vram_enabled);
                }
-       } else if (mr->opaque == &vgabank1regionptr) {
-               if (offset != vram_offset[1]) {
+       } else if (mr->opaque == &gb->vgabank1regionptr) {
+               if (offset != gb->vram_offset[1]) {
                        //write_log (_T("vgavramregion1 %08x\n"), offset);
-                       remap_vram (vram_offset[0], offset, vram_enabled);
+                       remap_vram (gb, gb->vram_offset[0], offset, gb->vram_enabled);
                }
-       } else if (mr->opaque == &vgaioregionptr) {
+       } else if (mr->opaque == &gb->vgaioregionptr) {
                write_log (_T("vgaioregion %d\n"), offset);
        } else {
                write_log (_T("unknown region %d\n"), offset);
@@ -631,12 +651,13 @@ void memory_region_set_alias_offset(MemoryRegion *mr,
 }
 void memory_region_set_enabled(MemoryRegion *mr, bool enabled)
 {
-       if (mr->opaque == &vgabank0regionptr || mr->opaque == &vgabank1regionptr) {
-               if (enabled != vram_enabled)  {
+       struct rtggfxboard *gb = &rtggfxboards[0];
+       if (mr->opaque == &gb->vgabank0regionptr || mr->opaque == &gb->vgabank1regionptr) {
+               if (enabled != gb->vram_enabled)  {
                        //write_log (_T("enable vgavramregion %d\n"), enabled);
-                       remap_vram (vram_offset[0], vram_offset[1], enabled);
+                       remap_vram (gb, gb->vram_offset[0], gb->vram_offset[1], enabled);
                }
-       } else if (mr->opaque == &vgaioregionptr) {
+       } else if (mr->opaque == &gb->vgaioregionptr) {
                write_log (_T("enable vgaioregion %d\n"), enabled);
        } else {
                write_log (_T("enable unknown region %d\n"), enabled);
@@ -650,10 +671,11 @@ void memory_region_reset_dirty(MemoryRegion *mr, hwaddr addr,
 bool memory_region_get_dirty(MemoryRegion *mr, hwaddr addr,
                              hwaddr size, unsigned client)
 {
-       if (mr->opaque != &vgavramregionptr)
+       struct rtggfxboard *gb = &rtggfxboards[0];
+       if (mr->opaque != &gb->vgavramregionptr)
                return false;
        //write_log (_T("memory_region_get_dirty %08x %08x\n"), addr, size);
-       if (fullrefresh)
+       if (gb->fullrefresh)
                return true;
        return picasso_is_vram_dirty (addr + gfxmem_bank.start, size);
 }
@@ -667,95 +689,95 @@ void qemu_register_reset(QEMUResetHandler *func, void *opaque)
        reset_func (reset_parm);
 }
 
-static void p4_pci_check (void)
+static void p4_pci_check (struct rtggfxboard *gb)
 {
        uaecptr b0, b1;
 
-       b0 = p4_pci[0x10 + 2] << 16;
-       b1 = p4_pci[0x14 + 2] << 16;
+       b0 = gb->p4_pci[0x10 + 2] << 16;
+       b1 = gb->p4_pci[0x14 + 2] << 16;
 
-       p4_vram_bank[0] = b0;
-       p4_vram_bank[1] = b1;
+       gb->p4_vram_bank[0] = b0;
+       gb->p4_vram_bank[1] = b1;
 #if PICASSOIV_DEBUG_IO
        write_log (_T("%08X %08X\n"), p4_vram_bank[0], p4_vram_bank[1]);
 #endif
 }
 
-static void reset_pci (void)
+static void reset_pci (struct rtggfxboard *gb)
 {
-       cirrus_pci[0] = 0x00;
-       cirrus_pci[1] = 0xb8;
-       cirrus_pci[2] = 0x10;
-       cirrus_pci[3] = 0x13;
+       gb->cirrus_pci[0] = 0x00;
+       gb->cirrus_pci[1] = 0xb8;
+       gb->cirrus_pci[2] = 0x10;
+       gb->cirrus_pci[3] = 0x13;
 
-       cirrus_pci[4] = 2;
-       cirrus_pci[5] = 0;
-       cirrus_pci[6] = 0;
-       cirrus_pci[7] &= ~(1 | 2 | 32);
+       gb->cirrus_pci[4] = 2;
+       gb->cirrus_pci[5] = 0;
+       gb->cirrus_pci[6] = 0;
+       gb->cirrus_pci[7] &= ~(1 | 2 | 32);
 
-       cirrus_pci[8] = 3;
-       cirrus_pci[9] = 0;
-       cirrus_pci[10] = 0;
-       cirrus_pci[11] = 68;
+       gb->cirrus_pci[8] = 3;
+       gb->cirrus_pci[9] = 0;
+       gb->cirrus_pci[10] = 0;
+       gb->cirrus_pci[11] = 68;
 
-       cirrus_pci[0x10] &= ~1; // B revision
-       cirrus_pci[0x13] &= ~1; // memory
+       gb->cirrus_pci[0x10] &= ~1; // B revision
+       gb->cirrus_pci[0x13] &= ~1; // memory
 }
 
-static void set_monswitch(bool newval)
+static void set_monswitch(struct rtggfxboard *gb, bool newval)
 {
-       if (monswitch_new == newval)
+       if (gb->monswitch_new == newval)
                return;
-       monswitch_new = newval; 
-       monswitch_delay = MONITOR_SWITCH_DELAY;
+       gb->monswitch_new = newval;
+       gb->monswitch_delay = MONITOR_SWITCH_DELAY;
 }
 
-static void picassoiv_checkswitch (void)
+static void picassoiv_checkswitch (struct rtggfxboard *gb)
 {
        if (ISP4()) {
-               bool rtg_active = (picassoiv_flifi & 1) == 0 || (vga.vga.cr[0x51] & 8) == 0;
+               bool rtg_active = (gb->picassoiv_flifi & 1) == 0 || (gb->vga.vga.cr[0x51] & 8) == 0;
                // do not switch to P4 RTG until monitor switch is set to native at least
                // once after reset.
-               if (monswitch_reset && rtg_active)
+               if (gb->monswitch_reset && rtg_active)
                        return;
-               monswitch_reset = false;
-               set_monswitch(rtg_active);
+               gb->monswitch_reset = false;
+               set_monswitch(gb, rtg_active);
        }
 }
 
-static void bput_regtest (uaecptr addr, uae_u8 v)
+static void bput_regtest (struct rtggfxboard *gb, uaecptr addr, uae_u8 v)
 {
        addr += 0x3b0;
        if (addr == 0x3d5) { // CRxx
-               if (vga.vga.cr_index == 0x11) {
-                       if (!(vga.vga.cr[0x11] & 0x10)) {
-                               gfxboard_vblank = false;
+               if (gb->vga.vga.cr_index == 0x11) {
+                       if (!(gb->vga.vga.cr[0x11] & 0x10)) {
+                               gb->gfxboard_vblank = false;
                        }
                }
        }
-       if (!(vga.vga.sr[0x07] & 0x01) && vram_enabled) {
-               remap_vram (vram_offset[0], vram_offset[1], false);
+       if (!(gb->vga.vga.sr[0x07] & 0x01) && gb->vram_enabled) {
+               remap_vram (gb, gb->vram_offset[0], gb->vram_offset[1], false);
        }
-       picassoiv_checkswitch ();
+       picassoiv_checkswitch (gb);
 }
 
-static uae_u8 bget_regtest (uaecptr addr, uae_u8 v)
+static uae_u8 bget_regtest (struct rtggfxboard *gb, uaecptr addr, uae_u8 v)
 {
        addr += 0x3b0;
        // Input Status 0
        if (addr == 0x3c2) {
-               if (gfxboard_vblank) {
+               if (gb->gfxboard_vblank) {
                        // Disable Vertical Interrupt == 0?
                        // Clear Vertical Interrupt == 1
                        // GR17 bit 2 = INTR disable
-                       if (!(vga.vga.cr[0x11] & 0x20) && (vga.vga.cr[0x11] & 0x10) && !(vga.vga.gr[0x17] & 4)) {
+                       if (!(gb->vga.vga.cr[0x11] & 0x20) && (gb->vga.vga.cr[0x11] & 0x10) && !(gb->vga.vga.gr[0x17] & 4)) {
                                v |= 0x80; // VGA Interrupt Pending
                        }
                }
                v |= 0x10; // DAC sensing
        }
        if (addr == 0x3c5) {
-               if (vga.vga.sr_index == 8) {
+               if (gb->vga.vga.sr_index == 8) {
                        // TODO: DDC
                }
        }
@@ -764,41 +786,46 @@ static uae_u8 bget_regtest (uaecptr addr, uae_u8 v)
 
 void vga_io_put(int portnum, uae_u8 v)
 {
-       if (!vgaio)
+       struct rtggfxboard *gb = &rtggfxboards[0];
+       if (!gb->vgaio)
                return;
        portnum -= 0x3b0;
-       bput_regtest(portnum, v);
-       vgaio->write(&vga, portnum, v, 1);
+       bput_regtest(gb, portnum, v);
+       gb->vgaio->write(&gb->vga, portnum, v, 1);
 }
 uae_u8 vga_io_get(int portnum)
 {
+       struct rtggfxboard *gb = &rtggfxboards[0];
        uae_u8 v = 0xff;
-       if (!vgaio)
+       if (!gb->vgaio)
                return v;
        portnum -= 0x3b0;
-       v = vgaio->read(&vga, portnum, 1);
-       v = bget_regtest(portnum, v);
+       v = gb->vgaio->read(&gb->vga, portnum, 1);
+       v = bget_regtest(gb, portnum, v);
        return v;
 }
 void vga_ram_put(int offset, uae_u8 v)
 {
-       if (!vgalowram)
+       struct rtggfxboard *gb = &rtggfxboards[0];
+       if (!gb->vgalowram)
                return;
        offset -= 0xa0000;
-       vgalowram->write(&vga, offset, v, 1);
+       gb->vgalowram->write(&gb->vga, offset, v, 1);
 }
 uae_u8 vga_ram_get(int offset)
 {
-       if (!vgalowram)
+       struct rtggfxboard *gb = &rtggfxboards[0];
+       if (!gb->vgalowram)
                return 0xff;
        offset -= 0xa0000;
-       return vgalowram->read(&vga, offset, 1);
+       return gb->vgalowram->read(&gb->vga, offset, 1);
 }
 
 void *memory_region_get_ram_ptr(MemoryRegion *mr)
 {
-       if (mr->opaque == &vgavramregionptr)
-               return vram;
+       struct rtggfxboard *gb = &rtggfxboards[0];
+       if (mr->opaque == &gb->vgavramregionptr)
+               return gb->vram;
        return NULL;
 }
 
@@ -806,8 +833,9 @@ void memory_region_init_ram(MemoryRegion *mr,
                             const char *name,
                             uint64_t size)
 {
+       struct rtggfxboard *gb = &rtggfxboards[0];
        if (!stricmp (name, "vga.vram")) {
-               vgavramregion.opaque = mr->opaque;
+               gb->vgavramregion.opaque = mr->opaque;
        }
 }
 
@@ -817,30 +845,32 @@ void memory_region_init_io(MemoryRegion *mr,
                            const char *name,
                            uint64_t size)
 {
+       struct rtggfxboard *gb = &rtggfxboards[0];
        if (!stricmp (name, "cirrus-io")) {
-               vgaio = ops;
-               mr->opaque = vgaioregion.opaque;
+               gb->vgaio = ops;
+               mr->opaque = gb->vgaioregion.opaque;
        } else if (!stricmp (name, "cirrus-linear-io")) {
-               vgaram = ops;
+               gb->vgaram = ops;
        } else if (!stricmp (name, "cirrus-low-memory")) {
-               vgalowram = ops;
+               gb->vgalowram = ops;
        } else if (!stricmp (name, "cirrus-mmio")) {
-               vgammio = ops;
+               gb->vgammio = ops;
        }
 }
 
 int is_surface_bgr(DisplaySurface *surface)
 {
-       return board->swap;
+       struct rtggfxboard *gb = &rtggfxboards[0];
+       return gb->board->swap;
 }
 
-static uaecptr fixaddr_bs (uaecptr addr, int mask, int *bs)
+static uaecptr fixaddr_bs (struct rtggfxboard *gb, uaecptr addr, int mask, int *bs)
 {
        bool swapped = false;
        addr &= gfxmem_bank.mask;
-       if (p4z2) {
+       if (gb->p4z2) {
                if (addr < 0x200000) {
-                       addr |= p4_vram_bank[0];
+                       addr |= gb->p4_vram_bank[0];
                        if (addr >= 0x400000 && addr < 0x600000) {
                                *bs = BYTESWAP_WORD;
                                swapped = true;
@@ -849,7 +879,7 @@ static uaecptr fixaddr_bs (uaecptr addr, int mask, int *bs)
                                swapped = true;
                        }
                } else {
-                       addr |= p4_vram_bank[1];
+                       addr |= gb->p4_vram_bank[1];
                        if (addr >= 0x600000 && addr < 0x800000) {
                                *bs = BYTESWAP_WORD;
                                swapped = true;
@@ -860,82 +890,82 @@ static uaecptr fixaddr_bs (uaecptr addr, int mask, int *bs)
                }
        }
 #ifdef JIT
-       if (mask && (vram_offset_enabled || !vram_enabled || swapped || p4z2))
+       if (mask && (gb->vram_offset_enabled || !gb->vram_enabled || swapped || gb->p4z2))
                special_mem |= mask;
 #endif
-       if (vram_offset_enabled) {
+       if (gb->vram_offset_enabled) {
                if (addr & 0x8000) {
-                       addr += vram_offset[1] & ~0x8000;
+                       addr += gb->vram_offset[1] & ~0x8000;
                } else {
-                       addr += vram_offset[0];
+                       addr += gb->vram_offset[0];
                }
        }
        addr &= gfxmem_bank.mask;
        return addr;
 }
 
-STATIC_INLINE uaecptr fixaddr (uaecptr addr, int mask)
+STATIC_INLINE uaecptr fixaddr (struct rtggfxboard *gb, uaecptr addr, int mask)
 {
 #ifdef JIT
-       if (mask && (vram_offset_enabled || !vram_enabled))
+       if (mask && (gb->vram_offset_enabled || !gb->vram_enabled))
                special_mem |= mask;
 #endif
-       if (vram_offset_enabled) {
+       if (gb->vram_offset_enabled) {
                if (addr & 0x8000) {
-                       addr += vram_offset[1] & ~0x8000;
+                       addr += gb->vram_offset[1] & ~0x8000;
                } else {
-                       addr += vram_offset[0];
+                       addr += gb->vram_offset[0];
                }
        }
        addr &= gfxmem_bank.mask;
        return addr;
 }
 
-STATIC_INLINE uaecptr fixaddr (uaecptr addr)
+STATIC_INLINE uaecptr fixaddr (struct rtggfxboard *gb, uaecptr addr)
 {
-       if (vram_offset_enabled) {
+       if (gb->vram_offset_enabled) {
                if (addr & 0x8000) {
-                       addr += vram_offset[1] & ~0x8000;
+                       addr += gb->vram_offset[1] & ~0x8000;
                } else {
-                       addr += vram_offset[0];
+                       addr += gb->vram_offset[0];
                }
        }
        addr &= gfxmem_bank.mask;
        return addr;
 }
 
-STATIC_INLINE const MemoryRegionOps *getvgabank (uaecptr *paddr)
+STATIC_INLINE const MemoryRegionOps *getvgabank (struct rtggfxboard *gb, uaecptr *paddr)
 {
        uaecptr addr = *paddr;
        addr &= gfxmem_bank.mask;
        *paddr = addr;
-       return vgaram;
+       return gb->vgaram;
 }
 
-static uae_u32 gfxboard_lget_vram (uaecptr addr, int bs)
+static uae_u32 gfxboard_lget_vram (struct rtggfxboard *gb, uaecptr addr, int bs)
 {
        uae_u32 v;
-       if (!vram_enabled) {
-               const MemoryRegionOps *bank = getvgabank (&addr);
+       if (!gb->vram_enabled) {
+               const MemoryRegionOps *bank = getvgabank (gb, &addr);
                addr &= gfxmem_bank.mask;
                if (bs < 0) { // WORD
-                       v  = bank->read (&vga, addr + 1, 1) << 24;
-                       v |= bank->read (&vga, addr + 0, 1) << 16;
-                       v |= bank->read (&vga, addr + 3, 1) <<  8;
-                       v |= bank->read (&vga, addr + 2, 1) <<  0;
+                       v  = bank->read (&gb->vga, addr + 1, 1) << 24;
+                       v |= bank->read (&gb->vga, addr + 0, 1) << 16;
+                       v |= bank->read (&gb->vga, addr + 3, 1) <<  8;
+                       v |= bank->read (&gb->vga, addr + 2, 1) <<  0;
                } else if (bs > 0) { // LONG
-                       v  = bank->read (&vga, addr + 3, 1) << 24;
-                       v |= bank->read (&vga, addr + 2, 1) << 16;
-                       v |= bank->read (&vga, addr + 1, 1) <<  8;
-                       v |= bank->read (&vga, addr + 0, 1) <<  0;
+                       v  = bank->read (&gb->vga, addr + 3, 1) << 24;
+                       v |= bank->read (&gb->vga, addr + 2, 1) << 16;
+                       v |= bank->read (&gb->vga, addr + 1, 1) <<  8;
+                       v |= bank->read (&gb->vga, addr + 0, 1) <<  0;
                } else {
-                       v  = bank->read (&vga, addr + 0, 1) << 24;
-                       v |= bank->read (&vga, addr + 1, 1) << 16;
-                       v |= bank->read (&vga, addr + 2, 1) <<  8;
-                       v |= bank->read (&vga, addr + 3, 1) <<  0;
+                       v  = bank->read (&gb->vga, addr + 0, 1) << 24;
+                       v |= bank->read (&gb->vga, addr + 1, 1) << 16;
+                       v |= bank->read (&gb->vga, addr + 2, 1) <<  8;
+                       v |= bank->read (&gb->vga, addr + 3, 1) <<  0;
                }
        } else {
-               uae_u8 *m = vram + addr;
+               uae_u8 *m = gb->vram + addr;
                if (bs < 0) {
                        v  = (*((uae_u16*)(m + 0))) << 16;
                        v |= (*((uae_u16*)(m + 2))) << 0;
@@ -954,20 +984,20 @@ static uae_u32 gfxboard_lget_vram (uaecptr addr, int bs)
 #endif
        return v;
 }
-static uae_u16 gfxboard_wget_vram (uaecptr addr, int bs)
+static uae_u16 gfxboard_wget_vram (struct rtggfxboard *gb, uaecptr addr, int bs)
 {
        uae_u32 v;
-       if (!vram_enabled) {
-               const MemoryRegionOps *bank = getvgabank (&addr);
+       if (!gb->vram_enabled) {
+               const MemoryRegionOps *bank = getvgabank (gb, &addr);
                if (bs) {
-                       v  = bank->read (&vga, addr + 0, 1) <<  0;
-                       v |= bank->read (&vga, addr + 1, 1) <<  8;
+                       v  = bank->read (&gb->vga, addr + 0, 1) <<  0;
+                       v |= bank->read (&gb->vga, addr + 1, 1) <<  8;
                } else {
-                       v  = bank->read (&vga, addr + 0, 1) <<  8;
-                       v |= bank->read (&vga, addr + 1, 1) <<  0;
+                       v  = bank->read (&gb->vga, addr + 0, 1) <<  8;
+                       v |= bank->read (&gb->vga, addr + 1, 1) <<  0;
                }
        } else {
-               uae_u8 *m = vram + addr;
+               uae_u8 *m = gb->vram + addr;
                if (bs)
                        v = *((uae_u16*)m);
                else
@@ -982,20 +1012,20 @@ static uae_u16 gfxboard_wget_vram (uaecptr addr, int bs)
 #endif
        return v;
 }
-static uae_u8 gfxboard_bget_vram (uaecptr addr, int bs)
+static uae_u8 gfxboard_bget_vram (struct rtggfxboard *gb, uaecptr addr, int bs)
 {
        uae_u32 v;
-       if (!vram_enabled) {
-               const MemoryRegionOps *bank = getvgabank (&addr);
+       if (!gb->vram_enabled) {
+               const MemoryRegionOps *bank = getvgabank (gb, &addr);
                if (bs)
-                       v = bank->read (&vga, addr ^ 1, 1);
+                       v = bank->read (&gb->vga, addr ^ 1, 1);
                else
-                       v = bank->read (&vga, addr + 0, 1);
+                       v = bank->read (&gb->vga, addr + 0, 1);
        } else {
                if (bs)
-                       v = vram[addr ^ 1];
+                       v = gb->vram[addr ^ 1];
                else
-                       v = vram[addr];
+                       v = gb->vram[addr];
        }
 #if MEMLOGR
 #if MEMLOGINDIRECT
@@ -1007,7 +1037,7 @@ static uae_u8 gfxboard_bget_vram (uaecptr addr, int bs)
        return v;
 }
 
-static void gfxboard_lput_vram (uaecptr addr, uae_u32 l, int bs)
+static void gfxboard_lput_vram (struct rtggfxboard *gb, uaecptr addr, uae_u32 l, int bs)
 {
 #if MEMDEBUG
        if ((addr & MEMDEBUGMASK) >= MEMDEBUGTEST && l)
@@ -1020,26 +1050,26 @@ static void gfxboard_lput_vram (uaecptr addr, uae_u32 l, int bs)
        if (memlogw)
        write_log (_T("W %08X L %08X\n"), addr, l);
 #endif
-       if (!vram_enabled) {
-               const MemoryRegionOps *bank = getvgabank (&addr);
+       if (!gb->vram_enabled) {
+               const MemoryRegionOps *bank = getvgabank (gb, &addr);
                if (bs < 0) { // WORD
-                       bank->write (&vga, addr + 1, l >> 24, 1);
-                       bank->write (&vga, addr + 0, (l >> 16) & 0xff, 1);
-                       bank->write (&vga, addr + 3, (l >> 8) & 0xff, 1);
-                       bank->write (&vga, addr + 2, (l >> 0) & 0xff, 1);
+                       bank->write (&gb->vga, addr + 1, l >> 24, 1);
+                       bank->write (&gb->vga, addr + 0, (l >> 16) & 0xff, 1);
+                       bank->write (&gb->vga, addr + 3, (l >> 8) & 0xff, 1);
+                       bank->write (&gb->vga, addr + 2, (l >> 0) & 0xff, 1);
                } else if (bs > 0) { // LONG
-                       bank->write (&vga, addr + 3, l >> 24, 1);
-                       bank->write (&vga, addr + 2, (l >> 16) & 0xff, 1);
-                       bank->write (&vga, addr + 1, (l >> 8) & 0xff, 1);
-                       bank->write (&vga, addr + 0, (l >> 0) & 0xff, 1);
+                       bank->write (&gb->vga, addr + 3, l >> 24, 1);
+                       bank->write (&gb->vga, addr + 2, (l >> 16) & 0xff, 1);
+                       bank->write (&gb->vga, addr + 1, (l >> 8) & 0xff, 1);
+                       bank->write (&gb->vga, addr + 0, (l >> 0) & 0xff, 1);
                } else {
-                       bank->write (&vga, addr + 0, l >> 24, 1);
-                       bank->write (&vga, addr + 1, (l >> 16) & 0xff, 1);
-                       bank->write (&vga, addr + 2, (l >> 8) & 0xff, 1);
-                       bank->write (&vga, addr + 3, (l >> 0) & 0xff, 1);
+                       bank->write (&gb->vga, addr + 0, l >> 24, 1);
+                       bank->write (&gb->vga, addr + 1, (l >> 16) & 0xff, 1);
+                       bank->write (&gb->vga, addr + 2, (l >> 8) & 0xff, 1);
+                       bank->write (&gb->vga, addr + 3, (l >> 0) & 0xff, 1);
                }
        } else {
-               uae_u8 *m = vram + addr;
+               uae_u8 *m = gb->vram + addr;
                if (bs < 0) {
                        *((uae_u16*)(m + 0)) = l >> 16;
                        *((uae_u16*)(m + 2)) = l >>  0;
@@ -1050,7 +1080,7 @@ static void gfxboard_lput_vram (uaecptr addr, uae_u32 l, int bs)
                }
        }
 }
-static void gfxboard_wput_vram (uaecptr addr, uae_u16 w, int bs)
+static void gfxboard_wput_vram (struct rtggfxboard *gb, uaecptr addr, uae_u16 w, int bs)
 {
 #if MEMDEBUG
        if ((addr & MEMDEBUGMASK) >= MEMDEBUGTEST && w)
@@ -1063,24 +1093,24 @@ static void gfxboard_wput_vram (uaecptr addr, uae_u16 w, int bs)
        if (memlogw)
        write_log (_T("W %08X W %04X\n"), addr, w & 0xffff);
 #endif
-       if (!vram_enabled) {
-               const MemoryRegionOps *bank = getvgabank (&addr);
+       if (!gb->vram_enabled) {
+               const MemoryRegionOps *bank = getvgabank (gb, &addr);
                if (bs) {
-                       bank->write (&vga, addr + 0, (w >> 0) & 0xff, 1);
-                       bank->write (&vga, addr + 1, w >> 8, 1);
+                       bank->write (&gb->vga, addr + 0, (w >> 0) & 0xff, 1);
+                       bank->write (&gb->vga, addr + 1, w >> 8, 1);
                } else {
-                       bank->write (&vga, addr + 0, w >> 8, 1);
-                       bank->write (&vga, addr + 1, (w >> 0) & 0xff, 1);
+                       bank->write (&gb->vga, addr + 0, w >> 8, 1);
+                       bank->write (&gb->vga, addr + 1, (w >> 0) & 0xff, 1);
                }
        } else {
-               uae_u8 *m = vram + addr;
+               uae_u8 *m = gb->vram + addr;
                if (bs)
                        *((uae_u16*)m) = w;
                else
                        do_put_mem_word ((uae_u16*)m, w);
        }
 }
-static void gfxboard_bput_vram (uaecptr addr, uae_u8 b, int bs)
+static void gfxboard_bput_vram (struct rtggfxboard *gb, uaecptr addr, uae_u8 b, int bs)
 {
 #if MEMDEBUG
        if ((addr & MEMDEBUGMASK) >= MEMDEBUGTEST && b)
@@ -1093,322 +1123,361 @@ static void gfxboard_bput_vram (uaecptr addr, uae_u8 b, int bs)
        if (memlogw)
        write_log (_T("W %08X B %02X\n"), addr, b & 0xff);
 #endif
-       if (!vram_enabled) {
-               const MemoryRegionOps *bank = getvgabank (&addr);
+       if (!gb->vram_enabled) {
+               const MemoryRegionOps *bank = getvgabank (gb, &addr);
 #ifdef JIT
                special_mem |= S_WRITE;
 #endif
                if (bs)
-                       bank->write (&vga, addr ^ 1, b, 1);
+                       bank->write (&gb->vga, addr ^ 1, b, 1);
                else
-                       bank->write (&vga, addr, b, 1);
+                       bank->write (&gb->vga, addr, b, 1);
        } else {
                if (bs)
-                       vram[addr ^ 1] = b;
+                       gb->vram[addr ^ 1] = b;
                else
-                       vram[addr] = b;
+                       gb->vram[addr] = b;
        }
 }
 
+STATIC_INLINE rtggfxboard *getgfxboard(uaecptr addr)
+{
+       return &rtggfxboards[0];
+}
+
 // LONG byteswapped VRAM
 static uae_u32 REGPARAM2 gfxboard_lget_lbsmem (uaecptr addr)
 {
-       addr -= gfxboardmem_start & gfxmem_bank.mask;
-       addr = fixaddr (addr, 0);
+       struct rtggfxboard *gb = getgfxboard(addr);
+       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr = fixaddr(gb, addr, 0);
        if (addr == -1)
                return 0;
-       return gfxboard_lget_vram (addr, BYTESWAP_LONG);
+       return gfxboard_lget_vram (gb, addr, BYTESWAP_LONG);
 }
 static uae_u32 REGPARAM2 gfxboard_wget_lbsmem (uaecptr addr)
 {
-       addr -= gfxboardmem_start & gfxmem_bank.mask;
-       addr = fixaddr (addr, 0);
+       struct rtggfxboard *gb = getgfxboard(addr);
+       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr = fixaddr(gb, addr, 0);
        if (addr == -1)
                return 0;
-       return gfxboard_wget_vram (addr, BYTESWAP_LONG);
+       return gfxboard_wget_vram (gb, addr, BYTESWAP_LONG);
 }
 static uae_u32 REGPARAM2 gfxboard_bget_lbsmem (uaecptr addr)
 {
-       addr -= gfxboardmem_start & gfxmem_bank.mask;
-       addr = fixaddr (addr, 0);
+       struct rtggfxboard *gb = getgfxboard(addr);
+       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr = fixaddr(gb, addr, 0);
        if (addr == -1)
                return 0;
-       return gfxboard_bget_vram (addr, BYTESWAP_LONG);
+       return gfxboard_bget_vram (gb, addr, BYTESWAP_LONG);
 }
 
 static void REGPARAM2 gfxboard_lput_lbsmem (uaecptr addr, uae_u32 l)
 {
-       addr -= gfxboardmem_start & gfxmem_bank.mask;
-       addr = fixaddr (addr, 0);
+       struct rtggfxboard *gb = getgfxboard(addr);
+       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr = fixaddr(gb, addr, 0);
        if (addr == -1)
                return;
-       gfxboard_lput_vram (addr, l, BYTESWAP_LONG);
+       gfxboard_lput_vram (gb, addr, l, BYTESWAP_LONG);
 }
 static void REGPARAM2 gfxboard_wput_lbsmem (uaecptr addr, uae_u32 w)
 {
-       addr -= gfxboardmem_start & gfxmem_bank.mask;
-       addr = fixaddr (addr, 0);
+       struct rtggfxboard *gb = getgfxboard(addr);
+       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr = fixaddr(gb, addr, 0);
        if (addr == -1)
                return;
-       gfxboard_wput_vram (addr, w, BYTESWAP_LONG);
+       gfxboard_wput_vram (gb, addr, w, BYTESWAP_LONG);
 }
 static void REGPARAM2 gfxboard_bput_lbsmem (uaecptr addr, uae_u32 w)
 {
-       addr -= gfxboardmem_start & gfxmem_bank.mask;
-       addr = fixaddr (addr, 0);
+       struct rtggfxboard *gb = getgfxboard(addr);
+       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr = fixaddr(gb, addr, 0);
        if (addr == -1)
                return;
-       gfxboard_bput_vram (addr, w, BYTESWAP_LONG);
+       gfxboard_bput_vram (gb, addr, w, BYTESWAP_LONG);
 }
 
 // WORD byteswapped VRAM
 static uae_u32 REGPARAM2 gfxboard_lget_wbsmem (uaecptr addr)
 {
-       addr -= gfxboardmem_start & gfxmem_bank.mask;
-       addr = fixaddr (addr, 0);
+       struct rtggfxboard *gb = getgfxboard(addr);
+       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr = fixaddr(gb, addr, 0);
        if (addr == -1)
                return 0;
-       return gfxboard_lget_vram (addr, BYTESWAP_WORD);
+       return gfxboard_lget_vram (gb, addr, BYTESWAP_WORD);
 }
 static uae_u32 REGPARAM2 gfxboard_wget_wbsmem (uaecptr addr)
 {
-       addr -= gfxboardmem_start & gfxmem_bank.mask;
-       addr = fixaddr (addr, 0);
+       struct rtggfxboard *gb = getgfxboard(addr);
+       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr = fixaddr(gb, addr, 0);
        if (addr == -1)
                return 0;
-       return gfxboard_wget_vram (addr, BYTESWAP_WORD);
+       return gfxboard_wget_vram (gb, addr, BYTESWAP_WORD);
 }
 static uae_u32 REGPARAM2 gfxboard_bget_wbsmem (uaecptr addr)
 {
-       addr -= gfxboardmem_start & gfxmem_bank.mask;
-       addr = fixaddr (addr, 0);
+       struct rtggfxboard *gb = getgfxboard(addr);
+       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr = fixaddr(gb, addr, 0);
        if (addr == -1)
                return 0;
-       return gfxboard_bget_vram (addr, BYTESWAP_WORD);
+       return gfxboard_bget_vram (gb, addr, BYTESWAP_WORD);
 }
 
 static void REGPARAM2 gfxboard_lput_wbsmem (uaecptr addr, uae_u32 l)
 {
-       addr -= gfxboardmem_start & gfxmem_bank.mask;
-       addr = fixaddr (addr, 0);
+       struct rtggfxboard *gb = getgfxboard(addr);
+       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr = fixaddr(gb, addr, 0);
        if (addr == -1)
                return;
-       gfxboard_lput_vram (addr, l, BYTESWAP_WORD);
+       gfxboard_lput_vram (gb, addr, l, BYTESWAP_WORD);
 }
 static void REGPARAM2 gfxboard_wput_wbsmem (uaecptr addr, uae_u32 w)
 {
-       addr -= gfxboardmem_start & gfxmem_bank.mask;
-       addr = fixaddr (addr, 0);
+       struct rtggfxboard *gb = getgfxboard(addr);
+       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr = fixaddr(gb, addr, 0);
        if (addr == -1)
                return;
-       gfxboard_wput_vram (addr, w, BYTESWAP_WORD);
+       gfxboard_wput_vram (gb, addr, w, BYTESWAP_WORD);
 }
 static void REGPARAM2 gfxboard_bput_wbsmem (uaecptr addr, uae_u32 w)
 {
-       addr -= gfxboardmem_start & gfxmem_bank.mask;
-       addr = fixaddr (addr, 0);
+       struct rtggfxboard *gb = getgfxboard(addr);
+       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr = fixaddr(gb, addr, 0);
        if (addr == -1)
                return;
-       gfxboard_bput_vram (addr, w, BYTESWAP_WORD);
+       gfxboard_bput_vram (gb, addr, w, BYTESWAP_WORD);
 }
 
 // normal or byteswapped (banked) vram
 static uae_u32 REGPARAM2 gfxboard_lget_nbsmem (uaecptr addr)
 {
+       struct rtggfxboard *gb = getgfxboard(addr);
        int bs = 0;
-       addr -= gfxboardmem_start & gfxmem_bank.mask;
-       addr = fixaddr_bs (addr, 0, &bs);
+       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr = fixaddr_bs (gb, addr, 0, &bs);
        if (addr == -1)
                return 0;
 //     activate_debugger();
-       return gfxboard_lget_vram (addr, bs);
+       return gfxboard_lget_vram (gb, addr, bs);
 }
 static uae_u32 REGPARAM2 gfxboard_wget_nbsmem (uaecptr addr)
 {
+       struct rtggfxboard *gb = getgfxboard(addr);
        int bs = 0;
-       addr -= gfxboardmem_start & gfxmem_bank.mask;
-       addr = fixaddr_bs (addr, 0, &bs);
+       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr = fixaddr_bs (gb, addr, 0, &bs);
        if (addr == -1)
                return 0;
-       return gfxboard_wget_vram (addr, bs);
+       return gfxboard_wget_vram (gb, addr, bs);
 }
 
 static void REGPARAM2 gfxboard_lput_nbsmem (uaecptr addr, uae_u32 l)
 {
+       struct rtggfxboard *gb = getgfxboard(addr);
        int bs = 0;
-       addr -= gfxboardmem_start & gfxmem_bank.mask;
-       addr = fixaddr_bs (addr, 0, &bs);
+       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr = fixaddr_bs (gb, addr, 0, &bs);
        if (addr == -1)
                return;
-       gfxboard_lput_vram (addr, l, bs);
+       gfxboard_lput_vram (gb, addr, l, bs);
 }
 static void REGPARAM2 gfxboard_wput_nbsmem (uaecptr addr, uae_u32 w)
 {
+       struct rtggfxboard *gb = getgfxboard(addr);
        int bs = 0;
-       addr -= gfxboardmem_start & gfxmem_bank.mask;
-       addr = fixaddr_bs (addr, 0, &bs);
+       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr = fixaddr_bs (gb, addr, 0, &bs);
        if (addr == -1)
                return;
-       gfxboard_wput_vram (addr, w, bs);
+       gfxboard_wput_vram (gb, addr, w, bs);
 }
 
 static uae_u32 REGPARAM2 gfxboard_bget_bsmem (uaecptr addr)
 {
+       struct rtggfxboard *gb = getgfxboard(addr);
        int bs = 0;
-       addr -= gfxboardmem_start & gfxmem_bank.mask;
-       addr = fixaddr (addr, 0);
+       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr = fixaddr(gb, addr, 0);
        if (addr == -1)
                return 0;
-       return gfxboard_bget_vram (addr, bs);
+       return gfxboard_bget_vram (gb, addr, bs);
 }
 static void REGPARAM2 gfxboard_bput_bsmem (uaecptr addr, uae_u32 b)
 {
+       struct rtggfxboard *gb = getgfxboard(addr);
        int bs = 0;
-       addr -= gfxboardmem_start & gfxmem_bank.mask;
-       addr = fixaddr_bs (addr, 0, &bs);
+       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr = fixaddr_bs (gb, addr, 0, &bs);
        if (addr == -1)
                return;
-       gfxboard_bput_vram (addr, b, bs);
+       gfxboard_bput_vram (gb, addr, b, bs);
 }
 
 // normal vram
 static uae_u32 REGPARAM2 gfxboard_lget_mem (uaecptr addr)
 {
-       addr -= gfxboardmem_start & gfxmem_bank.mask;
-       addr = fixaddr (addr, S_READ);
+       struct rtggfxboard *gb = getgfxboard(addr);
+       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr = fixaddr(gb, addr, S_READ);
        if (addr == -1)
                return 0;
-       return gfxboard_lget_vram (addr, 0);
+       return gfxboard_lget_vram (gb, addr, 0);
 }
 static uae_u32 REGPARAM2 gfxboard_wget_mem (uaecptr addr)
 {
-       addr -= gfxboardmem_start & gfxmem_bank.mask;
-       addr = fixaddr (addr, S_READ);
+       struct rtggfxboard *gb = getgfxboard(addr);
+       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr = fixaddr(gb, addr, S_READ);
        if (addr == -1)
                return 0;
-       return gfxboard_wget_vram (addr, 0);
+       return gfxboard_wget_vram (gb, addr, 0);
 }
 static uae_u32 REGPARAM2 gfxboard_bget_mem (uaecptr addr)
 {
-       addr -= gfxboardmem_start & gfxmem_bank.mask;
-       addr = fixaddr (addr, S_READ);
+       struct rtggfxboard *gb = getgfxboard(addr);
+       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr = fixaddr(gb, addr, S_READ);
        if (addr == -1)
                return 0;
-       return gfxboard_bget_vram (addr, 0);
+       return gfxboard_bget_vram (gb, addr, 0);
 }
 static void REGPARAM2 gfxboard_lput_mem (uaecptr addr, uae_u32 l)
 {
-       addr -= gfxboardmem_start & gfxmem_bank.mask;
-       addr = fixaddr (addr, S_WRITE);
+       struct rtggfxboard *gb = getgfxboard(addr);
+       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr = fixaddr(gb, addr, S_WRITE);
        if (addr == -1)
                return;
-       gfxboard_lput_vram (addr, l, 0);
+       gfxboard_lput_vram (gb, addr, l, 0);
 }
 static void REGPARAM2 gfxboard_wput_mem (uaecptr addr, uae_u32 w)
 {
-       addr -= gfxboardmem_start & gfxmem_bank.mask;
-       addr = fixaddr (addr, S_WRITE);
+       struct rtggfxboard *gb = getgfxboard(addr);
+       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr = fixaddr(gb, addr, S_WRITE);
        if (addr == -1)
                return;
-       gfxboard_wput_vram (addr, w, 0);
+       gfxboard_wput_vram (gb, addr, w, 0);
 }
 static void REGPARAM2 gfxboard_bput_mem (uaecptr addr, uae_u32 b)
 {
-       addr -= gfxboardmem_start & gfxmem_bank.mask;
-       addr = fixaddr (addr, S_WRITE);
+       struct rtggfxboard *gb = getgfxboard(addr);
+       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr = fixaddr(gb, addr, S_WRITE);
        if (addr == -1)
                return;
-       gfxboard_bput_vram (addr, b, 0);
+       gfxboard_bput_vram (gb, addr, b, 0);
 }
 
 // normal vram, no jit direct
 static uae_u32 REGPARAM2 gfxboard_lget_mem_nojit (uaecptr addr)
 {
-       addr -= gfxboardmem_start & gfxmem_bank.mask;
-       addr = fixaddr (addr);
+       struct rtggfxboard *gb = getgfxboard(addr);
+       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr = fixaddr (gb, addr);
        if (addr == -1)
                return 0;
-       return gfxboard_lget_vram (addr, 0);
+       return gfxboard_lget_vram (gb, addr, 0);
 }
 static uae_u32 REGPARAM2 gfxboard_wget_mem_nojit (uaecptr addr)
 {
-       addr -= gfxboardmem_start & gfxmem_bank.mask;
-       addr = fixaddr (addr);
+       struct rtggfxboard *gb = getgfxboard(addr);
+       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr = fixaddr (gb, addr);
        if (addr == -1)
                return 0;
-       return gfxboard_wget_vram (addr, 0);
+       return gfxboard_wget_vram (gb, addr, 0);
 }
 static uae_u32 REGPARAM2 gfxboard_bget_mem_nojit (uaecptr addr)
 {
-       addr -= gfxboardmem_start & gfxmem_bank.mask;
-       addr = fixaddr (addr);
+       struct rtggfxboard *gb = getgfxboard(addr);
+       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr = fixaddr (gb, addr);
        if (addr == -1)
                return 0;
-       return gfxboard_bget_vram (addr, 0);
+       return gfxboard_bget_vram (gb, addr, 0);
 }
 static void REGPARAM2 gfxboard_lput_mem_nojit (uaecptr addr, uae_u32 l)
 {
-       addr -= gfxboardmem_start & gfxmem_bank.mask;
-       addr = fixaddr (addr);
+       struct rtggfxboard *gb = getgfxboard(addr);
+       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr = fixaddr (gb, addr);
        if (addr == -1)
                return;
-       gfxboard_lput_vram (addr, l, 0);
+       gfxboard_lput_vram (gb, addr, l, 0);
 }
 static void REGPARAM2 gfxboard_wput_mem_nojit (uaecptr addr, uae_u32 w)
 {
-       addr -= gfxboardmem_start & gfxmem_bank.mask;
-       addr = fixaddr (addr);
+       struct rtggfxboard *gb = getgfxboard(addr);
+       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr = fixaddr (gb, addr);
        if (addr == -1)
                return;
-       gfxboard_wput_vram (addr, w, 0);
+       gfxboard_wput_vram (gb, addr, w, 0);
 }
 static void REGPARAM2 gfxboard_bput_mem_nojit (uaecptr addr, uae_u32 b)
 {
-       addr -= gfxboardmem_start & gfxmem_bank.mask;
-       addr = fixaddr (addr);
+       struct rtggfxboard *gb = getgfxboard(addr);
+       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
+       addr = fixaddr (gb, addr);
        if (addr == -1)
                return;
-       gfxboard_bput_vram (addr, b, 0);
+       gfxboard_bput_vram (gb, addr, b, 0);
 }
 
 static int REGPARAM2 gfxboard_check (uaecptr addr, uae_u32 size)
 {
-       addr -= gfxboardmem_start & gfxmem_bank.mask;
+       struct rtggfxboard *gb = getgfxboard(addr);
+       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
        addr &= gfxmem_bank.mask;
        return (addr + size) <= currprefs.rtgmem_size;
 }
 static uae_u8 *REGPARAM2 gfxboard_xlate (uaecptr addr)
 {
-       addr -= gfxboardmem_start & gfxmem_bank.mask;
+       struct rtggfxboard *gb = getgfxboard(addr);
+       addr -= gb->gfxboardmem_start & gfxmem_bank.mask;
        addr &= gfxmem_bank.mask;
-       return vram + addr;
+       return gb->vram + addr;
 }
 
 static uae_u32 REGPARAM2 gfxboard_bget_mem_autoconfig (uaecptr addr)
 {
+       struct rtggfxboard *gb = getgfxboard(addr);
        uae_u32 v = 0;
        addr &= 65535;
        if (addr < GFXBOARD_AUTOCONFIG_SIZE)
-               v = automemory[addr];
+               v = gb->automemory[addr];
        return v;
 }
 
 static void REGPARAM2 gfxboard_wput_mem_autoconfig (uaecptr addr, uae_u32 b)
 {
-       if (board->configtype == 2)
+       struct rtggfxboard *gb = getgfxboard(addr);
+       if (gb->board->configtype == 2)
                return;
        b &= 0xffff;
        addr &= 65535;
        if (addr == 0x44) {
                uae_u32 start;
                if (!expamem_z3hack(&currprefs)) {
-                       start = (b & 0xff00) | expamem_lo;
+                       start = (b & 0xff00) | gb->expamem_lo;
                        gfxmem_bank.start = start << 16;
                }
                gfxboard_bank_memory.bget = gfxboard_bget_mem;
                gfxboard_bank_memory.bput = gfxboard_bput_mem;
                gfxboard_bank_memory.wput = gfxboard_wput_mem;
-               init_board ();
+               init_board (gb);
                if (ISP4()) {
                        if (validate_banks_z3(&gfxboard_bank_memory, gfxmem_bank.start >> 16, expamem_z3_size >> 16)) {
                                // main vram
@@ -1421,19 +1490,19 @@ static void REGPARAM2 gfxboard_wput_mem_autoconfig (uaecptr addr, uae_u32 b)
                                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);
                        }
-                       picassoiv_bank = 0;
-                       picassoiv_flifi = 1;
-                       configured_regs = gfxmem_bank.start >> 16;
+                       gb->picassoiv_bank = 0;
+                       gb->picassoiv_flifi = 1;
+                       gb->configured_regs = gfxmem_bank.start >> 16;
                } else {
-                       map_banks_z3(&gfxboard_bank_memory, gfxmem_bank.start >> 16, board->banksize >> 16);
+                       map_banks_z3(&gfxboard_bank_memory, gfxmem_bank.start >> 16, gb->board->banksize >> 16);
                }
-               configured_mem = gfxmem_bank.start >> 16;
-               gfxboardmem_start = gfxmem_bank.start;
+               gb->configured_mem = gfxmem_bank.start >> 16;
+               gb->gfxboardmem_start = gfxmem_bank.start;
                expamem_next (&gfxboard_bank_memory, NULL);
                return;
        }
        if (addr == 0x4c) {
-               configured_mem = 0xff;
+               gb->configured_mem = 0xff;
                expamem_shutup(&gfxboard_bank_memory);
                return;
        }
@@ -1441,19 +1510,20 @@ static void REGPARAM2 gfxboard_wput_mem_autoconfig (uaecptr addr, uae_u32 b)
 
 static void REGPARAM2 gfxboard_bput_mem_autoconfig (uaecptr addr, uae_u32 b)
 {
+       struct rtggfxboard *gb = getgfxboard(addr);
        b &= 0xff;
        addr &= 65535;
        if (addr == 0x48) {
-               if (board->configtype == 2) {
+               if (gb->board->configtype == 2) {
                        addrbank *ab;
                        if (ISP4()) {
                                ab = &gfxboard_bank_nbsmemory;
-                               if (configured_mem == 0)
-                                       init_board ();
+                               if (gb->configured_mem == 0)
+                                       init_board (gb);
                                map_banks_z2 (ab, b, 0x00200000 >> 16);
-                               if (configured_mem == 0) {
-                                       configured_mem = b;
-                                       gfxboardmem_start = b << 16;
+                               if (gb->configured_mem == 0) {
+                                       gb->configured_mem = b;
+                                       gb->gfxboardmem_start = b << 16;
                                } else {
                                        gfxboard_bank_memory.bget = gfxboard_bget_mem;
                                        gfxboard_bank_memory.bput = gfxboard_bput_mem;
@@ -1462,25 +1532,25 @@ static void REGPARAM2 gfxboard_bput_mem_autoconfig (uaecptr addr, uae_u32 b)
                                ab = &gfxboard_bank_memory;
                                gfxboard_bank_memory.bget = gfxboard_bget_mem;
                                gfxboard_bank_memory.bput = gfxboard_bput_mem;
-                               init_board ();
-                               map_banks_z2 (ab, b, board->banksize >> 16);
-                               configured_mem = b;
-                               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;
                        }
                        expamem_next (ab, NULL);
                } else {
-                       expamem_lo = b & 0xff;
+                       gb->expamem_lo = b & 0xff;
                }
                return;
        }
        if (addr == 0x4c) {
-               configured_mem = 0xff;
+               gb->configured_mem = 0xff;
                expamem_shutup(&gfxboard_bank_memory);
                return;
        }
 }
 
-static uaecptr mungeaddr (uaecptr addr, bool write)
+static uaecptr mungeaddr (struct rtggfxboard *gb, uaecptr addr, bool write)
 {
        addr &= 65535;
        if (addr >= 0x2000) {
@@ -1492,13 +1562,13 @@ static uaecptr mungeaddr (uaecptr addr, bool write)
                return 0;
        }
        if (addr >= 0x1000) {
-               if (board->manufacturer == BOARD_MANUFACTURER_PICASSO) {
+               if (gb->board->manufacturer == BOARD_MANUFACTURER_PICASSO) {
                        if (addr == 0x1001) {
-                               gfxboard_intena = true;
+                               gb->gfxboard_intena = true;
                                return 0;
                        }
                        if (addr == 0x1000) {
-                               gfxboard_intena = false;
+                               gb->gfxboard_intena = false;
                                return 0;
                        }
                }
@@ -1523,133 +1593,141 @@ static uaecptr mungeaddr (uaecptr addr, bool write)
 
 static uae_u32 REGPARAM2 gfxboard_lget_regs (uaecptr addr)
 {
+       struct rtggfxboard *gb = getgfxboard(addr);
        uae_u32 v = 0xffffffff;
-       addr = mungeaddr (addr, false);
+       addr = mungeaddr (gb, addr, false);
        if (addr)
-               v = vgaio->read (&vga, addr, 4);
+               v = gb->vgaio->read (&gb->vga, addr, 4);
        return v;
 }
 static uae_u32 REGPARAM2 gfxboard_wget_regs (uaecptr addr)
 {
+       struct rtggfxboard *gb = getgfxboard(addr);
        uae_u16 v = 0xffff;
-       addr = mungeaddr (addr, false);
+       addr = mungeaddr (gb, addr, false);
        if (addr) {
                uae_u8 v1, v2;
-               v1  = vgaio->read (&vga, addr + 0, 1);
-               v1 = bget_regtest (addr + 0, v1);
-               v2 = vgaio->read (&vga, addr + 1, 1);
-               v2 = bget_regtest (addr + 1, v2);
+               v1  = gb->vgaio->read (&gb->vga, addr + 0, 1);
+               v1 = bget_regtest (gb, addr + 0, v1);
+               v2 = gb->vgaio->read (&gb->vga, addr + 1, 1);
+               v2 = bget_regtest (gb, addr + 1, v2);
                v = (v1 << 8) | v2;
        }
        return v;
 }
 static uae_u32 REGPARAM2 gfxboard_bget_regs (uaecptr addr)
 {
+       struct rtggfxboard *gb = getgfxboard(addr);
        uae_u8 v = 0xff;
        addr &= 65535;
        if (addr >= 0x8000) {
                write_log (_T("GFX SPECIAL BGET IO %08X\n"), addr);
                return 0;
        }
-       addr = mungeaddr (addr, false);
+       addr = mungeaddr (gb, addr, false);
        if (addr) {
-               v = vgaio->read (&vga, addr, 1);
-               v = bget_regtest (addr, v);
+               v = gb->vgaio->read (&gb->vga, addr, 1);
+               v = bget_regtest (gb, addr, v);
        }
        return v;
 }
 
 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);
-       addr = mungeaddr (addr, true);
+       addr = mungeaddr (gb, addr, true);
        if (addr) {
-               vgaio->write (&vga, addr + 0, l >> 24, 1);
-               bput_regtest (addr + 0, (l >> 24));
-               vgaio->write (&vga, addr + 1, (l >> 16) & 0xff, 1);
-               bput_regtest (addr + 0, (l >> 16));
-               vgaio->write (&vga, addr + 2, (l >>  8) & 0xff, 1);
-               bput_regtest (addr + 0, (l >>  8));
-               vgaio->write (&vga, addr + 3, (l >>  0) & 0xff, 1);
-               bput_regtest (addr + 0, (l >>  0));
+               gb->vgaio->write (&gb->vga, addr + 0, l >> 24, 1);
+               bput_regtest (gb, addr + 0, (l >> 24));
+               gb->vgaio->write (&gb->vga, addr + 1, (l >> 16) & 0xff, 1);
+               bput_regtest (gb, addr + 0, (l >> 16));
+               gb->vgaio->write (&gb->vga, addr + 2, (l >>  8) & 0xff, 1);
+               bput_regtest (gb, addr + 0, (l >>  8));
+               gb->vgaio->write (&gb->vga, addr + 3, (l >>  0) & 0xff, 1);
+               bput_regtest (gb, addr + 0, (l >>  0));
        }
 }
 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);
-       addr = mungeaddr (addr, true);
+       addr = mungeaddr (gb, addr, true);
        if (addr) {
-               vgaio->write (&vga, addr + 0, (w >> 8) & 0xff, 1);
-               bput_regtest (addr + 0, (w >> 8));
-               vgaio->write (&vga, addr + 1, (w >> 0) & 0xff, 1);
-               bput_regtest (addr + 1, (w >> 0));
+               gb->vgaio->write (&gb->vga, addr + 0, (w >> 8) & 0xff, 1);
+               bput_regtest (gb, addr + 0, (w >> 8));
+               gb->vgaio->write (&gb->vga, addr + 1, (w >> 0) & 0xff, 1);
+               bput_regtest (gb, addr + 1, (w >> 0));
        }
 }
 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);
        addr &= 65535;
        if (addr >= 0x8000) {
                write_log (_T("GFX SPECIAL BPUT IO %08X = %02X\n"), addr, b & 0xff);
-               switch (board->manufacturer)
+               switch (gb->board->manufacturer)
                {
                case BOARD_MANUFACTURER_PICASSO:
                        {
                                if ((addr & 1) == 0) {
                                        int idx = addr >> 12;
                                        if (idx == 0x0b || idx == 0x09) {
-                                               set_monswitch(false);
+                                               set_monswitch(gb, false);
                                        } else if (idx == 0x0a || idx == 0x08) {
-                                               set_monswitch(true);
+                                               set_monswitch(gb, true);
                                        }
                                }
                        }
                break;
                case BOARD_MANUFACTURER_PICCOLO:
                case BOARD_MANUFACTURER_SPECTRUM:
-                       set_monswitch((b & 0x20) != 0);
-                       gfxboard_intena = (b & 0x40) != 0;
+                       set_monswitch(gb, (b & 0x20) != 0);
+                       gb->gfxboard_intena = (b & 0x40) != 0;
                break;
                }
                return;
        }
-       addr = mungeaddr (addr, true);
+       addr = mungeaddr (gb, addr, true);
        if (addr) {
-               vgaio->write (&vga, addr, b & 0xff, 1);
-               bput_regtest (addr, b);
+               gb->vgaio->write (&gb->vga, addr, b & 0xff, 1);
+               bput_regtest (gb, addr, b);
        }
 }
 
 static uae_u32 REGPARAM2 gfxboard_bget_regs_autoconfig (uaecptr addr)
 {
+       struct rtggfxboard *gb = getgfxboard(addr);
        uae_u32 v = 0;
        addr &= 65535;
        if (addr < GFXBOARD_AUTOCONFIG_SIZE)
-               v = automemory[addr];
+               v = gb->automemory[addr];
        return v;
 }
 
 static void REGPARAM2 gfxboard_bput_regs_autoconfig (uaecptr addr, uae_u32 b)
 {
+       struct rtggfxboard *gb = getgfxboard(addr);
        addrbank *ab;
        b &= 0xff;
        addr &= 65535;
        if (addr == 0x48) {
                gfxboard_bank_registers.bget = gfxboard_bget_regs;
                gfxboard_bank_registers.bput = gfxboard_bput_regs;
-               if (p4z2) {
+               if (gb->p4z2) {
                        ab = &gfxboard_bank_special;
                        map_banks_z2(ab, b, gfxboard_bank_special.allocated >> 16);
                } else {
                        ab = &gfxboard_bank_registers;
                        map_banks_z2(ab, b, gfxboard_bank_registers.allocated >> 16);
                }
-               configured_regs = b;
+               gb->configured_regs = b;
                expamem_next (ab, NULL);
                return;
        }
        if (addr == 0x4c) {
-               configured_regs = 0xff;
+               gb->configured_regs = 0xff;
                expamem_next (NULL, NULL);
                return;
        }
@@ -1657,43 +1735,45 @@ static void REGPARAM2 gfxboard_bput_regs_autoconfig (uaecptr addr, uae_u32 b)
 
 void gfxboard_free(void)
 {
+       struct rtggfxboard *gb = &rtggfxboards[0];
        if (currprefs.rtgmem_type == GFXBOARD_A2410) {
                tms_free();
                return;
        }
-       if (vram) {
-               gfxmem_bank.baseaddr = vramrealstart;
+       if (gb->vram) {
+               gfxmem_bank.baseaddr = gb->vramrealstart;
                mapped_free (&gfxmem_bank);
        }
-       vram = NULL;
-       vramrealstart = NULL;
-       xfree (fakesurface_surface);
-       fakesurface_surface = NULL;
-       configured_mem = 0;
-       configured_regs = 0;
-       monswitch_new = false;
-       monswitch_current = false;
-       monswitch_delay = -1;
-       monswitch_reset = true;
-       modechanged = false;
-       gfxboard_vblank = false;
-       gfxboard_intena = false;
-       picassoiv_bank = 0;
+       gb->vram = NULL;
+       gb->vramrealstart = NULL;
+       xfree (gb->fakesurface_surface);
+       gb->fakesurface_surface = NULL;
+       gb->configured_mem = 0;
+       gb->configured_regs = 0;
+       gb->monswitch_new = false;
+       gb->monswitch_current = false;
+       gb->monswitch_delay = -1;
+       gb->monswitch_reset = true;
+       gb->modechanged = false;
+       gb->gfxboard_vblank = false;
+       gb->gfxboard_intena = false;
+       gb->picassoiv_bank = 0;
 }
 
 void gfxboard_reset (void)
 {
+       struct rtggfxboard *gb = &rtggfxboards[0];
        if (currprefs.rtgmem_type == GFXBOARD_A2410) {
                tms_reset();
                return;
        }
        if (currprefs.rtgmem_type >= GFXBOARD_HARDWARE) {
-               board = &boards[currprefs.rtgmem_type - GFXBOARD_HARDWARE];
+               gb->board = &boards[currprefs.rtgmem_type - GFXBOARD_HARDWARE];
                gfxmem_bank.mask = currprefs.rtgmem_size - 1;
        }
        gfxboard_free();
-       if (board) {
-               if (board->configtype == 3)
+       if (gb->board) {
+               if (gb->board->configtype == 3)
                        gfxboard_bank_memory.wput = gfxboard_wput_mem_autoconfig;
                if (reset_func) 
                        reset_func (reset_parm);
@@ -1702,40 +1782,41 @@ void gfxboard_reset (void)
 
 static uae_u32 REGPARAM2 gfxboards_lget_regs (uaecptr addr)
 {
+       struct rtggfxboard *gb = getgfxboard(addr);
        uae_u32 v = 0;
-       addr &= p4_special_mask;
+       addr &= gb->p4_special_mask;
        // pci config
-       if (addr >= 0x400000 || (p4z2 && !(picassoiv_bank & PICASSOIV_BANK_MAPRAM) && (picassoiv_bank & PICASSOIV_BANK_UNMAPFLASH) && ((addr >= 0x800 && addr < 0xc00) || (addr >= 0x1000 && addr < 0x2000)))) {
+       if (addr >= 0x400000 || (gb->p4z2 && !(gb->picassoiv_bank & PICASSOIV_BANK_MAPRAM) && (gb->picassoiv_bank & PICASSOIV_BANK_UNMAPFLASH) && ((addr >= 0x800 && addr < 0xc00) || (addr >= 0x1000 && addr < 0x2000)))) {
                uae_u32 addr2 = addr & 0xffff;
                if (addr2 >= 0x0800 && addr2 < 0x840) {
                        addr2 -= 0x800;
-                       v =  p4_pci[addr2 + 0] << 24;
-                       v |= p4_pci[addr2 + 1] << 16;
-                       v |= p4_pci[addr2 + 2] <<  8;
-                       v |= p4_pci[addr2 + 3] <<  0;
+                       v = gb->p4_pci[addr2 + 0] << 24;
+                       v |= gb->p4_pci[addr2 + 1] << 16;
+                       v |= gb->p4_pci[addr2 + 2] <<  8;
+                       v |= gb->p4_pci[addr2 + 3] <<  0;
 #if PICASSOIV_DEBUG_IO
                        write_log (_T("PicassoIV PCI LGET %08x %08x\n"), addr, v);
 #endif
                } else if (addr2 >= 0x1000 && addr2 < 0x1040) {
                        addr2 -= 0x1000;
-                       v =  cirrus_pci[addr2 + 0] << 24;
-                       v |= cirrus_pci[addr2 + 1] << 16;
-                       v |= cirrus_pci[addr2 + 2] <<  8;
-                       v |= cirrus_pci[addr2 + 3] <<  0;
+                       v = gb->cirrus_pci[addr2 + 0] << 24;
+                       v |= gb->cirrus_pci[addr2 + 1] << 16;
+                       v |= gb->cirrus_pci[addr2 + 2] <<  8;
+                       v |= gb->cirrus_pci[addr2 + 3] <<  0;
 #if PICASSOIV_DEBUG_IO
                        write_log (_T("PicassoIV CL PCI LGET %08x %08x\n"), addr, v);
 #endif
                }
                return v;
        }
-       if (picassoiv_bank & PICASSOIV_BANK_MAPRAM) {
+       if (gb->picassoiv_bank & PICASSOIV_BANK_MAPRAM) {
                // memory mapped io
-               if (addr >= p4_mmiobase && addr < p4_mmiobase + 0x8000) {
-                       uae_u32 addr2 = addr - p4_mmiobase;
-                       v  = vgammio->read(&vga, addr2 + 0, 1) << 24;
-                       v |= vgammio->read(&vga, addr2 + 1, 1) << 16;
-                       v |= vgammio->read(&vga, addr2 + 2, 1) <<  8;
-                       v |= vgammio->read(&vga, addr2 + 3, 1) <<  0;
+               if (addr >= gb->p4_mmiobase && addr < gb->p4_mmiobase + 0x8000) {
+                       uae_u32 addr2 = addr - gb->p4_mmiobase;
+                       v  = gb->vgammio->read(&gb->vga, addr2 + 0, 1) << 24;
+                       v |= gb->vgammio->read(&gb->vga, addr2 + 1, 1) << 16;
+                       v |= gb->vgammio->read(&gb->vga, addr2 + 2, 1) <<  8;
+                       v |= gb->vgammio->read(&gb->vga, addr2 + 3, 1) <<  0;
 #if PICASSOIV_DEBUG_IO
                        write_log (_T("PicassoIV MMIO LGET %08x %08x\n"), addr, v);
 #endif
@@ -1749,34 +1830,35 @@ static uae_u32 REGPARAM2 gfxboards_lget_regs (uaecptr addr)
 }
 static uae_u32 REGPARAM2 gfxboards_wget_regs (uaecptr addr)
 {
+       struct rtggfxboard *gb = getgfxboard(addr);
        uae_u16 v = 0;
-       addr &= p4_special_mask;
+       addr &= gb->p4_special_mask;
        // pci config
-       if (addr >= 0x400000 || (p4z2 && !(picassoiv_bank & PICASSOIV_BANK_MAPRAM) && (picassoiv_bank & PICASSOIV_BANK_UNMAPFLASH) && ((addr >= 0x800 && addr < 0xc00) || (addr >= 0x1000 && addr < 0x2000)))) {
+       if (addr >= 0x400000 || (gb->p4z2 && !(gb->picassoiv_bank & PICASSOIV_BANK_MAPRAM) && (gb->picassoiv_bank & PICASSOIV_BANK_UNMAPFLASH) && ((addr >= 0x800 && addr < 0xc00) || (addr >= 0x1000 && addr < 0x2000)))) {
                uae_u32 addr2 = addr & 0xffff;
                if (addr2 >= 0x0800 && addr2 < 0x840) {
                        addr2 -= 0x800;
-                       v =  p4_pci[addr2 + 0] << 8;
-                       v |= p4_pci[addr2 + 1] << 0;
+                       v = gb->p4_pci[addr2 + 0] << 8;
+                       v |= gb->p4_pci[addr2 + 1] << 0;
 #if PICASSOIV_DEBUG_IO
                        write_log (_T("PicassoIV PCI WGET %08x %04x\n"), addr, v);
 #endif
                } else if (addr2 >= 0x1000 && addr2 < 0x1040) {
                        addr2 -= 0x1000;
-                       v =  cirrus_pci[addr2 + 0] << 8;
-                       v |= cirrus_pci[addr2 + 1] << 0;
+                       v = gb->cirrus_pci[addr2 + 0] << 8;
+                       v |= gb->cirrus_pci[addr2 + 1] << 0;
 #if PICASSOIV_DEBUG_IO
                        write_log (_T("PicassoIV CL PCI WGET %08x %04x\n"), addr, v);
 #endif
                }
                return v;
        }
-       if (picassoiv_bank & PICASSOIV_BANK_MAPRAM) {
+       if (gb->picassoiv_bank & PICASSOIV_BANK_MAPRAM) {
                // memory mapped io
-               if (addr >= p4_mmiobase && addr < p4_mmiobase + 0x8000) {
-                       uae_u32 addr2 = addr - p4_mmiobase;
-                       v  = vgammio->read(&vga, addr2 + 0, 1) << 8;
-                       v |= vgammio->read(&vga, addr2 + 1, 1) << 0;
+               if (addr >= gb->p4_mmiobase && addr < gb->p4_mmiobase + 0x8000) {
+                       uae_u32 addr2 = addr - gb->p4_mmiobase;
+                       v  = gb->vgammio->read(&gb->vga, addr2 + 0, 1) << 8;
+                       v |= gb->vgammio->read(&gb->vga, addr2 + 1, 1) << 0;
 #if PICASSOIV_DEBUG_IO
                        write_log (_T("PicassoIV MMIO WGET %08x %04x\n"), addr, v & 0xffff);
 #endif
@@ -1790,16 +1872,17 @@ static uae_u32 REGPARAM2 gfxboards_wget_regs (uaecptr addr)
 }
 static uae_u32 REGPARAM2 gfxboards_bget_regs (uaecptr addr)
 {
+       struct rtggfxboard *gb = getgfxboard(addr);
        uae_u8 v = 0xff;
-       addr &= p4_special_mask;
+       addr &= gb->p4_special_mask;
 
        // pci config
-       if (addr >= 0x400000 || (p4z2 && !(picassoiv_bank & PICASSOIV_BANK_MAPRAM) && (picassoiv_bank & PICASSOIV_BANK_UNMAPFLASH) && ((addr >= 0x800 && addr < 0xc00) || (addr >= 0x1000 && addr < 0x2000)))) {
+       if (addr >= 0x400000 || (gb->p4z2 && !(gb->picassoiv_bank & PICASSOIV_BANK_MAPRAM) && (gb->picassoiv_bank & PICASSOIV_BANK_UNMAPFLASH) && ((addr >= 0x800 && addr < 0xc00) || (addr >= 0x1000 && addr < 0x2000)))) {
                uae_u32 addr2 = addr & 0xffff;
                v = 0;
                if (addr2 >= 0x0800 && addr2 < 0x840) {
                        addr2 -= 0x800;
-                       v =  p4_pci[addr2];
+                       v = gb->p4_pci[addr2];
 #if PICASSOIV_DEBUG_IO
                        write_log (_T("PicassoIV PCI BGET %08x %02x\n"), addr, v);
 #endif
@@ -1813,7 +1896,7 @@ static uae_u32 REGPARAM2 gfxboards_bget_regs (uaecptr addr)
 #endif
                } else if (addr2 >= 0x1000 && addr2 <= 0x1040) {
                        addr2 -= 0x1000;
-                       v = cirrus_pci[addr2];
+                       v = gb->cirrus_pci[addr2];
 #if PICASSOIV_DEBUG_IO
                        write_log (_T("PicassoIV CL PCI BGET %08x %02x\n"), addr, v);
 #endif
@@ -1821,11 +1904,11 @@ static uae_u32 REGPARAM2 gfxboards_bget_regs (uaecptr addr)
                return v;
        }
 
-       if (picassoiv_bank & PICASSOIV_BANK_MAPRAM) {
+       if (gb->picassoiv_bank & PICASSOIV_BANK_MAPRAM) {
                // memory mapped io
-               if (addr >= p4_mmiobase && addr < p4_mmiobase + 0x8000) {
-                       uae_u32 addr2 = addr - p4_mmiobase;
-                       v = vgammio->read(&vga, addr2, 1);
+               if (addr >= gb->p4_mmiobase && addr < gb->p4_mmiobase + 0x8000) {
+                       uae_u32 addr2 = addr - gb->p4_mmiobase;
+                       v = gb->vgammio->read(&gb->vga, addr2, 1);
 #if PICASSOIV_DEBUG_IO
                        write_log (_T("PicassoIV MMIO BGET %08x %02x\n"), addr, v & 0xff);
 #endif
@@ -1833,10 +1916,10 @@ static uae_u32 REGPARAM2 gfxboards_bget_regs (uaecptr addr)
                }
        }
        if (addr == 0) {
-               v = picassoiv_bank;
+               v = gb->picassoiv_bank;
                return v;
        }
-       if (picassoiv_bank & PICASSOIV_BANK_UNMAPFLASH) {
+       if (gb->picassoiv_bank & PICASSOIV_BANK_UNMAPFLASH) {
                v = 0;
                if (addr == 0x404) {
                        v = 0x70; // FLIFI revision
@@ -1846,13 +1929,13 @@ static uae_u32 REGPARAM2 gfxboards_bget_regs (uaecptr addr)
                        else
                                v |= 8;
                } else if (addr == 0x408) {
-                       v = gfxboard_vblank ? 0x80 : 0;
-               } else if (p4z2 && addr >= 0x10000) {
+                       v = gb->gfxboard_vblank ? 0x80 : 0;
+               } else if (gb->p4z2 && addr >= 0x10000) {
                        addr -= 0x10000;
-                       uaecptr addr2 = mungeaddr (addr, true);
+                       uaecptr addr2 = mungeaddr (gb, addr, true);
                        if (addr2) {
-                               v = vgaio->read (&vga, addr2, 1);
-                               v = bget_regtest (addr2, v);
+                               v = gb->vgaio->read (&gb->vga, addr2, 1);
+                               v = bget_regtest (gb, addr2, v);
                        }
                        //write_log (_T("PicassoIV IO %08x %02x\n"), addr, v);
                        return v;
@@ -1863,54 +1946,55 @@ static uae_u32 REGPARAM2 gfxboards_bget_regs (uaecptr addr)
 #endif
        } else {
                if (addr < PICASSOIV_FLASH_OFFSET) {
-                       v = automemory[addr];
+                       v = gb->automemory[addr];
                        return v;
                }
                addr -= PICASSOIV_FLASH_OFFSET;
                addr /= 2;
-               v = automemory[addr + PICASSOIV_FLASH_OFFSET + ((picassoiv_bank & PICASSOIV_BANK_FLASHBANK) ? 0x8000 : 0)];
+               v = gb->automemory[addr + PICASSOIV_FLASH_OFFSET + ((gb->picassoiv_bank & PICASSOIV_BANK_FLASHBANK) ? 0x8000 : 0)];
        }
        return v;
 }
 static void REGPARAM2 gfxboards_lput_regs (uaecptr addr, uae_u32 l)
 {
-       addr &= p4_special_mask;
-       if (addr >= 0x400000 || (p4z2 && !(picassoiv_bank & PICASSOIV_BANK_MAPRAM) && (picassoiv_bank & PICASSOIV_BANK_UNMAPFLASH) && ((addr >= 0x800 && addr < 0xc00) || (addr >= 0x1000 && addr < 0x2000)))) {
+       struct rtggfxboard *gb = getgfxboard(addr);
+       addr &= gb->p4_special_mask;
+       if (addr >= 0x400000 || (gb->p4z2 && !(gb->picassoiv_bank & PICASSOIV_BANK_MAPRAM) && (gb->picassoiv_bank & PICASSOIV_BANK_UNMAPFLASH) && ((addr >= 0x800 && addr < 0xc00) || (addr >= 0x1000 && addr < 0x2000)))) {
                uae_u32 addr2 = addr & 0xffff;
                if (addr2 >= 0x0800 && addr2 < 0x840) {
                        addr2 -= 0x800;
 #if PICASSOIV_DEBUG_IO
                        write_log (_T("PicassoIV PCI LPUT %08x %08x\n"), addr, l);
 #endif
-                       p4_pci[addr2 + 0] = l >> 24;
-                       p4_pci[addr2 + 1] = l >> 16;
-                       p4_pci[addr2 + 2] = l >>  8;
-                       p4_pci[addr2 + 3] = l >>  0;
-                       p4_pci_check ();
+                       gb->p4_pci[addr2 + 0] = l >> 24;
+                       gb->p4_pci[addr2 + 1] = l >> 16;
+                       gb->p4_pci[addr2 + 2] = l >>  8;
+                       gb->p4_pci[addr2 + 3] = l >>  0;
+                       p4_pci_check (gb);
                } else if (addr2 >= 0x1000 && addr2 < 0x1040) {
                        addr2 -= 0x1000;
 #if PICASSOIV_DEBUG_IO
                        write_log (_T("PicassoIV CL PCI LPUT %08x %08x\n"), addr, l);
 #endif
-                       cirrus_pci[addr2 + 0] = l >> 24;
-                       cirrus_pci[addr2 + 1] = l >> 16;
-                       cirrus_pci[addr2 + 2] = l >>  8;
-                       cirrus_pci[addr2 + 3] = l >>  0;
-                       reset_pci ();
+                       gb->cirrus_pci[addr2 + 0] = l >> 24;
+                       gb->cirrus_pci[addr2 + 1] = l >> 16;
+                       gb->cirrus_pci[addr2 + 2] = l >>  8;
+                       gb->cirrus_pci[addr2 + 3] = l >>  0;
+                       reset_pci (gb);
                }
                return;
        }
-       if (picassoiv_bank & PICASSOIV_BANK_MAPRAM) {
+       if (gb->picassoiv_bank & PICASSOIV_BANK_MAPRAM) {
                // memory mapped io
-               if (addr >= p4_mmiobase && addr < p4_mmiobase + 0x8000) {
+               if (addr >= gb->p4_mmiobase && addr < gb->p4_mmiobase + 0x8000) {
 #if PICASSOIV_DEBUG_IO
                        write_log (_T("PicassoIV MMIO LPUT %08x %08x\n"), addr, l);
 #endif
-                       uae_u32 addr2 = addr - p4_mmiobase;
-                       vgammio->write(&vga, addr2 + 0, l >> 24, 1);
-                       vgammio->write(&vga, addr2 + 1, l >> 16, 1);
-                       vgammio->write(&vga, addr2 + 2, l >>  8, 1);
-                       vgammio->write(&vga, addr2 + 3, l >>  0, 1);
+                       uae_u32 addr2 = addr - gb->p4_mmiobase;
+                       gb->vgammio->write(&gb->vga, addr2 + 0, l >> 24, 1);
+                       gb->vgammio->write(&gb->vga, addr2 + 1, l >> 16, 1);
+                       gb->vgammio->write(&gb->vga, addr2 + 2, l >>  8, 1);
+                       gb->vgammio->write(&gb->vga, addr2 + 3, l >>  0, 1);
                        return;
                }
        }
@@ -1920,49 +2004,50 @@ static void REGPARAM2 gfxboards_lput_regs (uaecptr addr, uae_u32 l)
 }
 static void REGPARAM2 gfxboards_wput_regs (uaecptr addr, uae_u32 v)
 {
+       struct rtggfxboard *gb = getgfxboard(addr);
        uae_u16 w = (uae_u16)v;
-       addr &= p4_special_mask;
-       if (addr >= 0x400000 || (p4z2 && !(picassoiv_bank & PICASSOIV_BANK_MAPRAM) && (picassoiv_bank & PICASSOIV_BANK_UNMAPFLASH) && ((addr >= 0x800 && addr < 0xc00) || (addr >= 0x1000 && addr < 0x2000)))) {
+       addr &= gb->p4_special_mask;
+       if (addr >= 0x400000 || (gb->p4z2 && !(gb->picassoiv_bank & PICASSOIV_BANK_MAPRAM) && (gb->picassoiv_bank & PICASSOIV_BANK_UNMAPFLASH) && ((addr >= 0x800 && addr < 0xc00) || (addr >= 0x1000 && addr < 0x2000)))) {
                uae_u32 addr2 = addr & 0xffff;
                if (addr2 >= 0x0800 && addr2 < 0x840) {
                        addr2 -= 0x800;
 #if PICASSOIV_DEBUG_IO
                        write_log (_T("PicassoIV PCI WPUT %08x %04x\n"), addr, w & 0xffff);
 #endif
-                       p4_pci[addr2 + 0] = w >> 8;
-                       p4_pci[addr2 + 1] = w >> 0;
-                       p4_pci_check ();
+                       gb->p4_pci[addr2 + 0] = w >> 8;
+                       gb->p4_pci[addr2 + 1] = w >> 0;
+                       p4_pci_check (gb);
                } else if (addr2 >= 0x1000 && addr2 < 0x1040) {
                        addr2 -= 0x1000;
 #if PICASSOIV_DEBUG_IO
                        write_log (_T("PicassoIV CL PCI WPUT %08x %04x\n"), addr, w & 0xffff);
 #endif
-                       cirrus_pci[addr2 + 0] = w >> 8;
-                       cirrus_pci[addr2 + 1] = w >> 0;
-                       reset_pci ();
+                       gb->cirrus_pci[addr2 + 0] = w >> 8;
+                       gb->cirrus_pci[addr2 + 1] = w >> 0;
+                       reset_pci (gb);
                }
                return;
        }
-       if (picassoiv_bank & PICASSOIV_BANK_MAPRAM) {
+       if (gb->picassoiv_bank & PICASSOIV_BANK_MAPRAM) {
                // memory mapped io
-               if (addr >= p4_mmiobase && addr < p4_mmiobase + 0x8000) {
+               if (addr >= gb->p4_mmiobase && addr < gb->p4_mmiobase + 0x8000) {
 #if PICASSOIV_DEBUG_IO
                        write_log (_T("PicassoIV MMIO LPUT %08x %08x\n"), addr, w & 0xffff);
 #endif
-                       uae_u32 addr2 = addr - p4_mmiobase;
-                       vgammio->write(&vga, addr2 + 0, w >> 8, 1);
-                       vgammio->write(&vga, addr2 + 1, (w >> 0) & 0xff, 1);
+                       uae_u32 addr2 = addr - gb->p4_mmiobase;
+                       gb->vgammio->write(&gb->vga, addr2 + 0, w >> 8, 1);
+                       gb->vgammio->write(&gb->vga, addr2 + 1, (w >> 0) & 0xff, 1);
                        return;
                }
        }
-       if (p4z2 && addr >= 0x10000) {
+       if (gb->p4z2 && addr >= 0x10000) {
                addr -= 0x10000;
-               addr = mungeaddr (addr, true);
+               addr = mungeaddr (gb, addr, true);
                if (addr) {
-                       vgaio->write (&vga, addr + 0, w >> 8, 1);
-                       bput_regtest (addr + 0, w >> 8);
-                       vgaio->write (&vga, addr + 1, (w >> 0) & 0xff, 1);
-                       bput_regtest (addr + 1, w >> 0);
+                       gb->vgaio->write (&gb->vga, addr + 0, w >> 8, 1);
+                       bput_regtest (gb, addr + 0, w >> 8);
+                       gb->vgaio->write (&gb->vga, addr + 1, (w >> 0) & 0xff, 1);
+                       bput_regtest (gb, addr + 1, w >> 0);
                }
                return;
        }
@@ -1973,50 +2058,51 @@ static void REGPARAM2 gfxboards_wput_regs (uaecptr addr, uae_u32 v)
 
 static void REGPARAM2 gfxboards_bput_regs (uaecptr addr, uae_u32 v)
 {
+       struct rtggfxboard *gb = getgfxboard(addr);
        uae_u8 b = (uae_u8)v;
-       addr &= p4_special_mask;
-       if (addr >= 0x400000 || (p4z2 && !(picassoiv_bank & PICASSOIV_BANK_MAPRAM) && (picassoiv_bank & PICASSOIV_BANK_UNMAPFLASH) && ((addr >= 0x800 && addr < 0xc00) || (addr >= 0x1000 && addr < 0x2000)))) {
+       addr &= gb->p4_special_mask;
+       if (addr >= 0x400000 || (gb->p4z2 && !(gb->picassoiv_bank & PICASSOIV_BANK_MAPRAM) && (gb->picassoiv_bank & PICASSOIV_BANK_UNMAPFLASH) && ((addr >= 0x800 && addr < 0xc00) || (addr >= 0x1000 && addr < 0x2000)))) {
                uae_u32 addr2 = addr & 0xffff;
                if (addr2 >= 0x0800 && addr2 < 0x840) {
                        addr2 -= 0x800;
-                       p4_pci[addr2] = b;
-                       p4_pci_check ();
+                       gb->p4_pci[addr2] = b;
+                       p4_pci_check (gb);
 #if PICASSOIV_DEBUG_IO
                        write_log (_T("PicassoIV PCI BPUT %08x %02x\n"), addr, b & 0xff);
 #endif
                } else if (addr2 >= 0x1000 && addr2 < 0x1040) {
                        addr2 -= 0x1000;
-                       cirrus_pci[addr2] = b;
-                       reset_pci ();
+                       gb->cirrus_pci[addr2] = b;
+                       reset_pci (gb);
 #if PICASSOIV_DEBUG_IO
                        write_log (_T("PicassoIV CL PCI BPUT %08x %02x\n"), addr, b & 0xff);
 #endif
                }
                return;
        }
-       if (picassoiv_bank & PICASSOIV_BANK_UNMAPFLASH) {
+       if (gb->picassoiv_bank & PICASSOIV_BANK_UNMAPFLASH) {
                if (addr == 0x404) {
-                       picassoiv_flifi = b;
-                       picassoiv_checkswitch ();
+                       gb->picassoiv_flifi = b;
+                       picassoiv_checkswitch (gb);
                }
        }
-       if (picassoiv_bank & PICASSOIV_BANK_MAPRAM) {
+       if (gb->picassoiv_bank & PICASSOIV_BANK_MAPRAM) {
                // memory mapped io
-               if (addr >= p4_mmiobase && addr < p4_mmiobase + 0x8000) {
+               if (addr >= gb->p4_mmiobase && addr < gb->p4_mmiobase + 0x8000) {
 #if PICASSOIV_DEBUG_IO
                        write_log (_T("PicassoIV MMIO BPUT %08x %08x\n"), addr, b & 0xff);
 #endif
-                       uae_u32 addr2 = addr - p4_mmiobase;
-                       vgammio->write(&vga, addr2, b, 1);
+                       uae_u32 addr2 = addr - gb->p4_mmiobase;
+                       gb->vgammio->write(&gb->vga, addr2, b, 1);
                        return;
                }
        }
-       if (p4z2 && addr >= 0x10000) {
+       if (gb->p4z2 && addr >= 0x10000) {
                addr -= 0x10000;
-               addr = mungeaddr (addr, true);
+               addr = mungeaddr (gb, addr, true);
                if (addr) {
-                       vgaio->write (&vga, addr, b & 0xff, 1);
-                       bput_regtest (addr, b);
+                       gb->vgaio->write (&gb->vga, addr, b & 0xff, 1);
+                       bput_regtest (gb, addr, b);
                }
                return;
        }
@@ -2024,7 +2110,7 @@ static void REGPARAM2 gfxboards_bput_regs (uaecptr addr, uae_u32 v)
        write_log (_T("PicassoIV BPUT %08x %02X\n"), addr, b & 0xff);
 #endif
        if (addr == 0) {
-               picassoiv_bank = b;
+               gb->picassoiv_bank = b;
        }
 }
 
@@ -2061,16 +2147,18 @@ int gfxboard_get_configtype(int type)
                return 2;
        if (type == GFXBOARD_UAE_Z3)
                return 3;
-       board = &boards[type - GFXBOARD_HARDWARE];
-       return board->configtype;
+       struct rtggfxboard *gb = &rtggfxboards[0];
+       gb->board = &boards[type - GFXBOARD_HARDWARE];
+       return gb->board->configtype;
 }
 
 bool gfxboard_need_byteswap (int type)
 {
        if (type < GFXBOARD_HARDWARE)
                return false;
-       board = &boards[type - GFXBOARD_HARDWARE];
-       return board->swap;
+       struct rtggfxboard *gb = &rtggfxboards[0];
+       gb->board = &boards[type - GFXBOARD_HARDWARE];
+       return gb->board->swap;
 }
 
 int gfxboard_get_autoconfig_size(int type)
@@ -2084,34 +2172,38 @@ int gfxboard_get_vram_min (int type)
 {
        if (type < GFXBOARD_HARDWARE)
                return -1;
-       board = &boards[type - GFXBOARD_HARDWARE];
-       return board->vrammin;
+       struct rtggfxboard *gb = &rtggfxboards[0];
+       gb->board = &boards[type - GFXBOARD_HARDWARE];
+       return gb->board->vrammin;
 }
 
 int gfxboard_get_vram_max (int type)
 {
        if (type < GFXBOARD_HARDWARE)
                return -1;
-       board = &boards[type - GFXBOARD_HARDWARE];
-       return board->vrammax;
+       struct rtggfxboard *gb = &rtggfxboards[0];
+       gb->board = &boards[type - GFXBOARD_HARDWARE];
+       return gb->board->vrammax;
 }
 
 bool gfxboard_is_registers (int type)
 {
        if (type < 2)
                return false;
-       board = &boards[type - 2];
-       return board->model_registers != 0;
+       struct rtggfxboard *gb = &rtggfxboards[0];
+       gb->board = &boards[type - 2];
+       return gb->board->model_registers != 0;
 }
 
 int gfxboard_num_boards (int type)
 {
        if (type < 2)
                return 1;
-       board = &boards[type - 2];
+       struct rtggfxboard *gb = &rtggfxboards[0];
+       gb->board = &boards[type - 2];
        if (type == GFXBOARD_PICASSO4_Z2)
                return 3;
-       if (board->model_registers == 0)
+       if (gb->board->model_registers == 0)
                return 1;
        return 2;
 }
@@ -2120,106 +2212,108 @@ uae_u32 gfxboard_get_romtype(int type)
 {
        if (type < 2)
                return 0;
-       board = &boards[type - 2];
-       return board->romtype;
+       struct rtggfxboard *gb = &rtggfxboards[0];
+       gb->board = &boards[type - 2];
+       return gb->board->romtype;
 }
 
-static void gfxboard_init (void)
+static void gfxboard_init (struct rtggfxboard *gb)
 {
-       if (!automemory)
-               automemory = xmalloc (uae_u8, GFXBOARD_AUTOCONFIG_SIZE);
-       memset (automemory, 0xff, GFXBOARD_AUTOCONFIG_SIZE);
-       p4z2 = false;
-       zfile_fclose (p4rom);
-       p4rom = NULL;
-       banksize_mask = board->banksize - 1;
-       memset (cirrus_pci, 0, sizeof cirrus_pci);
-       reset_pci ();
+       if (!gb->automemory)
+               gb->automemory = xmalloc (uae_u8, GFXBOARD_AUTOCONFIG_SIZE);
+       memset (gb->automemory, 0xff, GFXBOARD_AUTOCONFIG_SIZE);
+       gb->p4z2 = false;
+       zfile_fclose (gb->p4rom);
+       gb->p4rom = NULL;
+       gb->banksize_mask = gb->board->banksize - 1;
+       memset (gb->cirrus_pci, 0, sizeof gb->cirrus_pci);
+       reset_pci (gb);
 }
 
-static void copyp4autoconfig (int startoffset)
+static void copyp4autoconfig (struct rtggfxboard *gb, int startoffset)
 {
        int size = 0;
        int offset = 0;
-       memset (automemory, 0xff, 64);
+       memset (gb->automemory, 0xff, 64);
        while (size < 32) {
-               uae_u8 b = p4autoconfig[size + startoffset];
-               automemory[offset] = b;
+               uae_u8 b = gb->p4autoconfig[size + startoffset];
+               gb->automemory[offset] = b;
                offset += 2;
                size++;
        }
 }
 
-static void loadp4rom (void)
+static void loadp4rom (struct rtggfxboard *gb)
 {
        int size, offset;
        uae_u8 b;
        // rom loader code
-       zfile_fseek (p4rom, 256, SEEK_SET);
+       zfile_fseek (gb->p4rom, 256, SEEK_SET);
        offset = PICASSOIV_ROM_OFFSET;
        size = 0;
        while (size < 4096 - 256) {
-               if (!zfile_fread (&b, 1, 1, p4rom))
+               if (!zfile_fread (&b, 1, 1, gb->p4rom))
                        break;
-               automemory[offset] = b;
+               gb->automemory[offset] = b;
                offset += 2;
                size++;
        }
        // main flash code
-       zfile_fseek (p4rom, 16384, SEEK_SET);
-       zfile_fread (&automemory[PICASSOIV_FLASH_OFFSET], 1, PICASSOIV_MAX_FLASH, p4rom);
-       zfile_fclose (p4rom);
-       p4rom = NULL;
+       zfile_fseek (gb->p4rom, 16384, SEEK_SET);
+       zfile_fread (&gb->automemory[PICASSOIV_FLASH_OFFSET], 1, PICASSOIV_MAX_FLASH, gb->p4rom);
+       zfile_fclose (gb->p4rom);
+       gb->p4rom = NULL;
        write_log (_T("PICASSOIV: flash rom loaded\n"));
 }
 
-static void ew (int addr, uae_u32 value)
+static void ew (struct rtggfxboard *gb, int addr, uae_u32 value)
 {
        addr &= 0xffff;
        if (addr == 00 || addr == 02 || addr == 0x40 || addr == 0x42) {
-               automemory[addr] = (value & 0xf0);
-               automemory[addr + 2] = (value & 0x0f) << 4;
+               gb->automemory[addr] = (value & 0xf0);
+               gb->automemory[addr + 2] = (value & 0x0f) << 4;
        } else {
-               automemory[addr] = ~(value & 0xf0);
-               automemory[addr + 2] = ~((value & 0x0f) << 4);
+               gb->automemory[addr] = ~(value & 0xf0);
+               gb->automemory[addr + 2] = ~((value & 0x0f) << 4);
        }
 }
 
 addrbank *gfxboard_init_memory (int devnum)
 {
+       struct rtggfxboard *gb = &rtggfxboards[0];
        int bank;
        uae_u8 z2_flags, z3_flags, type;
 
-       gfxboard_init ();
+       gfxboard_init (gb);
 
-       memset (automemory, 0xff, GFXBOARD_AUTOCONFIG_SIZE);
+       memset (gb->automemory, 0xff, GFXBOARD_AUTOCONFIG_SIZE);
        
        z2_flags = 0x05; // 1M
        z3_flags = 0x06; // 1M
-       bank = board->banksize;
+       bank = gb->board->banksize;
        bank /= 0x00100000;
        while (bank > 1) {
                z2_flags++;
                z3_flags++;
                bank >>= 1;
        }
-       if (board->configtype == 3) {
+       if (gb->board->configtype == 3) {
                type = 0x00 | 0x08 | 0x80; // 16M Z3
-               ew (0x08, z3_flags | 0x10 | 0x20);
+               ew (gb, 0x08, z3_flags | 0x10 | 0x20);
        } else {
                type = z2_flags | 0x08 | 0xc0;
        }
-       ew (0x04, board->model_memory);
-       ew (0x10, board->manufacturer >> 8);
-       ew (0x14, board->manufacturer);
+       ew (gb, 0x04, gb->board->model_memory);
+       ew (gb, 0x10, gb->board->manufacturer >> 8);
+       ew (gb, 0x14, gb->board->manufacturer);
 
-       uae_u32 ser = board->serial;
-       ew (0x18, ser >> 24); /* ser.no. Byte 0 */
-       ew (0x1c, ser >> 16); /* ser.no. Byte 1 */
-       ew (0x20, ser >>  8); /* ser.no. Byte 2 */
-       ew (0x24, ser >>  0); /* ser.no. Byte 3 */
+       uae_u32 ser = gb->board->serial;
+       ew (gb, 0x18, ser >> 24); /* ser.no. Byte 0 */
+       ew (gb, 0x1c, ser >> 16); /* ser.no. Byte 1 */
+       ew (gb, 0x20, ser >>  8); /* ser.no. Byte 2 */
+       ew (gb, 0x24, ser >>  0); /* ser.no. Byte 3 */
 
-       ew (0x00, type);
+       ew (gb, 0x00, type);
 
        if (ISP4()) {
                int roms[] = { 91, -1 };
@@ -2227,57 +2321,57 @@ addrbank *gfxboard_init_memory (int devnum)
                TCHAR path[MAX_DPATH];
                fetch_rompath (path, sizeof path / sizeof (TCHAR));
 
-               p4rom = read_device_rom(&currprefs, ROMTYPE_PICASSOIV, 0, roms);
+               gb->p4rom = read_device_rom(&currprefs, ROMTYPE_PICASSOIV, 0, roms);
 
-               if (!p4rom && currprefs.picassoivromfile[0] && zfile_exists(currprefs.picassoivromfile))
-                       p4rom = read_rom_name(currprefs.picassoivromfile);
+               if (!gb->p4rom && currprefs.picassoivromfile[0] && zfile_exists(currprefs.picassoivromfile))
+                       gb->p4rom = read_rom_name(currprefs.picassoivromfile);
 
-               if (!p4rom && rl)
-                       p4rom = read_rom(rl->rd);
+               if (!gb->p4rom && rl)
+                       gb->p4rom = read_rom(rl->rd);
 
-               if (!p4rom) {
+               if (!gb->p4rom) {
                        _tcscat (path, _T("picasso_iv_flash.rom"));
-                       p4rom = read_rom_name (path);
-                       if (!p4rom)
-                               p4rom = read_rom_name (_T("picasso_iv_flash.rom"));
+                       gb->p4rom = read_rom_name (path);
+                       if (!gb->p4rom)
+                               gb->p4rom = read_rom_name (_T("picasso_iv_flash.rom"));
                }
-               if (p4rom) {
-                       zfile_fread (p4autoconfig, sizeof p4autoconfig, 1, p4rom);
-                       copyp4autoconfig (board->configtype == 3 ? 192 : 0);
-                       if (board->configtype == 3) {
-                               loadp4rom ();
-                               p4_mmiobase = 0x200000;
-                               p4_special_mask = 0x7fffff;
+               if (gb->p4rom) {
+                       zfile_fread (gb->p4autoconfig, sizeof gb->p4autoconfig, 1, gb->p4rom);
+                       copyp4autoconfig (gb, gb->board->configtype == 3 ? 192 : 0);
+                       if (gb->board->configtype == 3) {
+                               loadp4rom (gb);
+                               gb->p4_mmiobase = 0x200000;
+                               gb->p4_special_mask = 0x7fffff;
                        } else {
-                               p4z2 = true;
-                               p4_mmiobase = 0x8000;
-                               p4_special_mask = 0x1ffff;
+                               gb->p4z2 = true;
+                               gb->p4_mmiobase = 0x8000;
+                               gb->p4_special_mask = 0x1ffff;
                        }
-                       gfxboard_intena = true;
+                       gb->gfxboard_intena = true;
                } else {
                        error_log (_T("Picasso IV: '%s' flash rom image not found!\nAvailable from http://www.sophisticated-development.de/\nPIV_FlashImageXX -> picasso_iv_flash.rom"), path);
                        gui_message (_T("Picasso IV: '%s' flash rom image not found!\nAvailable from http://www.sophisticated-development.de/\nPIV_FlashImageXX -> picasso_iv_flash.rom"), path);
                }
        }
 
-       _stprintf (memorybankname, _T("%s VRAM"), board->name);
-       _stprintf (wbsmemorybankname, _T("%s VRAM WORDSWAP"), board->name);
-       _stprintf (lbsmemorybankname, _T("%s VRAM LONGSWAP"), board->name);
-       _stprintf (regbankname, _T("%s REG"), board->name);
+       _stprintf (gb->memorybankname, _T("%s VRAM"), gb->board->name);
+       _stprintf (gb->wbsmemorybankname, _T("%s VRAM WORDSWAP"), gb->board->name);
+       _stprintf (gb->lbsmemorybankname, _T("%s VRAM LONGSWAP"), gb->board->name);
+       _stprintf (gb->regbankname, _T("%s REG"), gb->board->name);
 
-       gfxboard_bank_memory.name = memorybankname;
-       gfxboard_bank_memory_nojit.name = memorybankname;
-       gfxboard_bank_wbsmemory.name = wbsmemorybankname;
-       gfxboard_bank_lbsmemory.name = lbsmemorybankname;
-       gfxboard_bank_registers.name = regbankname;
+       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;
 
        gfxboard_bank_memory.bget = gfxboard_bget_mem_autoconfig;
        gfxboard_bank_memory.bput = gfxboard_bput_mem_autoconfig;
 
        if (currprefs.rtgmem_type == GFXBOARD_VGA) {
-               init_board();
-               configured_mem = 1;
-               configured_regs = 1;
+               init_board(gb);
+               gb->configured_mem = 1;
+               gb->configured_regs = 1;
                return &expamem_null;
        }
 
@@ -2286,37 +2380,39 @@ addrbank *gfxboard_init_memory (int devnum)
 
 addrbank *gfxboard_init_memory_p4_z2 (int devnum)
 {
-       if (board->configtype == 3)
+       struct rtggfxboard *gb = &rtggfxboards[0];
+       if (gb->board->configtype == 3)
                return &expamem_null;
 
-       copyp4autoconfig (64);
+       copyp4autoconfig (gb, 64);
        return &gfxboard_bank_memory;
 }
 
 addrbank *gfxboard_init_registers (int devnum)
 {
-       if (!board->model_registers)
+       struct rtggfxboard *gb = &rtggfxboards[0];
+       if (!gb->board->model_registers)
                return &expamem_null;
 
-       memset (automemory, 0xff, GFXBOARD_AUTOCONFIG_SIZE);
-       ew (0x00, 0xc0 | 0x01); // 64k Z2
-       ew (0x04, board->model_registers);
-       ew (0x10, board->manufacturer >> 8);
-       ew (0x14, board->manufacturer);
+       memset (gb->automemory, 0xff, GFXBOARD_AUTOCONFIG_SIZE);
+       ew (gb, 0x00, 0xc0 | 0x01); // 64k Z2
+       ew (gb, 0x04, gb->board->model_registers);
+       ew (gb, 0x10, gb->board->manufacturer >> 8);
+       ew (gb, 0x14, gb->board->manufacturer);
 
-       uae_u32 ser = board->serial;
-       ew (0x18, ser >> 24); /* ser.no. Byte 0 */
-       ew (0x1c, ser >> 16); /* ser.no. Byte 1 */
-       ew (0x20, ser >>  8); /* ser.no. Byte 2 */
-       ew (0x24, ser >>  0); /* ser.no. Byte 3 */
+       uae_u32 ser = gb->board->serial;
+       ew (gb, 0x18, ser >> 24); /* ser.no. Byte 0 */
+       ew (gb, 0x1c, ser >> 16); /* ser.no. Byte 1 */
+       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;
 
        if (ISP4()) {
                uae_u8 v;
-               copyp4autoconfig (128);
-               loadp4rom ();
-               v = (((automemory[0] & 0xf0) | (automemory[2] >> 4)) & 3) - 1;
+               copyp4autoconfig (gb, 128);
+               loadp4rom (gb);
+               v = (((gb->automemory[0] & 0xf0) | (gb->automemory[2] >> 4)) & 3) - 1;
                gfxboard_bank_special.allocated = 0x10000 << v;
        }
 
index cb792d10f2656d966737bec0165a305b97608086..6abe7392f53e58b75e8e6bc7238ff6b8d8b1d067 100644 (file)
@@ -97,6 +97,7 @@ extern void filesys_store_devinfo (uae_u8 *);
 extern void hardfile_install (void);
 extern void hardfile_reset (void);
 extern void emulib_install (void);
+extern uae_u32 uaeboard_demux (uae_u32*);
 extern void expansion_init (void);
 extern void expansion_cleanup (void);
 extern void expansion_clear (void);
index 96604d13a4e56517c1a32b752c3444db50b1f3b2..1e199af9ed18e3c26f2065ab83d46a02ee2d281f 100644 (file)
@@ -285,30 +285,30 @@ STATIC_INLINE void m68k_do_rts_ce030 (void)
 
 #ifdef CPUEMU_11
 
-STATIC_INLINE uae_u32 get_word_prefetch (int o)
+STATIC_INLINE uae_u32 get_word_000_prefetch(int o)
 {
        uae_u32 v = regs.irc;
        regs.irc = regs.db = get_wordi (m68k_getpci () + o);
        return v;
 }
-STATIC_INLINE uae_u32 get_byte_prefetch (uaecptr addr)
+STATIC_INLINE uae_u32 get_byte_000(uaecptr addr)
 {
        uae_u32 v = get_byte (addr);
        regs.db = (v << 8) | v;
        return v;
 }
-STATIC_INLINE uae_u32 get_word_prefetch (uaecptr addr)
+STATIC_INLINE uae_u32 get_word_000(uaecptr addr)
 {
        uae_u32 v = get_word (addr);
        regs.db = v;
        return v;
 }
-STATIC_INLINE void put_byte_prefetch (uaecptr addr, uae_u32 v)
+STATIC_INLINE void put_byte_000(uaecptr addr, uae_u32 v)
 {
        regs.db = (v << 8) | v;
        put_byte (addr, v);
 }
-STATIC_INLINE void put_word_prefetch (uaecptr addr, uae_u32 v)
+STATIC_INLINE void put_word_000(uaecptr addr, uae_u32 v)
 {
        regs.db = v;
        put_word (addr, v);
index e788612edb5dacd939b4cfb726ce488bc435c917..448f0893547a73f4daeee96e36388e7fa2e79a5b 100644 (file)
@@ -13,6 +13,7 @@ extern void cpuboard_clear(void);
 extern void cpuboard_vsync(void);
 extern void cpuboard_hsync(void);
 extern void cpuboard_rethink(void);
+extern bool cpuboard_is_ppcboard_irq(void);
 extern int cpuboard_memorytype(struct uae_prefs *p);
 extern int cpuboard_maxmemory(struct uae_prefs *p);
 extern bool cpuboard_32bit(struct uae_prefs *p);
@@ -51,41 +52,43 @@ void blizzardppc_irq(int level);
 #define BOARD_COMMODORE 2
 #define BOARD_COMMODORE_SUB_A26x0 0
 
-#define BOARD_DKB 3
+#define BOARD_DCE 3
+
+#define BOARD_DKB 4
 #define BOARD_DKB_SUB_12x0 0
 #define BOARD_DKB_SUB_WILDFIRE 1
 
-#define BOARD_GVP 4
+#define BOARD_GVP 5
 #define BOARD_GVP_SUB_A3001SI 0
 #define BOARD_GVP_SUB_A3001SII 1
 #define BOARD_GVP_SUB_A530 2
 #define BOARD_GVP_SUB_GFORCE030 3
 #define BOARD_GVP_SUB_TEKMAGIC 4
 
-#define BOARD_KUPKE 5
+#define BOARD_KUPKE 6
 
-#define BOARD_MACROSYSTEM 6
+#define BOARD_MACROSYSTEM 7
 #define BOARD_MACROSYSTEM_SUB_WARPENGINE_A4000 0
 
-#define BOARD_MTEC 7
+#define BOARD_MTEC 8
 #define BOARD_MTEC_SUB_EMATRIX530 0
 
-#define BOARD_BLIZZARD 8
+#define BOARD_BLIZZARD 9
 #define BOARD_BLIZZARD_SUB_1230IV 0
 #define BOARD_BLIZZARD_SUB_1260 1
 #define BOARD_BLIZZARD_SUB_2060 2
 #define BOARD_BLIZZARD_SUB_PPC 3
 
-#define BOARD_CYBERSTORM 9
+#define BOARD_CYBERSTORM 10
 #define BOARD_CYBERSTORM_SUB_MK1 0
 #define BOARD_CYBERSTORM_SUB_MK2 1
 #define BOARD_CYBERSTORM_SUB_MK3 2
 #define BOARD_CYBERSTORM_SUB_PPC 3
 
-#define BOARD_RCS 10
+#define BOARD_RCS 11
 #define BOARD_RCS_SUB_FUSIONFORTY 0
 
-#define BOARD_IC 11
+#define BOARD_IC 12
 #define BOARD_IC_ACA500 0
 
 #endif /* UAE_CPUBOARD_H */
index 5bee425850e87f21f9149c97700ca86e4a009615..4439d0370592c110fb53d4382736ae886ca228f8 100644 (file)
@@ -21,7 +21,7 @@ extern int debugging;
 extern int memwatch_enabled;
 extern int exception_debugging;
 extern int debug_copper;
-extern int debug_dma;
+extern int debug_dma, debug_heatmap;
 extern int debug_sprite_mask;
 extern int debug_bpl_mask, debug_bpl_mask_one;
 extern int debugger_active;
@@ -64,35 +64,39 @@ struct breakpoint_node {
 };
 extern struct breakpoint_node bpnodes[BREAKPOINT_TOTAL];
 
-#define MW_MASK_CPU                            0x00000001
-#define MW_MASK_BLITTER_A              0x00000002
-#define MW_MASK_BLITTER_B              0x00000004
-#define MW_MASK_BLITTER_C              0x00000008
-#define MW_MASK_BLITTER_D              0x00000010
-#define MW_MASK_COPPER                 0x00000020
-#define MW_MASK_DISK                   0x00000040
-#define MW_MASK_AUDIO_0                        0x00000080
-#define MW_MASK_AUDIO_1                        0x00000100
-#define MW_MASK_AUDIO_2                        0x00000200
-#define MW_MASK_AUDIO_3                        0x00000400
-#define MW_MASK_BPL_0                  0x00000800
-#define MW_MASK_BPL_1                  0x00001000
-#define MW_MASK_BPL_2                  0x00002000
-#define MW_MASK_BPL_3                  0x00004000
-#define MW_MASK_BPL_4                  0x00008000
-#define MW_MASK_BPL_5                  0x00010000
-#define MW_MASK_BPL_6                  0x00020000
-#define MW_MASK_BPL_7                  0x00040000
-#define MW_MASK_SPR_0                  0x00080000
-#define MW_MASK_SPR_1                  0x00100000
-#define MW_MASK_SPR_2                  0x00200000
-#define MW_MASK_SPR_3                  0x00400000
-#define MW_MASK_SPR_4                  0x00800000
-#define MW_MASK_SPR_5                  0x01000000
-#define MW_MASK_SPR_6                  0x02000000
-#define MW_MASK_SPR_7                  0x04000000
-#define MW_MASK_NONE                   0x08000000
-#define MW_MASK_ALL                            (0x08000000 - 1)
+#define MW_MASK_CPU_I                  0x00000001
+#define MW_MASK_CPU_D_R                        0x00000002
+#define MW_MASK_CPU_D_W                        0x00000004
+#define MW_MASK_BLITTER_A              0x00000008
+#define MW_MASK_BLITTER_B              0x00000010
+#define MW_MASK_BLITTER_C              0x00000020
+#define MW_MASK_BLITTER_D_N            0x00000040
+#define MW_MASK_BLITTER_D_L            0x00000080
+#define MW_MASK_BLITTER_D_F            0x00000100
+#define MW_MASK_COPPER                 0x00000200
+#define MW_MASK_DISK                   0x00000400
+#define MW_MASK_AUDIO_0                        0x00000800
+#define MW_MASK_AUDIO_1                        0x00001000
+#define MW_MASK_AUDIO_2                        0x00002000
+#define MW_MASK_AUDIO_3                        0x00004000
+#define MW_MASK_BPL_0                  0x00008000
+#define MW_MASK_BPL_1                  0x00010000
+#define MW_MASK_BPL_2                  0x00020000
+#define MW_MASK_BPL_3                  0x00040000
+#define MW_MASK_BPL_4                  0x00080000
+#define MW_MASK_BPL_5                  0x00100000
+#define MW_MASK_BPL_6                  0x00200000
+#define MW_MASK_BPL_7                  0x00400000
+#define MW_MASK_SPR_0                  0x00800000
+#define MW_MASK_SPR_1                  0x01000000
+#define MW_MASK_SPR_2                  0x02000000
+#define MW_MASK_SPR_3                  0x04000000
+#define MW_MASK_SPR_4                  0x08000000
+#define MW_MASK_SPR_5                  0x10000000
+#define MW_MASK_SPR_6                  0x20000000
+#define MW_MASK_SPR_7                  0x40000000
+#define MW_MASK_NONE                   0x80000000
+#define MW_MASK_ALL                            (MW_MASK_NONE - 1)
 
 #define MEMWATCH_TOTAL 20
 struct memwatch_node {
@@ -152,21 +156,22 @@ struct dma_rec
 #define DMA_EVENT_COPPERWANTED 128
 
 #define DMARECORD_REFRESH 1
-#define DMARECORD_CPU 2
-#define DMARECORD_COPPER 3
-#define DMARECORD_AUDIO 4
-#define DMARECORD_BLITTER 5
-#define DMARECORD_BLITTER_FILL 6
-#define DMARECORD_BLITTER_LINE 7
-#define DMARECORD_BITPLANE 8
-#define DMARECORD_SPRITE 9
-#define DMARECORD_DISK 10
-#define DMARECORD_MAX 11
-
-extern struct dma_rec *record_dma (uae_u16 reg, uae_u16 dat, uae_u32 addr, int hpos, int vpos, int type);
-extern void record_dma_reset (void);
-extern void record_dma_event (int evt, int hpos, int vpos);
-extern void debug_draw_cycles (uae_u8 *buf, int bpp, int line, int width, int height, uae_u32 *xredcolors, uae_u32 *xgreencolors, uae_u32 *xbluescolors);
+#define DMARECORD_CPU_I 2
+#define DMARECORD_CPU_D 3
+#define DMARECORD_COPPER 4
+#define DMARECORD_AUDIO 5
+#define DMARECORD_BLITTER 6
+#define DMARECORD_BLITTER_FILL 7
+#define DMARECORD_BLITTER_LINE 8
+#define DMARECORD_BITPLANE 9
+#define DMARECORD_SPRITE 10
+#define DMARECORD_DISK 11
+#define DMARECORD_MAX 12
+
+extern struct dma_rec *record_dma(uae_u16 reg, uae_u16 dat, uae_u32 addr, int hpos, int vpos, int type);
+extern void record_dma_reset(void);
+extern void record_dma_event(int evt, int hpos, int vpos);
+extern void debug_draw(uae_u8 *buf, int bpp, int line, int width, int height, uae_u32 *xredcolors, uae_u32 *xgreencolors, uae_u32 *xbluescolors);
 
 #else
 
index 25227b6e9fc6c4f02ec1869acd58e6add5f056da..db5a37197ad27c80dd9c7bbfe61471e423077160 100644 (file)
@@ -75,7 +75,7 @@ extern void DISK_reset (void);
 extern int disk_getwriteprotect (struct uae_prefs *p, const TCHAR *name);
 extern int disk_setwriteprotect (struct uae_prefs *p, int num, const TCHAR *name, bool writeprotected);
 extern bool disk_creatediskfile (const TCHAR *name, int type, drive_type adftype, const TCHAR *disk_name, bool ffs, bool bootable, struct zfile *copyfrom);
-extern void dumpdisk (void);
+extern void dumpdisk (const TCHAR*);
 extern int DISK_history_add (const TCHAR *name, int idx, int type, int donotcheck);
 extern TCHAR *DISK_history_get (int idx, int type);
 int DISK_examine_image (struct uae_prefs *p, int num, struct diskinfo *di);
index d621143dd7b59cf502648a128b4321676702d609..a6312d4422592c6230320334ba2a3d7178c6db0c 100644 (file)
@@ -6,7 +6,7 @@ extern addrbank *gfxboard_init_memory_p4_z2(int devnum);
 extern addrbank *gfxboard_init_registers(int devnum);
 extern void gfxboard_free (void);
 extern void gfxboard_reset (void);
-extern void gfxboard_vsync_handler (void);
+extern bool gfxboard_vsync_handler (void);
 extern void gfxboard_hsync_handler(void);
 extern int gfxboard_get_configtype (int);
 extern bool gfxboard_is_registers (int);
@@ -27,7 +27,7 @@ extern addrbank *tms_init(int devnum);
 extern void tms_free(void);
 extern void tms_reset(void);
 extern void tms_hsync_handler(void);
-extern void tms_vsync_handler(void);
+extern bool tms_vsync_handler(void);
 extern bool tms_toggle(int);
 
 extern void vga_io_put(int portnum, uae_u8 v);
index 6d88ca2f52b029b084df15b7d02422ea44032de9..a6ef4ed97534f7a4165989031483e1102b297ef5 100644 (file)
@@ -71,10 +71,12 @@ struct uae_input_device_kbr_default {
 struct inputevent {
        const TCHAR *confname;
        const TCHAR *name;
+       const TCHAR *shortname;
        int allow_mask;
        int type;
        int unit;
        int data;
+       int portid;
 };
 
 #define MAX_INPUT_QUALIFIERS (8 + 5)
@@ -198,12 +200,14 @@ extern int input_get_default_joystick_analog (struct uae_input_device *uid, int
 extern int input_get_default_keyboard (int num);
 
 #define DEFEVENT(A, B, C, D, E, F) INPUTEVENT_ ## A,
+#define DEFEVENT2(A, B, B2, C, D, E, F, G) INPUTEVENT_ ## A,
 enum inputevents {
 INPUTEVENT_ZERO,
 #include "../inputevents.def"
 INPUTEVENT_END
 };
 #undef DEFEVENT
+#undef DEFEVENT2
 
 extern void handle_cd32_joystick_cia (uae_u8, uae_u8);
 extern uae_u8 handle_parport_joystick (int port, uae_u8 pra, uae_u8 dra);
@@ -249,12 +253,14 @@ extern int inputdevice_iskeymapped (int keyboard, int scancode);
 extern int inputdevice_synccapslock (int, int*);
 extern void inputdevice_testrecord (int type, int num, int wtype, int wnum, int state, int max);
 extern int inputdevice_get_compatibility_input (struct uae_prefs*, int index, int *typelist, int *inputlist, const int **at);
-extern struct inputevent *inputdevice_get_eventinfo (int evt);
+extern const struct inputevent *inputdevice_get_eventinfo (int evt);
 extern bool inputdevice_get_eventname (const struct inputevent *ie, TCHAR *out);
 extern void inputdevice_compa_prepare_custom (struct uae_prefs *prefs, int index, int mode, bool removeold);
 extern void inputdevice_compa_clear (struct uae_prefs *prefs, int index);
 extern int intputdevice_compa_get_eventtype (int evt, const int **axistable);
 extern void inputdevice_sparecopy (struct uae_input_device *uid, int num, int sub);
+extern void inputdevice_parse_jport_custom(struct uae_prefs *pr, int index, int port, TCHAR *outname);
+extern void inputdevice_generate_jport_custom(struct uae_prefs *pr, int port);
 
 extern uae_u16 potgo_value;
 extern uae_u16 POTGOR (void);
@@ -274,11 +280,12 @@ extern void inputdevice_reset (void);
 extern void write_inputdevice_config (struct uae_prefs *p, struct zfile *f);
 extern void read_inputdevice_config (struct uae_prefs *p, const TCHAR *option, TCHAR *value);
 extern void reset_inputdevice_config (struct uae_prefs *pr);
-extern void store_inputdevice_config (struct uae_prefs *pr);
-extern void restore_inputdevice_config (struct uae_prefs *p, int portnum);
-extern int inputdevice_joyport_config (struct uae_prefs *p, const TCHAR *value, int portnum, int mode, int type, bool validate);
+extern int inputdevice_joyport_config(struct uae_prefs *p, const TCHAR *value, int portnum, int mode, int type);
+extern void inputdevice_joyport_config_store(struct uae_prefs *p, const TCHAR *value, int portnum, int mode, int type);
 extern int inputdevice_getjoyportdevice (int port, int val);
-extern void inputdevice_validate_jports (struct uae_prefs *p, int changedport);
+extern void inputdevice_validate_jports (struct uae_prefs *p, int changedport, bool *fixedports);
+extern void inputdevice_fix_prefs(struct uae_prefs *p);
+extern void inputdevice_config_load_start(struct uae_prefs *p);
 
 extern void inputdevice_init (void);
 extern void inputdevice_close (void);
@@ -317,18 +324,17 @@ extern void setsystime (void);
 #define JSEM_MODE_LIGHTPEN 8
 
 #define JSEM_KBDLAYOUT 0
+#define JSEM_CUSTOM 10
 #define JSEM_JOYS 100
 #define JSEM_MICE 200
 #define JSEM_END 300
-#define JSEM_XARCADE1LAYOUT (JSEM_KBDLAYOUT + 3)
-#define JSEM_XARCADE2LAYOUT (JSEM_KBDLAYOUT + 4)
 #define JSEM_DECODEVAL(port,p) ((p)->jports[port].id)
 #define JSEM_ISNUMPAD(port,p) (jsem_iskbdjoy(port,p) == JSEM_KBDLAYOUT)
 #define JSEM_ISCURSOR(port,p) (jsem_iskbdjoy(port,p) == JSEM_KBDLAYOUT + 1)
 #define JSEM_ISSOMEWHEREELSE(port,p) (jsem_iskbdjoy(port,p) == JSEM_KBDLAYOUT + 2)
-#define JSEM_ISXARCADE1(port,p) (jsem_iskbdjoy(port,p) == JSEM_XARCADE1LAYOUT)
-#define JSEM_ISXARCADE2(port,p) (jsem_iskbdjoy(port,p) == JSEM_XARCADE2LAYOUT)
-#define JSEM_LASTKBD 5
+#define JSEM_ISCUSTOM(port,p) ((p)->jports[port].id >= JSEM_CUSTOM && (p)->jports[port].id < JSEM_CUSTOM + MAX_JPORTS_CUSTOM)
+#define JSEM_GETCUSTOMIDX(port,p) ((p)->jports[port].id - JSEM_CUSTOM)
+#define JSEM_LASTKBD 3
 #define JSEM_ISANYKBD(port,p) (jsem_iskbdjoy(port,p) >= JSEM_KBDLAYOUT && jsem_iskbdjoy(port,p) < JSEM_KBDLAYOUT + JSEM_LASTKBD)
 
 extern int jsem_isjoy (int port, const struct uae_prefs *p);
index 91b4b67eed1331116522f81506ca6993487b519d..82164fbea0d2352d9040f480a49d3a9c350b331e 100644 (file)
@@ -163,7 +163,8 @@ enum aks { AKS_ENTERGUI = 0x200, AKS_SCREENSHOT_FILE, AKS_SCREENSHOT_CLIPBOARD,
     AKS_ARCADIADIAGNOSTICS, AKS_ARCADIAPLY1, AKS_ARCADIAPLY2, AKS_ARCADIACOIN1, AKS_ARCADIACOIN2,
     AKS_TOGGLEMOUSEGRAB, AKS_SWITCHINTERPOL, AKS_TOGGLERTG,
     AKS_INPUT_CONFIG_1,AKS_INPUT_CONFIG_2,AKS_INPUT_CONFIG_3,AKS_INPUT_CONFIG_4,
-    AKS_DISKSWAPPER_NEXT,AKS_DISKSWAPPER_PREV,
+       AKS_SWAPJOYPORTS,
+       AKS_DISKSWAPPER_NEXT,AKS_DISKSWAPPER_PREV,
     AKS_DISKSWAPPER_INSERT0,AKS_DISKSWAPPER_INSERT1,AKS_DISKSWAPPER_INSERT2,AKS_DISKSWAPPER_INSERT3,
        AKS_DISK_PREV0, AKS_DISK_PREV1, AKS_DISK_PREV2, AKS_DISK_PREV3,
        AKS_DISK_NEXT0, AKS_DISK_NEXT1, AKS_DISK_NEXT2, AKS_DISK_NEXT3,
index 65160037d6bff8157b42ab514588bd18048902a5..7bd0ce32ca327d1e33df9dc669222ee13cd1e953 100644 (file)
@@ -73,7 +73,8 @@ enum
 {
        ABFLAG_UNK = 0, ABFLAG_RAM = 1, ABFLAG_ROM = 2, ABFLAG_ROMIN = 4, ABFLAG_IO = 8,
        ABFLAG_NONE = 16, ABFLAG_SAFE = 32, ABFLAG_INDIRECT = 64, ABFLAG_NOALLOC = 128,
-       ABFLAG_RTG = 256, ABFLAG_THREADSAFE = 512, ABFLAG_DIRECTMAP = 1024
+       ABFLAG_RTG = 256, ABFLAG_THREADSAFE = 512, ABFLAG_DIRECTMAP = 1024,
+       ABFLAG_CHIPRAM = 2048, ABFLAG_CIA = 4096, ABFLAG_PPCIOSPACE = 8192
 };
 typedef struct {
        /* These ones should be self-explanatory... */
index d7460a647f14c25e05bbb83716f44ae79628becf..c854338b9dfea3e9c2e085d80d5aa4a04e340a21 100644 (file)
@@ -68,6 +68,7 @@ struct cputbl {
 };
 
 #ifdef JIT
+#define MAX_JIT_CACHE 16384
 typedef uae_u32 REGPARAM3 compop_func (uae_u32) REGPARAM;
 
 #define COMP_OPCODE_ISJUMP      0x0001
index aab95e30a32aee88de327893b60180dd26f2a0af..77c32521537e3a09d7468d514e9e092151461fe4 100644 (file)
@@ -13,8 +13,8 @@
 #include "uae/types.h"
 
 #define UAEMAJOR 3
-#define UAEMINOR 2
-#define UAESUBREV 2
+#define UAEMINOR 3
+#define UAESUBREV 0
 
 typedef enum { KBD_LANG_US, KBD_LANG_DK, KBD_LANG_DE, KBD_LANG_SE, KBD_LANG_FR, KBD_LANG_IT, KBD_LANG_ES } KbdLang;
 
@@ -59,9 +59,13 @@ struct uae_input_device {
        uae_s8 enabled;
 };
 
+#define MAX_JPORTS_CUSTOM 6
 #define MAX_JPORTS 4
 #define NORMAL_JPORTS 2
 #define MAX_JPORTNAME 128
+struct jport_custom {
+       TCHAR custom[MAX_DPATH];
+};
 struct jport {
        int id;
        int mode; // 0=def,1=mouse,2=joy,3=anajoy,4=lightpen
@@ -71,7 +75,7 @@ struct jport {
        bool nokeyboardoverride;
 };
 #define JPORT_NONE -1
-#define JPORT_CUSTOM -2
+
 #define JPORT_AF_NORMAL 1
 #define JPORT_AF_TOGGLE 2
 #define JPORT_AF_ALWAYS 3
@@ -337,6 +341,7 @@ struct uae_prefs {
        int config_version;
        TCHAR config_hardware_path[MAX_DPATH];
        TCHAR config_host_path[MAX_DPATH];
+       TCHAR config_all_path[MAX_DPATH];
        TCHAR config_window_title[256];
 
        bool illegal_mem;
@@ -591,6 +596,7 @@ struct uae_prefs {
        bool rtg_more_compatible;
        uae_u32 custom_memory_addrs[MAX_CUSTOM_MEMORY_ADDRS];
        uae_u32 custom_memory_sizes[MAX_CUSTOM_MEMORY_ADDRS];
+       uae_u32 custom_memory_mask[MAX_CUSTOM_MEMORY_ADDRS];
        int uaeboard;
 
        bool kickshifter;
@@ -683,6 +689,7 @@ struct uae_prefs {
        /* input */
 
        struct jport jports[MAX_JPORTS];
+       struct jport_custom jports_custom[MAX_JPORTS_CUSTOM];
        int input_selected_setting;
        int input_joymouse_multiplier;
        int input_joymouse_deadzone;
index 4fe1b6617fde3de7d450145885c62e1e70b2b6f0..dcfb7040bb8568d169c58101fc0d18392fc93498 100644 (file)
@@ -37,6 +37,7 @@ extern int decode_cloanto_rom_do (uae_u8 *mem, int size, int real_size);
 #define ROMTYPE_CB_ACA500      0x00040011
 #define ROMTYPE_CB_DBK_WF      0x00040012
 #define ROMTYPE_CB_EMATRIX     0x00040013
+#define ROMTYPE_CB_SX32PRO     0x00040014
 
 #define ROMTYPE_FREEZER                0x00080000
 #define ROMTYPE_AR                     0x00080001
index 3d3eb756324bc7fe9a6d8311bbe8e92d44d5bf12..c1780ede93d65cbbe93b61b360434c6466ec23ff 100644 (file)
@@ -19,6 +19,7 @@ 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 void sleep_cpu_wakeup(void);
 extern int sleep_resolution;
 
 #define UAE_QUIT 1
index c1f0d0af6fb14ea70eac9d97a676bbf6f67ca96e..568b8db94a559f1d609ab67cde747d3b5aa1135d 100644 (file)
@@ -43,6 +43,7 @@ void uae_ppc_hsync_handler(void);
 void uae_ppc_wakeup(void);
 void ppc_map_banks(uae_u32, uae_u32, const TCHAR*, void*, bool);
 bool uae_self_is_ppc(void);
+void uae_ppc_wakeup_main(void);
 
 void uae_ppc_execute_quick(void);
 void uae_ppc_execute_check(void);
index 516f2511f4053bc76ccda0830a7a527d2f9ae2c7..c66e46dd3c6e1f9138d548753c4d33c24ef14f52 100644 (file)
@@ -3,7 +3,7 @@
 *
 * joystick/mouse emulation
 *
-* Copyright 2001-2012 Toni Wilen
+* Copyright 2001-2016 Toni Wilen
 *
 * new fetures:
 * - very configurable (and very complex to configure :)
@@ -91,13 +91,15 @@ extern int tablet_log;
 
 #define JOYMOUSE_CDTV 8
 
-#define DEFEVENT(A, B, C, D, E, F) {_T(#A), B, C, D, E, F },
-static struct inputevent events[] = {
-       {0, 0, AM_K,0,0,0},
+#define DEFEVENT(A, B, C, D, E, F) {_T(#A), B, NULL, C, D, E, F, 0 },
+#define DEFEVENT2(A, B, B2, C, D, E, F, G) {_T(#A), B, B2, C, D, E, F, G },
+static const struct inputevent events[] = {
+       {0, 0, 0, AM_K, 0, 0, 0, 0},
 #include "inputevents.def"
-       {0, 0, 0, 0, 0, 0}
+       {0, 0, 0, 0, 0, 0, 0, 0}
 };
 #undef DEFEVENT
+#undef DEFEVENT2
 
 static int sublevdir[2][MAX_INPUT_SUB_EVENT];
 
@@ -119,7 +121,7 @@ static uae_s16 *qualifiers_evt[MAX_INPUT_QUALIFIERS];
 static bool mouse_pullup = true;
 
 static int joymodes[MAX_JPORTS];
-static int *joyinputs[MAX_JPORTS];
+static const int *joyinputs[MAX_JPORTS];
 
 static int input_acquired;
 static int testmode;
@@ -144,6 +146,19 @@ static int handle_input_event (int nr, int state, int max, int autofire, bool ca
 
 static struct inputdevice_functions idev[IDTYPE_MAX];
 
+struct temp_uids {
+       TCHAR *name;
+       TCHAR *configname;
+       uae_s8 disabled;
+       uae_s8 empty;
+       uae_s8 custom;
+       int joystick;
+       int devtype;
+};
+static struct temp_uids temp_uid;
+static int temp_uid_index[MAX_INPUT_DEVICES][IDTYPE_MAX];
+static int temp_uid_cnt[IDTYPE_MAX];
+
 static int isdevice (struct uae_input_device *id)
 {
        int i, j;
@@ -174,7 +189,7 @@ int inputdevice_uaelib (const TCHAR *s, const TCHAR *parm)
                        value += 2, base = 16;
                v = _tcstol(value, &endptr, base);
                for (i = 1; events[i].name; i++) {
-                       struct inputevent *ie = &events[i];
+                       const struct inputevent *ie = &events[i];
                        if (_tcsncmp(ie->confname, _T("KEY_"), 4))
                                continue;
                        if (ie->data == v) {
@@ -207,6 +222,54 @@ int inputdevice_uaelib(const TCHAR *s, int parm, int max, bool autofire)
        return 0;
 }
 
+static int getdevnum(int type, int devnum)
+{
+       int jcnt = idev[IDTYPE_JOYSTICK].get_num();
+       int mcnt = idev[IDTYPE_MOUSE].get_num();
+       int kcnt = idev[IDTYPE_KEYBOARD].get_num();
+
+       if (type == IDTYPE_JOYSTICK)
+               return devnum;
+       else if (type == IDTYPE_MOUSE)
+               return jcnt + devnum;
+       else if (type == IDTYPE_KEYBOARD)
+               return jcnt + mcnt + devnum;
+       else if (type == IDTYPE_INTERNALEVENT)
+               return jcnt + mcnt + kcnt + devnum;
+       return -1;
+}
+
+static int gettype(int devnum)
+{
+       int jcnt = idev[IDTYPE_JOYSTICK].get_num();
+       int mcnt = idev[IDTYPE_MOUSE].get_num();
+       int kcnt = idev[IDTYPE_KEYBOARD].get_num();
+
+       if (devnum < jcnt)
+               return IDTYPE_JOYSTICK;
+       else if (devnum < jcnt + mcnt)
+               return IDTYPE_MOUSE;
+       else if (devnum < jcnt + mcnt + kcnt)
+               return IDTYPE_KEYBOARD;
+       else if (devnum < jcnt + mcnt + kcnt + INTERNALEVENT_COUNT)
+               return IDTYPE_INTERNALEVENT;
+       return -1;
+}
+
+static struct inputdevice_functions *getidf(int devnum)
+{
+       int type = gettype(devnum);
+       if (type < 0)
+               return NULL;
+       return &idev[type];
+}
+
+const struct inputevent *inputdevice_get_eventinfo(int evt)
+{
+       if (evt > 0 && !events[evt].name)
+               return NULL;
+       return &events[evt];
+}
 
 static struct uae_input_device *joysticks;
 static struct uae_input_device *mice;
@@ -229,11 +292,8 @@ static int default_keyboard_layout[MAX_JPORTS];
 #define KBR_DEFAULT_MAP_CD32_NP 6
 #define KBR_DEFAULT_MAP_CD32_CK 7
 #define KBR_DEFAULT_MAP_CD32_SE 8
-#define KBR_DEFAULT_MAP_XA1 9
-#define KBR_DEFAULT_MAP_XA2 10
-#define KBR_DEFAULT_MAP_ARCADIA 11
-#define KBR_DEFAULT_MAP_ARCADIA_XA 12
-#define KBR_DEFAULT_MAP_CDTV 13
+#define KBR_DEFAULT_MAP_ARCADIA 9
+#define KBR_DEFAULT_MAP_CDTV 10
 static int **keyboard_default_kbmaps;
 
 static int mouse_axis[MAX_INPUT_DEVICES][MAX_INPUT_DEVICE_EVENTS];
@@ -327,6 +387,127 @@ static void copyjport (const struct uae_prefs *src, struct uae_prefs *dst, int n
        dst->jports[num].nokeyboardoverride = src->jports[num].nokeyboardoverride;
 }
 
+#define MAX_STORED_JPORTS 8
+struct stored_jport
+{
+       struct jport jp;
+       bool inuse;
+       uae_u32 age;
+};
+static struct stored_jport stored_jports[MAX_JPORTS][8];
+static uae_u32 stored_jport_cnt;
+
+static struct jport *inputdevice_get_used_device(int portnum, int ageindex)
+{
+       int idx = -1;
+       int used[MAX_STORED_JPORTS] = { 0 };
+       if (ageindex < 0)
+               return NULL;
+       while (ageindex >= 0) {
+               uae_u32 age = 0;
+               idx = -1;
+               for (int i = 0; i < MAX_STORED_JPORTS; i++) {
+                       struct stored_jport *jp = &stored_jports[portnum][i];
+                       if (jp->inuse && !used[i] && jp->age > age) {
+                               age = jp->age;
+                               idx = i;
+                       }
+               }
+               if (idx < 0)
+                       return NULL;
+               used[idx] = 1;
+               ageindex--;
+       }
+       return &stored_jports[portnum][idx].jp;
+}
+
+static void inputdevice_set_newest_used_device(int portnum, struct jport *jps)
+{
+       for (int i = 0; i < MAX_STORED_JPORTS; i++) {
+               struct stored_jport *jp = &stored_jports[portnum][i];
+               if (jp->inuse && &jp->jp == jps) {
+                       stored_jport_cnt++;
+                       jp->age = stored_jport_cnt;
+               }
+       }
+}
+
+static void inputdevice_store_used_device(struct uae_prefs *p, int portnum)
+{
+       struct jport *jps = &p->jports[portnum];
+       if (jps->id < 0)
+               return;
+       // already added? if custom or kbr layout: delete all old
+       for (int i = 0; i < MAX_STORED_JPORTS; i++) {
+               struct stored_jport *jp = &stored_jports[portnum][i];
+               if (jp->inuse && ((jps->id == jp->jp.id) || (jps->configname[0] != 0 && jp->jp.configname[0] != 0 && !_tcscmp(jps->configname, jp->jp.configname)))) {
+                       jp->inuse = false;
+               }
+       }
+       // delete from other ports
+       for (int j = 0; j < MAX_JPORTS; j++) {
+               for (int i = 0; i < MAX_STORED_JPORTS; i++) {
+                       struct stored_jport *jp = &stored_jports[j][i];
+                       if (jp->inuse && ((jps->id == jp->jp.id) || (jps->configname[0] != 0 && jp->jp.configname[0] != 0 && !_tcscmp(jps->configname, jp->jp.configname)))) {
+                               jp->inuse = false;
+                       }
+               }
+       }
+       // delete oldest if full
+       for (int i = 0; i < MAX_STORED_JPORTS; i++) {
+               struct stored_jport *jp = &stored_jports[portnum][i];
+               if (!jp->inuse)
+                       break;
+               if (i == MAX_STORED_JPORTS - 1) {
+                       uae_u32 age = 0xffffffff;
+                       int idx = -1;
+                       for (int j = 0; j < MAX_STORED_JPORTS; j++) {
+                               struct stored_jport *jp = &stored_jports[portnum][j];
+                               if (jp->age < age) {
+                                       age = jp->age;
+                                       idx = j;
+                               }
+                       }
+                       if (idx >= 0) {
+                               struct stored_jport *jp = &stored_jports[portnum][idx];
+                               jp->inuse = false;
+                       }
+               }
+       }
+       // add new      
+       for (int i = 0; i < MAX_STORED_JPORTS; i++) {
+               struct stored_jport *jp = &stored_jports[portnum][i];
+               if (!jp->inuse) {
+                       memcpy(jp, jps, sizeof(struct jport));
+                       write_log(_T("port %d/%d: added %d %d %s %s\n"), portnum, i, jp->jp.id, jp->jp.mode, jp->jp.name, jp->jp.configname);
+                       jp->inuse = true;
+                       stored_jport_cnt++;
+                       jp->age = stored_jport_cnt;
+                       return;
+               }
+       }
+}
+
+
+static bool isemptykey(int keyboard, int scancode)
+{
+       int j = 0;
+       struct uae_input_device *na = &keyboards[keyboard];
+       while (j < MAX_INPUT_DEVICE_EVENTS && na->extra[j] >= 0) {
+               if (na->extra[j] == scancode) {
+                       for (int k = 0; k < MAX_INPUT_SUB_EVENT; k++) {
+                               if (na->eventid[j][k] > 0)
+                                       return false;
+                               if (na->custom[j][k] != NULL)
+                                       return false;
+                       }
+                       break;
+               }
+               j++;
+       }
+       return true;
+}
+
 static void out_config (struct zfile *f, int id, int num, const TCHAR *s1, const TCHAR *s2)
 {
        TCHAR tmp[MAX_DPATH];
@@ -538,6 +719,25 @@ static void write_kbr_config (struct zfile *f, int idnum, int devnum, struct uae
                        i++;
                        continue;
                }
+
+               if (!input_get_default_keyboard(devnum)) {
+                       bool isempty = true;
+                       for (j = 0; j < MAX_INPUT_SUB_EVENT; j++) {
+                               if (kbr->eventid[i][j] > 0) {
+                                       isempty = false;
+                                       break;
+                               }
+                               if (kbr->custom[i][j] != NULL) {
+                                       isempty = false;
+                                       break;
+                               }
+                       }
+                       if (isempty) {
+                               i++;
+                               continue;
+                       }
+               }
+
                tmp2[0] = 0;
                p = tmp2;
                for (j = 0; j < MAX_INPUT_SUB_EVENT; j++) {
@@ -669,7 +869,7 @@ static int getnum (const TCHAR **pp)
        else
                v = _tstol (p);
 
-       while (*p != 0 && *p !='.' && *p != ',')
+       while (*p != 0 && *p !='.' && *p != ',' && *p != '=')
                p++;
        if (*p == '.' || *p == ',')
                p++;
@@ -730,11 +930,22 @@ void reset_inputdevice_config (struct uae_prefs *prefs)
 {
        for (int i = 0; i < MAX_INPUT_SETTINGS; i++)
                reset_inputdevice_slot (prefs, i);
+       for (int i = 0; i < MAX_INPUT_DEVICES; i++) {
+               for (int j = 0; j < IDTYPE_MAX; j++) {
+                       temp_uid_index[i][j] = -1;
+               }
+       }
+       for (int i = 0; i < IDTYPE_MAX; i++) {
+               temp_uid_cnt[i] = 0;
+       }
+       memset(&temp_uid, 0, sizeof temp_uid);
 }
 
 
 static void set_kbr_default_event (struct uae_input_device *kbr, struct uae_input_device_kbr_default *trans, int num)
 {
+       if (!kbr->enabled || !trans)
+               return;
        for (int i = 0; trans[i].scancode >= 0; i++) {
                if (kbr->extra[num] == trans[i].scancode) {
                        int k;
@@ -784,13 +995,14 @@ static void set_kbr_default (struct uae_prefs *p, int index, int devnum, struct
        struct inputdevice_functions *id = &idev[IDTYPE_KEYBOARD];
        uae_u32 scancode;
 
-       if (!trans)
-               return;
        for (j = 0; j < MAX_INPUT_DEVICES; j++) {
                if (devnum >= 0 && devnum != j)
                        continue;
                kbr = &p->keyboard_settings[index][j];
+               uae_s8 ena = kbr->enabled;
                clear_id (kbr);
+               if (ena > 0)
+                       kbr->enabled = ena;
                for (i = 0; i < MAX_INPUT_DEVICE_EVENTS; i++)
                        kbr->extra[i] = -1;
                if (j < id->get_num ()) {
@@ -799,7 +1011,8 @@ static void set_kbr_default (struct uae_prefs *p, int index, int devnum, struct
                        for (i = 0; i < id->get_widget_num (j); i++) {
                                id->get_widget_type (j, i, 0, &scancode);
                                kbr->extra[i] = scancode;
-                               set_kbr_default_event (kbr, trans, i);
+                               if (j == 0 || kbr->enabled)
+                                       set_kbr_default_event (kbr, trans, i);
                        }
                }
        }
@@ -808,18 +1021,156 @@ static void set_kbr_default (struct uae_prefs *p, int index, int devnum, struct
 static void inputdevice_default_kb (struct uae_prefs *p, int num)
 {
        if (num == GAMEPORT_INPUT_SETTINGS) {
-               if (p->jports[0].id != JPORT_CUSTOM || p->jports[1].id != JPORT_CUSTOM)
-                       reset_inputdevice_slot (p, num);
+               reset_inputdevice_slot (p, num);
        }
        set_kbr_default (p, num, -1, keyboard_default);
 }
+
 static void inputdevice_default_kb_all (struct uae_prefs *p)
 {
        for (int i = 0; i < MAX_INPUT_SETTINGS; i++)
                inputdevice_default_kb (p, i);
 }
 
-static bool read_slot (const TCHAR *parm, int num, int joystick, int button, struct uae_input_device *id, int keynum, int subnum, struct inputevent *ie, uae_u64 flags, int port, TCHAR *custom)
+static const int af_port1[] = {
+       INPUTEVENT_JOY1_FIRE_BUTTON, INPUTEVENT_JOY1_CD32_RED,
+       -1
+};
+static const int af_port2[] = {
+       INPUTEVENT_JOY2_FIRE_BUTTON, INPUTEVENT_JOY2_CD32_RED,
+       -1
+};
+static const int af_port3[] = {
+       INPUTEVENT_PAR_JOY1_FIRE_BUTTON, INPUTEVENT_PAR_JOY1_2ND_BUTTON,
+       -1
+};
+static const int af_port4[] = {
+       INPUTEVENT_PAR_JOY2_FIRE_BUTTON, INPUTEVENT_PAR_JOY2_2ND_BUTTON,
+       -1
+};
+static const int *af_ports[] = { af_port1, af_port2, af_port3, af_port4 }; 
+
+static void setautofireevent(struct uae_input_device *uid, int num, int sub, int af, int index)
+{
+       if (!af)
+               return;
+#ifdef RETROPLATFORM
+       // don't override custom AF autofire mappings
+       if (rp_isactive())
+               return;
+#endif
+       const int *afp = af_ports[index];
+       for (int k = 0; afp[k] >= 0; k++) {
+               if (afp[k] == uid->eventid[num][sub]) {
+                       uid->flags[num][sub] &= ~ID_FLAG_AUTOFIRE_MASK;
+                       if (af >= JPORT_AF_NORMAL)
+                               uid->flags[num][sub] |= ID_FLAG_AUTOFIRE;
+                       if (af == JPORT_AF_TOGGLE)
+                               uid->flags[num][sub] |= ID_FLAG_TOGGLE;
+                       if (af == JPORT_AF_ALWAYS)
+                               uid->flags[num][sub] |= ID_FLAG_INVERTTOGGLE;
+                       return;
+               }
+       }
+}
+
+static void setcompakbevent(struct uae_prefs *p, struct uae_input_device *uid, int l, int evt, int port, int af)
+{
+       inputdevice_sparecopy(uid, l, 0);
+       if (p->jports[port].nokeyboardoverride && uid->port[l][0] == 0) {
+               uid->eventid[l][MAX_INPUT_SUB_EVENT - 1] = uid->eventid[l][0];
+               uid->flags[l][MAX_INPUT_SUB_EVENT - 1] = uid->flags[l][0] | ID_FLAG_RESERVEDGAMEPORTSCUSTOM;
+               uid->custom[l][MAX_INPUT_SUB_EVENT - 1] = my_strdup(uid->custom[l][0]);
+               uid->eventid[l][MAX_INPUT_SUB_EVENT - 1] = uid->eventid[l][0];
+       }
+       uid->eventid[l][0] = evt;
+       uid->flags[l][0] &= COMPA_RESERVED_FLAGS;
+       uid->port[l][0] = port + 1;
+       xfree(uid->custom[l][0]);
+       uid->custom[l][0] = NULL;
+       setautofireevent(uid, l, 0, af, port);
+}
+
+static int matchdevice(struct inputdevice_functions *inf, const TCHAR *configname, const TCHAR *name)
+{
+       int match = -1;
+       for (int i = 0; i < inf->get_num(); i++) {
+               TCHAR *aname1 = inf->get_friendlyname(i);
+               TCHAR *aname2 = inf->get_uniquename(i);
+               if (aname2 && configname) {
+                       bool matched = false;
+                       TCHAR bname[MAX_DPATH];
+                       TCHAR bname2[MAX_DPATH];
+                       TCHAR *p1, *p2;
+                       _tcscpy(bname, configname);
+                       _tcscpy(bname2, aname2);
+                       // strip possible local guid part
+                       p1 = _tcschr(bname, '{');
+                       p2 = _tcschr(bname2, '{');
+                       if (!p1 && !p2) {
+                               // check possible directinput names too
+                               p1 = _tcschr(bname, ' ');
+                               p2 = _tcschr(bname2, ' ');
+                       }
+                       if (!_tcscmp(bname, bname2)) {
+                               matched = true;
+                       } else if (p1 && p2 && p1 - bname == p2 - bname2) {
+                               *p1 = 0;
+                               *p2 = 0;
+                               if (bname[0] && !_tcscmp(bname2, bname))
+                                       matched = true;
+                       }
+                       if (matched) {
+                               if (match >= 0)
+                                       match = -2;
+                               else
+                                       match = i;
+                       }
+                       if (match == -2)
+                               break;
+               }
+       }
+       // multiple matches -> use complete local-only id string for comparisons
+       if (match == -2) {
+               match = -1;
+               for (int i = 0; i < inf->get_num(); i++) {
+                       TCHAR *aname1 = inf->get_friendlyname(i);
+                       TCHAR *aname2 = inf->get_uniquename(i);
+                       if (aname2 && configname) {
+                               const TCHAR *bname2 = configname;
+                               if (aname2 && bname2 && !_tcscmp(aname2, bname2)) {
+                                       if (match >= 0) {
+                                               match = -2;
+                                               break;
+                                       } else {
+                                               match = i;
+                                       }
+                               }
+                       }
+               }
+       }
+       if (match < 0) {
+               // no match, try friend names
+               for (int i = 0; i < inf->get_num(); i++) {
+                       TCHAR *aname1 = inf->get_friendlyname(i);
+                       TCHAR *aname2 = inf->get_uniquename(i);
+                       if (aname1 && name) {
+                               const TCHAR *bname1 = name;
+                               if (aname1 && bname1 && !_tcscmp(aname1, bname1)) {
+                                       if (match >= 0) {
+                                               match = -2;
+                                               break;
+                                       } else {
+                                               match = 1;
+                                       }
+                               }
+                       }
+               }
+       }
+       return match;
+}
+
+static bool read_slot (const TCHAR *parm, int num, int joystick, int button, struct uae_input_device *id, int keynum, int subnum, const struct inputevent *ie, uae_u64 flags, int port, TCHAR *custom)
 {
        int mask;
 
@@ -877,7 +1228,7 @@ static bool read_slot (const TCHAR *parm, int num, int joystick, int button, str
        return true;
 }
 
-static struct inputevent *readevent (const TCHAR *name, TCHAR **customp)
+static const struct inputevent *readevent (const TCHAR *name, TCHAR **customp)
 {
        int i = 1;
        while (events[i].name) {
@@ -886,6 +1237,8 @@ static struct inputevent *readevent (const TCHAR *name, TCHAR **customp)
                i++;
        }
        if (_tcslen (name) > 2 && name[0] == '\'' && name[_tcslen (name) - 1] == '\'') {
+               if (!customp)
+                       return NULL;
                TCHAR *custom = my_strdup (name + 1);
                custom[_tcslen (custom) - 1] = 0;
                *customp = custom;
@@ -895,11 +1248,13 @@ static struct inputevent *readevent (const TCHAR *name, TCHAR **customp)
 
 void read_inputdevice_config (struct uae_prefs *pr, const TCHAR *option, TCHAR *value)
 {
-       struct uae_input_device *id = 0;
-       struct inputevent *ie;
-       int devnum, num, button, joystick, subnum, idnum, keynum;
+       struct uae_input_device *id = NULL;
+       const struct inputevent *ie;
+       int devnum, num, button, joystick, subnum, idnum, keynum, devtype;
        const TCHAR *p;
        TCHAR *p2, *custom;
+       struct temp_uids *tid = &temp_uid;
+       struct inputdevice_functions *idf = NULL;
 
        option += 6; /* "input." */
        p = getstring (&option);
@@ -970,70 +1325,133 @@ void read_inputdevice_config (struct uae_prefs *pr, const TCHAR *option, TCHAR *
        if (_tcsncmp (option, _T("mouse."), 6) == 0) {
                id = &pr->mouse_settings[idnum][devnum];
                joystick = 0;
+               devtype = IDTYPE_MOUSE;
        } else if (_tcsncmp (option, _T("joystick."), 9) == 0) {
                id = &pr->joystick_settings[idnum][devnum];
                joystick = 1;
+               devtype = IDTYPE_JOYSTICK;
        } else if (_tcsncmp (option, _T("keyboard."), 9) == 0) {
                id = &pr->keyboard_settings[idnum][devnum];
                joystick = -1;
+               devtype = IDTYPE_KEYBOARD;
        } else if (_tcsncmp (option, _T("internal."), 9) == 0) {
-               if (devnum > 0)
+               if (devnum >= INTERNALEVENT_COUNT)
                        return;
                id = &pr->internalevent_settings[idnum][devnum];
-               joystick = 1;
+               joystick = 2;
+               devtype = IDTYPE_INTERNALEVENT;
        }
        if (!id)
                return;
+       idf = &idev[devtype];
 
        if (!_tcscmp (p2, _T("name"))) {
-               xfree (id->configname);
-               id->configname = my_strdup (value);
+               xfree(tid->configname);
+               tid->configname = my_strdup (value);
+               tid->joystick = joystick;
+               tid->devtype = devtype;
+               tid->custom = false;
+               tid->empty = false;
+               tid->disabled = false;
                return;
        }
        if (!_tcscmp (p2, _T("friendlyname"))) {
-               xfree (id->name);
-               id->name = my_strdup (value);
+               xfree (tid->name);
+               tid->name = my_strdup (value);
+               tid->joystick = joystick;
+               tid->devtype = devtype;
+               tid->custom = false;
+               tid->empty = false;
+               tid->disabled = false;
                return;
        }
-
        if (!_tcscmp (p2, _T("custom"))) {
-               int iscustom;
                p = value;
-               iscustom = getnum (&p);
-               if (idnum == GAMEPORT_INPUT_SETTINGS) {
-                       clear_id (id);
-                       if (joystick < 0)
-                               set_kbr_default (pr, idnum, devnum, keyboard_default);
-                       id->enabled = iscustom;
+               tid->custom = getnum(&p);
+               tid->joystick = joystick;
+               tid->devtype = devtype;
+               tid->empty = false;
+               return;
+       }
+       if (!_tcscmp(p2, _T("empty"))) {
+               p = value;
+               tid->empty = getnum(&p);
+               tid->joystick = joystick;
+               tid->devtype = devtype;
+               return;
+       }
+       if (!_tcscmp(p2, _T("disabled"))) {
+               p = value;
+               tid->disabled = getnum(&p);
+               tid->joystick = joystick;
+               tid->devtype = devtype;
+               return;
+       }
+
+       bool newdev = false;
+       if (temp_uid_index[devnum][tid->devtype] == -1) {
+               int newdevnum;
+               // keyboard devnum == 0: always select keyboard zero.
+               if (tid->devtype == IDTYPE_KEYBOARD && devnum == 0) {
+                       newdevnum = 0;
+                       tid->disabled = false;
+                       tid->empty = false;
                } else {
-                       id->enabled = false;
+                       newdevnum = matchdevice(idf, tid->configname, tid->name);
                }
+               newdev = true;
+               if (newdevnum >= 0) {
+                       temp_uid_index[devnum][tid->devtype] = newdevnum;
+                       write_log(_T("%d %d: %d -> %d (%s)\n"), idnum, tid->devtype, devnum, temp_uid_index[devnum][tid->devtype], tid->name);
+               } else {
+                       newdevnum = idf->get_num() + temp_uid_cnt[tid->devtype];
+                       if (newdevnum < MAX_INPUT_DEVICES) {
+                               temp_uid_index[devnum][tid->devtype] = newdevnum;
+                               temp_uid_cnt[tid->devtype]++;
+                               write_log(_T("%d %d: %d -> %d (NO MATCH) (%s)\n"), idnum, tid->devtype, devnum, temp_uid_index[devnum][tid->devtype], tid->name);
+                       } else {
+                               temp_uid_index[devnum][tid->devtype] = -1;
+                       }
+               }
+       }
+       devnum = temp_uid_index[devnum][tid->devtype];
+       if (devnum < 0) {
+               if (devnum == -1)
+                       write_log(_T("%s (%s) not found and no free slots\n"), tid->name, tid->configname);
+               temp_uid_index[devnum][tid->devtype] = -2;
                return;
        }
 
-       if (!_tcscmp (p2, _T("empty"))) {
-               int empty;
-               p = value;
-               empty = getnum (&p);
-               clear_id (id);
-               if (!empty) {
-                       if (joystick < 0)
-                               set_kbr_default (pr, idnum, devnum, keyboard_default);
-               }
-               id->enabled = 1;
-               if (idnum == GAMEPORT_INPUT_SETTINGS)
-                       id->enabled = 0;
+       if (tid->devtype == IDTYPE_MOUSE) {
+               id = &pr->mouse_settings[idnum][devnum];
+       } else if (tid->devtype == IDTYPE_JOYSTICK) {
+               id = &pr->joystick_settings[idnum][devnum];
+       } else if (tid->devtype == IDTYPE_KEYBOARD) {
+               id = &pr->keyboard_settings[idnum][devnum];
+       } else if (tid->devtype == IDTYPE_INTERNALEVENT) {
+               if (devnum >= INTERNALEVENT_COUNT)
+                       return;
+               id = &pr->internalevent_settings[idnum][devnum];
+       } else {
                return;
        }
 
-       if (!_tcscmp (p2, _T("disabled"))) {
-               int disabled;
-               p = value;
-               disabled = getnum (&p);
-               id->enabled = disabled == 0 ? 1 : 0;
-               if (idnum == GAMEPORT_INPUT_SETTINGS)
+       if (newdev) {
+               clear_id(id);
+               if (!tid->empty && tid->devtype == IDTYPE_KEYBOARD) {
+                       set_kbr_default(pr, idnum, devnum, keyboard_default);
+               }
+               id->enabled = tid->disabled == 0 ? 1 : 0;
+               if (idnum == GAMEPORT_INPUT_SETTINGS) {
                        id->enabled = 0;
-               return;
+               }
+               if (tid->custom) {
+                       id->enabled = 1;
+               }
+               xfree(tid->configname);
+               xfree(tid->name);
+               tid->configname = NULL;
+               tid->name = NULL;
        }
 
        if (idnum == GAMEPORT_INPUT_SETTINGS && id->enabled == 0)
@@ -1041,6 +1459,7 @@ void read_inputdevice_config (struct uae_prefs *pr, const TCHAR *option, TCHAR *
 
        button = 0;
        keynum = 0;
+       joystick = tid->joystick;
        if (joystick < 0) {
                num = getnum (&p);
                for (keynum = 0; keynum < MAX_INPUT_DEVICE_EVENTS; keynum++) {
@@ -1092,7 +1511,7 @@ void read_inputdevice_config (struct uae_prefs *pr, const TCHAR *option, TCHAR *
                                if (p[-1] == '.' && (p[0] >= 'A' && p[0] <= 'Z') || (p[0] >= 'a' && p[0] <= 'z'))
                                        flags |= getqual (&p);
                                TCHAR *custom2 = NULL;
-                               struct inputevent *ie2 = readevent (p2, &custom2);
+                               const struct inputevent *ie2 = readevent (p2, &custom2);
                                read_slot (p2, num, joystick, button, id, keynum, SPARE_SUB_EVENT, ie2, flags2, MAX_JPORTS + 1, custom2);
                        }
                }
@@ -1109,6 +1528,235 @@ void read_inputdevice_config (struct uae_prefs *pr, const TCHAR *option, TCHAR *
        xfree (custom);
 }
 
+static void generate_jport_custom_item(struct uae_input_device *uid, int num, int port, int devtype, TCHAR *out)
+{
+       struct uae_input_device *uid2 = &uid[num];
+       for (int i = 0; i < MAX_INPUT_DEVICE_EVENTS; i++) {
+               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_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);
+                       }
+               }
+       }
+}
+
+void inputdevice_generate_jport_custom(struct uae_prefs *pr, int port)
+{
+       if (!JSEM_ISCUSTOM(port, pr))
+               return;
+       struct jport_custom *jpc = &pr->jports_custom[JSEM_GETCUSTOMIDX(port, pr)];
+       jpc->custom[0] = 0;
+       for (int l = 0; l < MAX_INPUT_DEVICES; l++) {
+               generate_jport_custom_item(pr->joystick_settings[pr->input_selected_setting], l, port, IDTYPE_JOYSTICK, jpc->custom);
+               generate_jport_custom_item(pr->mouse_settings[pr->input_selected_setting], l, port, IDTYPE_MOUSE, jpc->custom);
+               generate_jport_custom_item(pr->keyboard_settings[pr->input_selected_setting], l, port, IDTYPE_KEYBOARD, jpc->custom);
+       }
+}
+
+static int custom_autoswitch_joy[MAX_JPORTS_CUSTOM];
+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 *bufp;
+       int cnt = 0;
+
+       custom_autoswitch_joy[index] = -1;
+
+       if (eventstr == NULL || eventstr[0] == 0)
+               return;
+       if (outname)
+               outname[0] = 0;
+
+       write_log(_T("parse_custom port %d, '%s'\n"), port, eventstr ? eventstr : _T("<NULL>"));
+
+       _tcscpy(data, eventstr);
+       _tcscat(data, _T(" "));
+       bufp = data;
+       for (;;) {
+               TCHAR *next = bufp;
+               while (next != NULL && *next != ' ' && *next != 0)
+                       next++;
+               if (!next || *next == 0)
+                       break;
+               *next++ = 0;
+               const TCHAR *bufp2 = bufp;
+               struct uae_input_device *id = 0;
+               int joystick = 0;
+               TCHAR *p = getstring(&bufp2);
+               if (!p)
+                       goto skip;
+
+               int devindex = getnum(&bufp2);
+               if (*bufp == 0)
+                       goto skip;
+               if (devindex < 0 || devindex >= MAX_INPUT_DEVICES)
+                       goto skip;
+
+               TCHAR devtype = _totupper(*p);
+
+               int devnum = 0;
+               if (devtype == 'M') {
+                       id = &pr->mouse_settings[pr->input_selected_setting][devindex];
+                       joystick = 0;
+                       devnum = getdevnum(IDTYPE_MOUSE, devindex);
+                       if (gettype(devnum) != IDTYPE_MOUSE)
+                               goto skip;
+               } else if (devtype == 'J') {
+                       id = &pr->joystick_settings[pr->input_selected_setting][devindex];
+                       joystick = 1;
+                       devnum = getdevnum(IDTYPE_JOYSTICK, devindex);
+                       if (gettype(devnum) != IDTYPE_JOYSTICK)
+                               goto skip;
+               } else if (devtype == 'K') {
+                       // always use keyboard 0
+                       devindex = 0;
+                       id = &pr->keyboard_settings[pr->input_selected_setting][devindex];
+                       joystick = -1;
+                       devnum = getdevnum(IDTYPE_KEYBOARD, devindex);
+                       if (gettype(devnum) != IDTYPE_KEYBOARD) {
+                               write_log(_T("parse_custom keyboard missing!?\n"));
+                               goto skip;
+                       }
+               }
+               if (!id)
+                       goto skip;
+
+               p = getstring(&bufp2);
+               if (!p)
+                       goto skip;
+
+               int num = -1;
+               int keynum = 0;
+               if (joystick < 0) {
+                       num = getnum(&bufp2);
+                       if (*bufp == 0)
+                               goto skip;
+                       for (keynum = 0; keynum < MAX_INPUT_DEVICE_EVENTS; keynum++) {
+                               if (id->extra[keynum] == num)
+                                       break;
+                       }
+                       if (keynum >= MAX_INPUT_DEVICE_EVENTS) {
+                               write_log(_T("parse_custom keyboard missing key %02x!\n"), num);
+                               goto skip;
+                       }
+                       num = keynum;
+               } else {
+                       TCHAR dt = _totupper(*p);
+                       const struct inputdevice_functions *idf = getidf(devnum);
+                       num = getnum(&bufp2);
+                       if (dt == 'A') {
+                               num += idf->get_widget_first(devnum, IDEV_WIDGET_AXIS);
+                       } else if (dt == 'B') {
+                               num += idf->get_widget_first(devnum, IDEV_WIDGET_BUTTON);
+                       } else {
+                               goto skip;
+                       }
+               }
+
+               while (*bufp2 != '=' && *bufp2 != 0)
+                       bufp2++;
+               if (*bufp2 == 0)
+                       goto skip;
+               bufp2++;
+
+               p = getstring(&bufp2);
+               if (!p)
+                       goto skip;
+
+               const struct inputevent *ie = readevent(p, NULL);
+               if (ie) {
+                       // Different port? Find matching request port event.
+                       if (port >= 0 && ie->unit > 0 && ie->unit != port + 1) {
+                               int pid = ie->portid;
+                               if (!pid)
+                                       goto skip;
+                               for (int i = 1; events[i].name; i++) {
+                                       const struct inputevent *ie2 = &events[i];
+                                       if (ie2->portid == pid && ie2->unit == port + 1) {
+                                               ie = ie2;
+                                               break;
+                                       }
+                               }
+                               if (ie->unit != port + 1)
+                                       goto skip;
+                       }
+                       if (outname == NULL) {
+                               int evt = ie - &events[0];
+                               if (joystick < 0) {
+                                       if (port >= 0) {
+                                               // all active keyboards
+                                               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);
+                                                       }
+                                               }
+                                       }
+                               } else {
+                                       if (port >= 0) {
+                                               inputdevice_set_gameports_mapping(pr, devnum, num, evt, 0, port, pr->input_selected_setting);
+                                       }
+                                       if (evt == INPUTEVENT_JOY1_FIRE_BUTTON || evt == INPUTEVENT_JOY2_FIRE_BUTTON) {
+                                               if (joystick > 0)
+                                                       custom_autoswitch_joy[index] = devindex;
+                                               else
+                                                       custom_autoswitch_mouse[index] = devindex;
+                                       }
+                               }
+                       } else {
+                               TCHAR tmp[MAX_DPATH];
+                               if (outname[0] != 0)
+                                       _tcscat(outname, _T(", "));
+                               const TCHAR *ps = ie->shortname ? ie->shortname : ie->name;
+                               if (inputdevice_get_widget_type(devnum, num, tmp)) {
+                                       if (tmp[0]) {
+                                               _tcscat(outname, tmp);
+                                               _tcscat(outname, _T("="));
+                                       }
+                               }
+                               _tcscat(outname, ps);
+                       }
+               } else {
+                       write_log(_T("parse_custom missing event %s\n"), p);
+               }
+skip:
+               bufp = next;
+       }
+}
+
 static int mouseedge_alive, mousehack_alive_cnt;
 static int lastmx, lastmy;
 static uaecptr magicmouse_ibase, magicmouse_gfxbase;
@@ -3125,6 +3773,12 @@ static bool inputdevice_handle_inputcode2 (int code, int state)
        case AKS_TOGGLERTG:
                toggle_rtg (newstate);
                break;
+       case AKS_SWAPJOYPORTS:
+               if (state == 1)
+                       inputdevice_swap_compa_ports(&changed_prefs, 0);
+               else if (state == 2)
+                       inputdevice_swap_compa_ports(&changed_prefs, 2);
+               break;
        case AKS_SWITCHINTERPOL:
                changed_prefs.sound_interpol++;
                if (changed_prefs.sound_interpol > 4)
@@ -3250,7 +3904,7 @@ static uae_u64 isqual (int evt)
 
 static int handle_input_event (int nr, int state, int max, int autofire, bool canstopplayback, bool playbackevent)
 {
-       struct inputevent *ie;
+       const struct inputevent *ie;
        int joy;
        bool isaks = false;
 
@@ -3624,15 +4278,15 @@ static int handle_input_event (int nr, int state, int max, int autofire, bool ca
 
 static void inputdevice_checkconfig (void)
 {
-       if (
-               currprefs.jports[0].id != changed_prefs.jports[0].id ||
-               currprefs.jports[1].id != changed_prefs.jports[1].id ||
-               currprefs.jports[2].id != changed_prefs.jports[2].id ||
-               currprefs.jports[3].id != changed_prefs.jports[3].id ||
-               currprefs.jports[0].mode != changed_prefs.jports[0].mode ||
-               currprefs.jports[1].mode != changed_prefs.jports[1].mode ||
-               currprefs.jports[2].mode != changed_prefs.jports[2].mode ||
-               currprefs.jports[3].mode != changed_prefs.jports[3].mode ||
+       bool changed = false;
+       for (int i = 0; i < MAX_JPORTS; i++) {
+               if (currprefs.jports[i].id != changed_prefs.jports[i].id ||
+                       currprefs.jports[i].mode != changed_prefs.jports[i].mode ||
+                       _tcscmp(currprefs.jports_custom[i].custom, changed_prefs.jports_custom[i].custom))
+                               changed = true;
+       }
+
+       if (changed ||
                currprefs.input_selected_setting != changed_prefs.input_selected_setting ||
                currprefs.input_joymouse_multiplier != changed_prefs.input_joymouse_multiplier ||
                currprefs.input_joymouse_deadzone != changed_prefs.input_joymouse_deadzone ||
@@ -3749,13 +4403,15 @@ static int getoldport (struct uae_input_device *id)
 
 static int switchdevice (struct uae_input_device *id, int num, bool buttonmode)
 {
-       int i, j;
        int ismouse = 0;
        int newport = 0;
+       int newslot = -1;
        int flags = 0;
        TCHAR *name = NULL, *fname = NULL;
        int otherbuttonpressed = 0;
        int acc = input_acquired;
+       const int *customswitch = NULL;
+
 
 #if SWITCH_DEBUG
        write_log (_T("switchdevice '%s' %d %d\n"), id->name, num, buttonmode);
@@ -3768,19 +4424,20 @@ static int switchdevice (struct uae_input_device *id, int num, bool buttonmode)
        if (!target_can_autoswitchdevice())
                return 0;
 
-       for (i = 0; i < MAX_INPUT_DEVICES; i++) {
+       for (int i = 0; i < MAX_INPUT_DEVICES; i++) {
                if (id == &joysticks[i]) {
                        name = idev[IDTYPE_JOYSTICK].get_uniquename (i);
                        fname = idev[IDTYPE_JOYSTICK].get_friendlyname (i);
                        newport = num == 0 ? 1 : 0;
                        flags = idev[IDTYPE_JOYSTICK].get_flags (i);
-                       for (j = 0; j < MAX_INPUT_DEVICES; j++) {
+                       for (int j = 0; j < MAX_INPUT_DEVICES; j++) {
                                if (j != i) {
                                        struct uae_input_device2 *id2 = &joysticks2[j];
                                        if (id2->buttonmask)
                                                otherbuttonpressed = 1;
                                }
                        }
+                       customswitch = custom_autoswitch_joy;
                }
                if (id == &mice[i]) {
                        ismouse = 1;
@@ -3788,6 +4445,7 @@ static int switchdevice (struct uae_input_device *id, int num, bool buttonmode)
                        fname = idev[IDTYPE_MOUSE].get_friendlyname (i);
                        newport = num == 0 ? 0 : 1;
                        flags = idev[IDTYPE_MOUSE].get_flags (i);
+                       customswitch = custom_autoswitch_mouse;
                }
        }
        if (!name) {
@@ -3810,7 +4468,7 @@ static int switchdevice (struct uae_input_device *id, int num, bool buttonmode)
 #if SWITCH_DEBUG
                write_log (_T("GAMEPORTS MODE %d %d\n"), currprefs.input_selected_setting, currprefs.jports[newport].id);
 #endif
-               if ((num == 0 || num == 1) && currprefs.jports[newport].id != JPORT_CUSTOM) {
+               if ((num == 0 || num == 1) && !JSEM_ISCUSTOM(newport, &currprefs)) {
 #if SWITCH_DEBUG
                        write_log (_T("Port supported\n"));
 #endif
@@ -3830,11 +4488,21 @@ static int switchdevice (struct uae_input_device *id, int num, bool buttonmode)
 #endif
                                return 0;
                        }
+
+                       for (int i = 0; i < MAX_JPORTS_CUSTOM; i++) {
+                               if (customswitch && customswitch[i] >= 0) {
+                                       newslot = customswitch[i];
+                                       name = currprefs.jports_custom[newslot].custom;
+                                       fname = name;
+                                       break;
+                               }
+                       }
+
 #if 1
                        if (ismouse) {
                                int nummouse = 0; // count number of non-supermouse mice
                                int supermouse = -1;
-                               for (i = 0; i < idev[IDTYPE_MOUSE].get_num (); i++) {
+                               for (int i = 0; i < idev[IDTYPE_MOUSE].get_num (); i++) {
                                        if (!idev[IDTYPE_MOUSE].get_flags (i))
                                                nummouse++;
                                        else
@@ -3858,8 +4526,13 @@ static int switchdevice (struct uae_input_device *id, int num, bool buttonmode)
                        write_log (_T("inputdevice gameports change '%s':%d->%d %d,%d\n"), name, num, newport, currprefs.input_selected_setting, currprefs.jports[newport].id);
 #endif
                        inputdevice_unacquire ();
-                       if (fname)
-                               statusline_add_message(_T("Port %d: %s"), newport, fname);
+                       if (fname) {
+                               if (newslot >= 0) {
+                                       statusline_add_message(_T("Port %d: Custom %d"), newport, newslot + 1);
+                               } else {
+                                       statusline_add_message(_T("Port %d: %s"), newport, fname);
+                               }
+                       }
 
                        if (currprefs.input_selected_setting != GAMEPORT_INPUT_SETTINGS && currprefs.jports[newport].id > JPORT_NONE) {
                                // disable old device
@@ -3907,8 +4580,14 @@ static int switchdevice (struct uae_input_device *id, int num, bool buttonmode)
                                }
                        }
 
-                       inputdevice_joyport_config (&changed_prefs, name, newport, -1, 2, false);
-                       inputdevice_validate_jports (&changed_prefs, -1);
+                       if (newslot >= 0) {
+                               TCHAR cust[100];
+                               _stprintf(cust, _T("custom%d"), newslot);
+                               inputdevice_joyport_config(&changed_prefs, cust, newport, -1, 0);
+                       } else {
+                               inputdevice_joyport_config (&changed_prefs, name, newport, -1, 2);
+                       }
+                       inputdevice_validate_jports (&changed_prefs, -1, NULL);
                        inputdevice_copyconfig (&changed_prefs, &currprefs);
                        if (acc)
                                inputdevice_acquire (TRUE);
@@ -3918,14 +4597,16 @@ static int switchdevice (struct uae_input_device *id, int num, bool buttonmode)
                write_log (_T("END1\n"));
 #endif
                return 0;
+
        } else {
+
 #if SWITCH_DEBUG
                write_log (_T("INPUTPANEL MODE %d\n"), flags);
 #endif
                int oldport = getoldport (id);
                int k, evt;
 
-               struct inputevent *ie, *ie2;
+               const struct inputevent *ie, *ie2;
                if (flags)
                        return 0;
                if (oldport <= 0) {
@@ -3937,7 +4618,7 @@ static int switchdevice (struct uae_input_device *id, int num, bool buttonmode)
                newport++;
                /* do not switch if switching mouse and any "supermouse" mouse enabled */
                if (ismouse) {
-                       for (i = 0; i < MAX_INPUT_SETTINGS; i++) {
+                       for (int i = 0; i < MAX_INPUT_SETTINGS; i++) {
                                if (mice[i].enabled && idev[IDTYPE_MOUSE].get_flags (i)) {
 #if SWITCH_DEBUG
                                        write_log(_T("SUPERMOUSE %d enabled\n"), i);
@@ -3946,7 +4627,7 @@ static int switchdevice (struct uae_input_device *id, int num, bool buttonmode)
                                }
                        }
                }
-               for (i = 0; i < MAX_INPUT_SETTINGS; i++) {
+               for (int i = 0; i < MAX_INPUT_SETTINGS; i++) {
                        if (getoldport (&joysticks[i]) == newport) {
                                joysticks[i].enabled = 0;
 #if SWITCH_DEBUG
@@ -3961,8 +4642,8 @@ static int switchdevice (struct uae_input_device *id, int num, bool buttonmode)
                        }
                }
                id->enabled = 1;
-               for (i = 0; i < MAX_INPUT_DEVICE_EVENTS; i++) {
-                       for (j = 0; j < MAX_INPUT_SUB_EVENT; j++) {
+               for (int i = 0; i < MAX_INPUT_DEVICE_EVENTS; i++) {
+                       for (int j = 0; j < MAX_INPUT_SUB_EVENT; j++) {
                                evt = id->eventid[i][j];
                                if (evt <= 0)
                                        continue;
@@ -3995,7 +4676,7 @@ static int switchdevice (struct uae_input_device *id, int num, bool buttonmode)
                if (fname)
                        statusline_add_message(_T("Port %d: %s"), newport, fname);
                inputdevice_copyconfig (&currprefs, &changed_prefs);
-               inputdevice_validate_jports (&changed_prefs, -1);
+               inputdevice_validate_jports (&changed_prefs, -1, NULL);
                inputdevice_copyconfig (&changed_prefs, &currprefs);
                if (acc)
                        inputdevice_acquire (TRUE);
@@ -4205,14 +4886,19 @@ static void setbuttonstateall (struct uae_input_device *id, struct uae_input_dev
 
        if (!id->enabled) {
                frame_time_t t = read_processor_time ();
+               if (!t)
+                       t++;
 
                if (buttonstate) {
                        switchdevice_timeout = t;
                } else {
-                       int port = button;
-                       if (t - switchdevice_timeout >= syncbase) // 1s
-                               port ^= 1;
-                       switchdevice (id, port, true);
+                       if (switchdevice_timeout) {
+                               int port = button;
+                               if (t - switchdevice_timeout >= syncbase) // 1s
+                                       port ^= 1;
+                               switchdevice (id, port, true);
+                       }
+                       switchdevice_timeout = 0;
                }
                return;
        }
@@ -4565,7 +5251,7 @@ int intputdevice_compa_get_eventtype (int evt, const int **axistablep)
        return IDEV_WIDGET_BUTTON;
 }
 
-static int rem_port1[] = {
+static const int rem_port1[] = {
        INPUTEVENT_MOUSE1_HORIZ, INPUTEVENT_MOUSE1_VERT,
        INPUTEVENT_JOY1_HORIZ, INPUTEVENT_JOY1_VERT,
        INPUTEVENT_JOY1_HORIZ_POT, INPUTEVENT_JOY1_VERT_POT,
@@ -4576,7 +5262,7 @@ static int rem_port1[] = {
        INPUTEVENT_LIGHTPEN_HORIZ, INPUTEVENT_LIGHTPEN_VERT,
        -1
 };
-static int rem_port2[] = {
+static const int rem_port2[] = {
        INPUTEVENT_MOUSE2_HORIZ, INPUTEVENT_MOUSE2_VERT,
        INPUTEVENT_JOY2_HORIZ, INPUTEVENT_JOY2_VERT,
        INPUTEVENT_JOY2_HORIZ_POT, INPUTEVENT_JOY2_VERT_POT,
@@ -4587,135 +5273,118 @@ static int rem_port2[] = {
        -1, -1,
        -1
 };
-static int rem_port3[] = {
+static const int rem_port3[] = {
        INPUTEVENT_PAR_JOY1_LEFT, INPUTEVENT_PAR_JOY1_RIGHT, INPUTEVENT_PAR_JOY1_UP, INPUTEVENT_PAR_JOY1_DOWN,
        INPUTEVENT_PAR_JOY1_FIRE_BUTTON, INPUTEVENT_PAR_JOY1_2ND_BUTTON,
        -1
 };
-static int rem_port4[] = {
+static const int rem_port4[] = {
        INPUTEVENT_PAR_JOY2_LEFT, INPUTEVENT_PAR_JOY2_RIGHT, INPUTEVENT_PAR_JOY2_UP, INPUTEVENT_PAR_JOY2_DOWN,
        INPUTEVENT_PAR_JOY2_FIRE_BUTTON, INPUTEVENT_PAR_JOY2_2ND_BUTTON,
        -1
 };
 
-static int *rem_ports[] = { rem_port1, rem_port2, rem_port3, rem_port4 };
-static int af_port1[] = {
-       INPUTEVENT_JOY1_FIRE_BUTTON, INPUTEVENT_JOY1_CD32_RED,
-       -1
-};
-static int af_port2[] = {
-       INPUTEVENT_JOY2_FIRE_BUTTON, INPUTEVENT_JOY2_CD32_RED,
-       -1
-};
-static int af_port3[] = {
-       INPUTEVENT_PAR_JOY1_FIRE_BUTTON, INPUTEVENT_PAR_JOY1_2ND_BUTTON,
-       -1
-};
-static int af_port4[] = {
-       INPUTEVENT_PAR_JOY2_FIRE_BUTTON, INPUTEVENT_PAR_JOY2_2ND_BUTTON,
-       -1
-};
-static int *af_ports[] = { af_port1, af_port2, af_port3, af_port4 };
-static int ip_joy1[] = {
+static const int *rem_ports[] = { rem_port1, rem_port2, rem_port3, rem_port4 };
+static const int ip_joy1[] = {
        INPUTEVENT_JOY1_LEFT, INPUTEVENT_JOY1_RIGHT, INPUTEVENT_JOY1_UP, INPUTEVENT_JOY1_DOWN,
        INPUTEVENT_JOY1_FIRE_BUTTON, INPUTEVENT_JOY1_2ND_BUTTON,
        -1
 };
-static int ip_joy2[] = {
+static const int ip_joy2[] = {
        INPUTEVENT_JOY2_LEFT, INPUTEVENT_JOY2_RIGHT, INPUTEVENT_JOY2_UP, INPUTEVENT_JOY2_DOWN,
        INPUTEVENT_JOY2_FIRE_BUTTON, INPUTEVENT_JOY2_2ND_BUTTON,
        -1
 };
-static int ip_joypad1[] = {
+static const int ip_joypad1[] = {
        INPUTEVENT_JOY1_LEFT, INPUTEVENT_JOY1_RIGHT, INPUTEVENT_JOY1_UP, INPUTEVENT_JOY1_DOWN,
        INPUTEVENT_JOY1_FIRE_BUTTON, INPUTEVENT_JOY1_2ND_BUTTON, INPUTEVENT_JOY1_3RD_BUTTON,
        -1
 };
-static int ip_joypad2[] = {
+static const int ip_joypad2[] = {
        INPUTEVENT_JOY2_LEFT, INPUTEVENT_JOY2_RIGHT, INPUTEVENT_JOY2_UP, INPUTEVENT_JOY2_DOWN,
        INPUTEVENT_JOY2_FIRE_BUTTON, INPUTEVENT_JOY2_2ND_BUTTON, INPUTEVENT_JOY2_3RD_BUTTON,
        -1
 };
-static int ip_joycd321[] = {
+static const int ip_joycd321[] = {
        INPUTEVENT_JOY1_LEFT, INPUTEVENT_JOY1_RIGHT, INPUTEVENT_JOY1_UP, INPUTEVENT_JOY1_DOWN,
        INPUTEVENT_JOY1_CD32_RED, INPUTEVENT_JOY1_CD32_BLUE, INPUTEVENT_JOY1_CD32_GREEN, INPUTEVENT_JOY1_CD32_YELLOW,
        INPUTEVENT_JOY1_CD32_RWD, INPUTEVENT_JOY1_CD32_FFW, INPUTEVENT_JOY1_CD32_PLAY,
        -1
 };
-static int ip_joycd322[] = {
+static const int ip_joycd322[] = {
        INPUTEVENT_JOY2_LEFT, INPUTEVENT_JOY2_RIGHT, INPUTEVENT_JOY2_UP, INPUTEVENT_JOY2_DOWN,
        INPUTEVENT_JOY2_CD32_RED, INPUTEVENT_JOY2_CD32_BLUE, INPUTEVENT_JOY2_CD32_GREEN, INPUTEVENT_JOY2_CD32_YELLOW,
        INPUTEVENT_JOY2_CD32_RWD, INPUTEVENT_JOY2_CD32_FFW, INPUTEVENT_JOY2_CD32_PLAY,
        -1
 };
-static int ip_parjoy1[] = {
+static const int ip_parjoy1[] = {
        INPUTEVENT_PAR_JOY1_LEFT, INPUTEVENT_PAR_JOY1_RIGHT, INPUTEVENT_PAR_JOY1_UP, INPUTEVENT_PAR_JOY1_DOWN,
        INPUTEVENT_PAR_JOY1_FIRE_BUTTON, INPUTEVENT_PAR_JOY1_2ND_BUTTON,
        -1
 };
-static int ip_parjoy2[] = {
+static const int ip_parjoy2[] = {
        INPUTEVENT_PAR_JOY2_LEFT, INPUTEVENT_PAR_JOY2_RIGHT, INPUTEVENT_PAR_JOY2_UP, INPUTEVENT_PAR_JOY2_DOWN,
        INPUTEVENT_PAR_JOY2_FIRE_BUTTON, INPUTEVENT_PAR_JOY2_2ND_BUTTON,
        -1
 };
-static int ip_parjoy1default[] = {
+static const int ip_parjoy1default[] = {
        INPUTEVENT_PAR_JOY1_LEFT, INPUTEVENT_PAR_JOY1_RIGHT, INPUTEVENT_PAR_JOY1_UP, INPUTEVENT_PAR_JOY1_DOWN,
        INPUTEVENT_PAR_JOY1_FIRE_BUTTON,
        -1
 };
-static int ip_parjoy2default[] = {
+static const int ip_parjoy2default[] = {
        INPUTEVENT_PAR_JOY2_LEFT, INPUTEVENT_PAR_JOY2_RIGHT, INPUTEVENT_PAR_JOY2_UP, INPUTEVENT_PAR_JOY2_DOWN,
        INPUTEVENT_PAR_JOY2_FIRE_BUTTON,
        -1
 };
-static int ip_mouse1[] = {
+static const int ip_mouse1[] = {
        INPUTEVENT_MOUSE1_LEFT, INPUTEVENT_MOUSE1_RIGHT, INPUTEVENT_MOUSE1_UP, INPUTEVENT_MOUSE1_DOWN,
        INPUTEVENT_JOY1_FIRE_BUTTON, INPUTEVENT_JOY1_2ND_BUTTON,
        -1
 };
-static int ip_mouse2[] = {
+static const int ip_mouse2[] = {
        INPUTEVENT_MOUSE2_LEFT, INPUTEVENT_MOUSE2_RIGHT, INPUTEVENT_MOUSE2_UP, INPUTEVENT_MOUSE2_DOWN,
        INPUTEVENT_JOY2_FIRE_BUTTON, INPUTEVENT_JOY2_2ND_BUTTON,
        -1
 };
-static int ip_mousecdtv[] =
+static const int ip_mousecdtv[] =
 {
        INPUTEVENT_MOUSE_CDTV_LEFT, INPUTEVENT_MOUSE_CDTV_RIGHT, INPUTEVENT_MOUSE_CDTV_UP, INPUTEVENT_MOUSE_CDTV_DOWN,
        INPUTEVENT_JOY1_FIRE_BUTTON, INPUTEVENT_JOY1_2ND_BUTTON,
        -1
 };
-static int ip_mediacdtv[] =
+static const int ip_mediacdtv[] =
 {
        INPUTEVENT_KEY_CDTV_PLAYPAUSE, INPUTEVENT_KEY_CDTV_STOP, INPUTEVENT_KEY_CDTV_PREV, INPUTEVENT_KEY_CDTV_NEXT,
        -1
 };
-static int ip_arcadia[] = {
+static const int ip_arcadia[] = {
        INPUTEVENT_SPC_ARCADIA_DIAGNOSTICS, INPUTEVENT_SPC_ARCADIA_PLAYER1, INPUTEVENT_SPC_ARCADIA_PLAYER2,
        INPUTEVENT_SPC_ARCADIA_COIN1, INPUTEVENT_SPC_ARCADIA_COIN2,
        -1
 };
-static int ip_lightpen1[] = {
+static const int ip_lightpen1[] = {
        INPUTEVENT_LIGHTPEN_HORIZ, INPUTEVENT_LIGHTPEN_VERT, INPUTEVENT_JOY1_3RD_BUTTON,
        -1
 };
-static int ip_lightpen2[] = {
+static const int ip_lightpen2[] = {
        INPUTEVENT_LIGHTPEN_HORIZ, INPUTEVENT_LIGHTPEN_VERT, INPUTEVENT_JOY2_3RD_BUTTON,
        -1
 };
-static int ip_analog1[] = {
+static const int ip_analog1[] = {
        INPUTEVENT_JOY1_HORIZ_POT, INPUTEVENT_JOY1_VERT_POT, INPUTEVENT_JOY1_LEFT, INPUTEVENT_JOY1_RIGHT,
        -1
 };
-static int ip_analog2[] = {
+static const int ip_analog2[] = {
        INPUTEVENT_JOY2_HORIZ_POT, INPUTEVENT_JOY2_VERT_POT, INPUTEVENT_JOY2_LEFT, INPUTEVENT_JOY2_RIGHT,
        -1
 };
 
-static int ip_arcadiaxa[] = {
+static const int ip_arcadiaxa[] = {
        -1
 };
 
-static void checkcompakb (int *kb, int *srcmap)
+static void checkcompakb (int *kb, const int *srcmap)
 {
        int found = 0, avail = 0;
        int j, k;
@@ -4770,30 +5439,6 @@ static void checkcompakb (int *kb, int *srcmap)
        }
 }
 
-static void setautofireevent (struct uae_input_device *uid, int num, int sub, int af, int index)
-{
-       if (!af)
-               return;
-#ifdef RETROPLATFORM
-       // don't override custom AF autofire mappings
-       if (rp_isactive ())
-               return;
-#endif
-       int *afp = af_ports[index];
-       for (int k = 0; afp[k] >= 0; k++) {
-               if (afp[k] == uid->eventid[num][sub]) {
-                       uid->flags[num][sub] &= ~ID_FLAG_AUTOFIRE_MASK;
-                       if (af >= JPORT_AF_NORMAL)
-                               uid->flags[num][sub] |= ID_FLAG_AUTOFIRE;
-                       if (af == JPORT_AF_TOGGLE)
-                               uid->flags[num][sub] |= ID_FLAG_TOGGLE;
-                       if (af == JPORT_AF_ALWAYS)
-                               uid->flags[num][sub] |= ID_FLAG_INVERTTOGGLE;
-                       return;
-               }
-       }
-}
-
 static void inputdevice_sparerestore (struct uae_input_device *uid, int num, int sub)
 {
        if (uid->port[num][SPARE_SUB_EVENT]) {
@@ -4838,33 +5483,22 @@ void inputdevice_sparecopy (struct uae_input_device *uid, int num, int sub)
        }
 }
 
-static void setcompakb (struct uae_prefs *p, int *kb, int *srcmap, int index, int af)
+static void setcompakb (struct uae_prefs *p, int *kb, const int *srcmap, int index, int af)
 {
        int j, k;
        k = j = 0;
        while (kb[j] >= 0 && srcmap[k] >= 0) {
                while (kb[j] >= 0) {
                        int id = kb[j];
+                       // default and active KB only
                        for (int m = 0; m < MAX_INPUT_DEVICES; m++) {
                                struct uae_input_device *uid = &keyboards[m];
-                               for (int l = 0; l < MAX_INPUT_DEVICE_EVENTS; l++) {
-                                       if (uid->extra[l] == id) {
-                                               inputdevice_sparecopy (uid, l, 0);
-
-                                               if (p->jports[index].nokeyboardoverride && uid->port[l][0] == 0) {
-                                                       uid->eventid[l][MAX_INPUT_SUB_EVENT - 1] = uid->eventid[l][0];
-                                                       uid->flags[l][MAX_INPUT_SUB_EVENT - 1] = uid->flags[l][0] | ID_FLAG_RESERVEDGAMEPORTSCUSTOM;
-                                                       uid->custom[l][MAX_INPUT_SUB_EVENT - 1] = my_strdup (uid->custom[l][0]);
-                                                       uid->eventid[l][MAX_INPUT_SUB_EVENT - 1] = uid->eventid[l][0];
+                               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);
+                                                       break;
                                                }
-
-                                               uid->eventid[l][0] = srcmap[k];
-                                               uid->flags[l][0] &= COMPA_RESERVED_FLAGS;
-                                               uid->port[l][0] = index + 1;
-                                               xfree (uid->custom[l][0]);
-                                               uid->custom[l][0] = NULL;
-                                               setautofireevent (uid, l, 0, af, index);
-                                               break;
                                        }
                                }
                        }
@@ -4969,7 +5603,7 @@ static void clearkbrevent (struct uae_input_device *uid, int evt)
 
 static void resetjport (struct uae_prefs *prefs, int index)
 {
-       int *p = rem_ports[index];
+       const int *p = rem_ports[index];
        while (*p >= 0) {
                int evtnum = *p++;
                for (int l = 0; l < MAX_INPUT_DEVICES; l++) {
@@ -5029,13 +5663,11 @@ static void remove_compa_config (struct uae_prefs *prefs, int index)
        }
 }
 
-static void cleardevgp (struct uae_input_device *uid, int num, bool nocustom, int index)
+static void cleardev_custom (struct uae_input_device *uid, int num, int index)
 {
        for (int i = 0; i < MAX_INPUT_DEVICE_EVENTS; i++) {
                for (int j = 0; j < MAX_INPUT_SUB_EVENT; j++) {
                        if (uid[num].port[i][j] == index + 1) {
-                               if (nocustom && (uid[num].flags[i][j] & ID_FLAG_GAMEPORTSCUSTOM_MASK))
-                                       continue;
                                uid[num].eventid[i][j] = 0;
                                uid[num].flags[i][j] &= COMPA_RESERVED_FLAGS;
                                xfree (uid[num].custom[i][j]);
@@ -5047,13 +5679,11 @@ static void cleardevgp (struct uae_input_device *uid, int num, bool nocustom, in
                }
        }
 }
-static void cleardevkbrgp (struct uae_input_device *uid, int num, bool nocustom, int index)
+static void cleardevkbr_custom(struct uae_input_device *uid, int num, int index)
 {
        for (int i = 0; i < MAX_INPUT_DEVICE_EVENTS; i++) {
                for (int j = 0; j < MAX_INPUT_SUB_EVENT; j++) {
                        if (uid[num].port[i][j] == index + 1) {
-                               if (nocustom && (uid[num].flags[i][j] & ID_FLAG_GAMEPORTSCUSTOM_MASK))
-                                       continue;
                                uid[num].eventid[i][j] = 0;
                                uid[num].flags[i][j] &= COMPA_RESERVED_FLAGS;
                                xfree (uid[num].custom[i][j]);
@@ -5070,12 +5700,12 @@ static void cleardevkbrgp (struct uae_input_device *uid, int num, bool nocustom,
 }
 
 // remove all gameports mappings mapped to port 'index'
-static void remove_custom_config (struct uae_prefs *prefs, bool nocustom, int index)
+static void remove_custom_config (struct uae_prefs *prefs, int index)
 {
        for (int l = 0; l < MAX_INPUT_DEVICES; l++) {
-               cleardevgp (joysticks, l, nocustom, index);
-               cleardevgp (mice, l, nocustom, index);
-               cleardevkbrgp (keyboards, l, nocustom, index);
+               cleardev_custom(joysticks, l, index);
+               cleardev_custom(mice, l, index);
+               cleardevkbr_custom (keyboards, l, index);
        }
 }
 
@@ -5083,19 +5713,17 @@ static void remove_custom_config (struct uae_prefs *prefs, bool nocustom, int in
 void inputdevice_compa_prepare_custom (struct uae_prefs *prefs, int index, int newmode, bool removeold)
 {
        int mode = prefs->jports[index].mode;
-       freejport (prefs, index);
-       resetjport (prefs, index);
        if (newmode >= 0) {
                mode = newmode;
        } else if (mode == 0) {
                mode = index == 0 ? JSEM_MODE_WHEELMOUSE : (prefs->cs_cd32cd ? JSEM_MODE_JOYSTICK_CD32 : JSEM_MODE_JOYSTICK);
        }
        prefs->jports[index].mode = mode;
-       prefs->jports[index].id = JPORT_CUSTOM;
 
        if (removeold) {
+               prefs->jports_custom[JSEM_GETCUSTOMIDX(index, prefs)].custom[0] = 0;
                remove_compa_config (prefs, index);
-               remove_custom_config (prefs, false, index);
+               remove_custom_config (prefs, index);
        }
 }
 // clear device before switching to new one
@@ -5124,7 +5752,8 @@ static void enablejoydevice (struct uae_input_device *uid, bool gameportsmode, i
        for (int i = 0; i < MAX_INPUT_DEVICE_EVENTS; i++) {
                for (int j = 0; j < MAX_INPUT_SUB_EVENT; j++) {
                        if ((gameportsmode && uid->eventid[i][j] == evtnum) || uid->port[i][j] > 0) {
-                               uid->enabled = 1;
+                               if (!uid->enabled)
+                                       uid->enabled = -1;
                        }
                }
        }
@@ -5137,7 +5766,7 @@ static void setjoydevices (struct uae_prefs *prefs, bool gameportsmode, int port
                for (int l = 0; l < MAX_INPUT_DEVICES; l++) {
                        enablejoydevice (&joysticks[l], gameportsmode, evtnum);
                        enablejoydevice (&mice[l], gameportsmode, evtnum);
-                       enablejoydevice (&keyboards[l], gameportsmode, evtnum);
+                       //enablejoydevice (&keyboards[l], gameportsmode, evtnum);
                }
                for (int k = 0; axistable[k] >= 0; k += 3) {
                        if (evtnum == axistable[k] || evtnum == axistable[k + 1] || evtnum == axistable[k + 2]) {
@@ -5146,7 +5775,7 @@ static void setjoydevices (struct uae_prefs *prefs, bool gameportsmode, int port
                                        for (int l = 0; l < MAX_INPUT_DEVICES; l++) {
                                                enablejoydevice (&joysticks[l], gameportsmode, evtnum2);
                                                enablejoydevice (&mice[l], gameportsmode, evtnum2);
-                                               enablejoydevice (&keyboards[l], gameportsmode, evtnum2);
+                                               //enablejoydevice (&keyboards[l], gameportsmode, evtnum2);
                                        }
                                }
                                break;
@@ -5192,7 +5821,7 @@ static void setjoyinputs (struct uae_prefs *prefs, int port)
 
 static void setautofire (struct uae_input_device *uid, int port, int af)
 {
-       int *afp = af_ports[port];
+       const int *afp = af_ports[port];
        for (int k = 0; afp[k] >= 0; k++) {
                for (int i = 0; i < MAX_INPUT_DEVICE_EVENTS; i++) {
                        for (int j = 0; j < MAX_INPUT_SUB_EVENT; j++) {
@@ -5233,12 +5862,10 @@ static void compatibility_copy (struct uae_prefs *prefs, bool gameports)
        for (i = 0; i < MAX_JPORTS; i++) {
                joymodes[i] = prefs->jports[i].mode;
                joyinputs[i] = NULL;
-               // remove all mappings from this port, except if custom
-               if (prefs->jports[i].id != JPORT_CUSTOM) {
-                       if (gameports)
-                               remove_compa_config (prefs, i);
-               }
-               remove_custom_config (prefs, prefs->jports[i].id == JPORT_CUSTOM, i);
+               // remove all mappings from this port
+               if (gameports)
+                       remove_compa_config (prefs, i);
+               remove_custom_config (prefs, i);
                setjoyinputs (prefs, i);
        }
 
@@ -5459,10 +6086,6 @@ static void compatibility_copy (struct uae_prefs *prefs, bool gameports)
                                                kb = keyboard_default_kbmaps[KBR_DEFAULT_MAP_SE3];
                                        else
                                                kb = keyboard_default_kbmaps[KBR_DEFAULT_MAP_SE];
-                               } else if (JSEM_ISXARCADE1 (i, prefs)) {
-                                       kb = keyboard_default_kbmaps[KBR_DEFAULT_MAP_XA1];
-                               } else if (JSEM_ISXARCADE2 (i, prefs)) {
-                                       kb = keyboard_default_kbmaps[KBR_DEFAULT_MAP_XA2];
                                }
                                if (kb) {
                                        switch (mode)
@@ -5495,8 +6118,6 @@ static void compatibility_copy (struct uae_prefs *prefs, bool gameports)
        }
        if (arcadia_bios) {
                setcompakb (prefs, keyboard_default_kbmaps[KBR_DEFAULT_MAP_ARCADIA], ip_arcadia, 0, 0);
-               if (JSEM_ISXARCADE1 (i, prefs) || JSEM_ISXARCADE2 (i, prefs))
-                       setcompakb (prefs, keyboard_default_kbmaps[KBR_DEFAULT_MAP_ARCADIA_XA], ip_arcadiaxa, JSEM_ISXARCADE2 (i, prefs) ? 1 : 0, prefs->jports[i].autofire);
        }
        if (0 && currprefs.cs_cdtvcd) {
                setcompakb (prefs, keyboard_default_kbmaps[KBR_DEFAULT_MAP_CDTV], ip_mediacdtv, 0, 0);
@@ -5529,10 +6150,6 @@ static void compatibility_copy (struct uae_prefs *prefs, bool gameports)
                                        kb = keyboard_default_kbmaps[KBR_DEFAULT_MAP_CK];
                                else if (JSEM_ISSOMEWHEREELSE (i, prefs))
                                        kb = keyboard_default_kbmaps[KBR_DEFAULT_MAP_SE];
-                               else if (JSEM_ISXARCADE1 (i, prefs))
-                                       kb = keyboard_default_kbmaps[KBR_DEFAULT_MAP_XA1];
-                               else if (JSEM_ISXARCADE2 (i, prefs))
-                                       kb = keyboard_default_kbmaps[KBR_DEFAULT_MAP_XA2];
                                if (kb) {
                                        setcompakb (prefs, kb, i == 3 ? ip_parjoy2default : ip_parjoy1default, i, prefs->jports[i].autofire);
                                        used[joy] = 1;
@@ -5543,6 +6160,9 @@ static void compatibility_copy (struct uae_prefs *prefs, bool gameports)
        }
 
        for (i = 0; i < MAX_JPORTS; i++) {
+               if (JSEM_ISCUSTOM(i, prefs)) {
+                       inputdevice_parse_jport_custom(prefs, prefs->jports[i].id - JSEM_CUSTOM, i, NULL);
+               }
                if (gameports)
                        setautofires (prefs, i, prefs->jports[i].autofire);
        }
@@ -5561,14 +6181,16 @@ static void disableifempty2 (struct uae_input_device *uid)
                                return;
                }
        }
-       uid->enabled = false;
+       if (uid->enabled < 0)
+               uid->enabled = 0;
 }
 static void disableifempty (struct uae_prefs *prefs)
 {
        for (int l = 0; l < MAX_INPUT_DEVICES; l++) {
                disableifempty2 (&joysticks[l]);
                disableifempty2 (&mice[l]);
-               disableifempty2 (&keyboards[l]);
+               if (!input_get_default_keyboard(l))
+                       disableifempty2 (&keyboards[l]);
        }
        prefs->internalevent_settings[0]->enabled = true;
 }
@@ -5667,7 +6289,7 @@ static void matchdevices_all (struct uae_prefs *prefs)
 bool inputdevice_set_gameports_mapping (struct uae_prefs *prefs, int devnum, int num, int evtnum, uae_u64 flags, int port, int input_selected_setting)
 {
        TCHAR name[256];
-       struct inputevent *ie;
+       const struct inputevent *ie;
        int sub;
 
        if (evtnum < 0) {
@@ -5750,19 +6372,24 @@ static void resetinput (void)
                sublevdir[0][i] = i;
                sublevdir[1][i] = MAX_INPUT_SUB_EVENT - i - 1;
        }
+       for (int i = 0; i < MAX_JPORTS_CUSTOM; i++) {
+               custom_autoswitch_joy[i] = -1;
+               custom_autoswitch_mouse[i] = -1;
+       }
 }
 
-
-void inputdevice_updateconfig_internal (const struct uae_prefs *srcprrefs, struct uae_prefs *dstprefs)
+void inputdevice_updateconfig_internal (const struct uae_prefs *srcprefs, struct uae_prefs *dstprefs)
 {
-       int i;
-
        keyboard_default = keyboard_default_table[currprefs.input_keyboard_type];
 
-       copyjport (srcprrefs, dstprefs, 0);
-       copyjport (srcprrefs, dstprefs, 1);
-       copyjport (srcprrefs, dstprefs, 2);
-       copyjport (srcprrefs, dstprefs, 3);
+       for (int i = 0; i < MAX_JPORTS; i++) {
+               copyjport (srcprefs, dstprefs, i);
+       }
+       if (srcprefs) {
+               for (int i = 0; i < MAX_JPORTS_CUSTOM; i++) {
+                       _tcscpy(dstprefs->jports_custom[i].custom, srcprefs->jports_custom[i].custom);
+               }
+       }
 
        resetinput ();
 
@@ -5776,17 +6403,27 @@ void inputdevice_updateconfig_internal (const struct uae_prefs *srcprrefs, struc
        memset (joysticks2, 0, sizeof joysticks2);
        memset (mice2, 0, sizeof mice2);
 
+       int input_selected_setting = dstprefs->input_selected_setting;
+
        joysticks = dstprefs->joystick_settings[GAMEPORT_INPUT_SETTINGS];
        mice = dstprefs->mouse_settings[GAMEPORT_INPUT_SETTINGS];
        keyboards = dstprefs->keyboard_settings[GAMEPORT_INPUT_SETTINGS];
        internalevents = dstprefs->internalevent_settings[GAMEPORT_INPUT_SETTINGS];
+       dstprefs->input_selected_setting = GAMEPORT_INPUT_SETTINGS;
 
-       for (i = 0; i < MAX_INPUT_SETTINGS; i++) {
+       for (int i = 0; i < MAX_INPUT_SETTINGS; i++) {
                joysticks[i].enabled = 0;
                mice[i].enabled = 0;
        }
 
+       for (int i = 0; i < MAX_JPORTS_CUSTOM; i++) {
+               inputdevice_parse_jport_custom(dstprefs, i, -1, NULL);
+       }
+
        compatibility_copy (dstprefs, true);
+
+       dstprefs->input_selected_setting = input_selected_setting;
+
        joysticks = dstprefs->joystick_settings[dstprefs->input_selected_setting];
        mice = dstprefs->mouse_settings[dstprefs->input_selected_setting];
        keyboards = dstprefs->keyboard_settings[dstprefs->input_selected_setting];
@@ -5806,6 +6443,10 @@ void inputdevice_updateconfig (const struct uae_prefs *srcprefs, struct uae_pref
        
        set_config_changed ();
 
+       for (int i = 0; i < MAX_JPORTS; i++) {
+               inputdevice_store_used_device(dstprefs, i);
+       }
+
 #ifdef RETROPLATFORM
        rp_input_change (0);
        rp_input_change (1);
@@ -5826,17 +6467,21 @@ void inputdevice_devicechange (struct uae_prefs *prefs)
        int i, idx;
        TCHAR *jports_name[MAX_JPORTS];
        TCHAR *jports_configname[MAX_JPORTS];
-       int jportskb[MAX_JPORTS], jportsmode[MAX_JPORTS];
+       int jportskb[MAX_JPORTS], jportscustom[MAX_JPORTS];
+       int jportsmode[MAX_JPORTS];
        int jportid[MAX_JPORTS], jportaf[MAX_JPORTS];
 
        for (i = 0; i < MAX_JPORTS; i++) {
                jportskb[i] = -1;
+               jportscustom[i] = -1;
                jportid[i] = prefs->jports[i].id;
                jportaf[i] = prefs->jports[i].autofire;
                jports_name[i] = NULL;
                jports_configname[i] = NULL;
                idx = inputdevice_getjoyportdevice (i, prefs->jports[i].id);
-               if (idx >= JSEM_LASTKBD) {
+               if (idx >= JSEM_LASTKBD + inputdevice_get_device_total(IDTYPE_MOUSE) + inputdevice_get_device_total(IDTYPE_JOYSTICK)) {
+                       jportscustom[i] = idx - (JSEM_LASTKBD + inputdevice_get_device_total(IDTYPE_MOUSE) + inputdevice_get_device_total(IDTYPE_JOYSTICK));
+               } else if (idx >= JSEM_LASTKBD) {
                        if (prefs->jports[i].name[0] == 0 && prefs->jports[i].configname[0] == 0) {
                                struct inputdevice_functions *idf;
                                int devidx;
@@ -5869,16 +6514,22 @@ void inputdevice_devicechange (struct uae_prefs *prefs)
 
        for (i = 0; i < MAX_JPORTS; i++) {
                freejport (prefs, i);
-               if (jportid[i] == JPORT_CUSTOM) {
-                       inputdevice_joyport_config (prefs, _T("custom"), i, jportsmode[i], 0, true);
+               if (jportscustom[i] >= 0) {
+                       TCHAR tmp[10];
+                       _stprintf(tmp, _T("custom%d"), jportscustom[i]);
+                       inputdevice_joyport_config(prefs, tmp, i, jportsmode[i], 0);
                } else if (jports_name[i][0] || jports_configname[i][0]) {
-                       if (!inputdevice_joyport_config (prefs, jports_configname[i], i, jportsmode[i], 1, true)) {
-                               inputdevice_joyport_config (prefs, jports_name[i], i, jportsmode[i], 2, true);
+                       bool found = true;
+                       if (!inputdevice_joyport_config (prefs, jports_configname[i], i, jportsmode[i], 1)) {
+                               found = inputdevice_joyport_config (prefs, jports_name[i], i, jportsmode[i], 2) != 0;
+                       }
+                       if (!found) {
+                               inputdevice_joyport_config(prefs, _T("joydefault"), i, jportsmode[i], 0);
                        }
                } else if (jportskb[i] >= 0) {
                        TCHAR tmp[10];
                        _stprintf (tmp, _T("kbd%d"), jportskb[i] + 1);
-                       inputdevice_joyport_config (prefs, tmp, i, jportsmode[i], 0, true);
+                       inputdevice_joyport_config (prefs, tmp, i, jportsmode[i], 0);
                }
                prefs->jports[i].autofire = jportaf[i];
                xfree (jports_name[i]);
@@ -6145,10 +6796,16 @@ static void sendmmcodes (int code, int newstate)
 // main keyboard press/release entry point
 int inputdevice_translatekeycode (int keyboard, int scancode, int state)
 {
+       // if not default keyboard and all events are empty: use default keyboard
+       if (!input_get_default_keyboard(keyboard) && isemptykey(keyboard, scancode)) {
+               keyboard = input_get_default_keyboard(-1);
+       }
        if (inputdevice_translatekeycode_2 (keyboard, scancode, state, false))
                return 1;
-       if (currprefs.mmkeyboard && scancode > 0)
+       if (currprefs.mmkeyboard && scancode > 0) {
                sendmmcodes (scancode, state);
+               return 1;
+       }
        return 0;
 }
 void inputdevice_checkqualifierkeycode (int keyboard, int scancode, int state)
@@ -6399,56 +7056,6 @@ int inputdevice_get_device_index (int devnum)
        return -1;
 }
 
-static int getdevnum (int type, int devnum)
-{
-       int jcnt = idev[IDTYPE_JOYSTICK].get_num ();
-       int mcnt = idev[IDTYPE_MOUSE].get_num ();
-       int kcnt = idev[IDTYPE_KEYBOARD].get_num ();
-
-       if (type == IDTYPE_JOYSTICK)
-               return devnum;
-       else if (type == IDTYPE_MOUSE)
-               return jcnt + devnum;
-       else if (type == IDTYPE_KEYBOARD)
-               return jcnt + mcnt + devnum;
-       else if (type == IDTYPE_INTERNALEVENT)
-               return jcnt + mcnt + kcnt + devnum;
-       return -1;
-}
-
-static int gettype (int devnum)
-{
-       int jcnt = idev[IDTYPE_JOYSTICK].get_num ();
-       int mcnt = idev[IDTYPE_MOUSE].get_num ();
-       int kcnt = idev[IDTYPE_KEYBOARD].get_num ();
-
-       if (devnum < jcnt)
-               return IDTYPE_JOYSTICK;
-       else if (devnum < jcnt + mcnt)
-               return IDTYPE_MOUSE;
-       else if (devnum < jcnt + mcnt + kcnt)
-               return IDTYPE_KEYBOARD;
-       else if (devnum < jcnt + mcnt + kcnt + INTERNALEVENT_COUNT)
-               return IDTYPE_INTERNALEVENT;
-       return -1;
-}
-
-static struct inputdevice_functions *getidf (int devnum)
-{
-       int type = gettype (devnum);
-       if (type < 0)
-               return NULL;
-       return &idev[type];
-}
-
-struct inputevent *inputdevice_get_eventinfo (int evt)
-{
-       if (evt > 0 && !events[evt].name)
-               return NULL;
-       return &events[evt];
-}
-
-
 /* returns number of devices of type "type" */
 int inputdevice_get_device_total (int type)
 {
@@ -6476,7 +7083,7 @@ int inputdevice_get_device_status (int devnum)
        if (idf == NULL)
                return -1;
        struct uae_input_device *uid = get_uid (idf, inputdevice_get_device_index (devnum));
-       return uid->enabled;
+       return uid->enabled != 0;
 }
 
 /* set state (enabled/disabled) */
@@ -6516,7 +7123,7 @@ int inputdevice_iterate (int devnum, int num, TCHAR *name, int *af)
 {
        const struct inputdevice_functions *idf = getidf (devnum);
        static int id_iterator;
-       struct inputevent *ie;
+       const struct inputevent *ie;
        int mask, data, type;
        uae_u64 flags;
        int devindex = inputdevice_get_device_index (devnum);
@@ -6547,7 +7154,7 @@ int inputdevice_iterate (int devnum, int num, TCHAR *name, int *af)
                        mask |= AM_K;
                }
                if (ie->allow_mask & AM_INFO) {
-                       struct inputevent *ie2 = ie + 1;
+                       const struct inputevent *ie2 = ie + 1;
                        while (!(ie2->allow_mask & AM_INFO)) {
                                if (is_event_used (idf, devindex, ie2 - ie, -1)) {
                                        ie2++;
@@ -6743,7 +7350,7 @@ static void swapevent (struct uae_input_device *uid, int i, int j, int evt)
        uid->port[i][j] = port;
 }
 
-static void swapjoydevice (struct uae_input_device *uid, int **swaps)
+static void swapjoydevice (struct uae_input_device *uid, const int **swaps)
 {
        for (int i = 0; i < MAX_INPUT_DEVICE_EVENTS; i++) {
                for (int j = 0; j < MAX_INPUT_SUB_EVENT; j++) {
@@ -6781,8 +7388,9 @@ static void swapjoydevice (struct uae_input_device *uid, int **swaps)
 void inputdevice_swap_compa_ports (struct uae_prefs *prefs, int portswap)
 {
        struct jport tmp;
+#if 0
        if ((prefs->jports[portswap].id == JPORT_CUSTOM || prefs->jports[portswap + 1].id == JPORT_CUSTOM)) {
-               int *swaps[2];
+               const int *swaps[2];
                swaps[0] = rem_ports[portswap];
                swaps[1] = rem_ports[portswap + 1];
                for (int l = 0; l < MAX_INPUT_DEVICES; l++) {
@@ -6791,6 +7399,7 @@ void inputdevice_swap_compa_ports (struct uae_prefs *prefs, int portswap)
                        swapjoydevice (&prefs->keyboard_settings[GAMEPORT_INPUT_SETTINGS][l], swaps);
                }
        }
+#endif
        memcpy (&tmp, &prefs->jports[portswap], sizeof (struct jport));
        memcpy (&prefs->jports[portswap], &prefs->jports[portswap + 1], sizeof (struct jport));
        memcpy (&prefs->jports[portswap + 1], &tmp, sizeof (struct jport));
@@ -6925,8 +7534,9 @@ void inputdevice_acquire (int allmode)
                if ((use_mice[i] && allmode >= 0) || (allmode && !idev[IDTYPE_MOUSE].get_flags (i)))
                        idev[IDTYPE_MOUSE].acquire (i, allmode < 0);
        }
+       // Always acquire first + enabled keyboards
        for (i = 0; i < MAX_INPUT_DEVICES; i++) {
-               if ((use_keyboards[i] && allmode >= 0) || (allmode <  0 && !idev[IDTYPE_KEYBOARD].get_flags (i)))
+               if (use_keyboards[i] || i == 0)
                        idev[IDTYPE_KEYBOARD].acquire (i, allmode < 0);
        }
 
@@ -7395,12 +8005,10 @@ int jsem_iskbdjoy (int port, const struct uae_prefs *p)
        return v;
 }
 
-static struct jport stored_ports[MAX_JPORTS];
-
 static void fixjport (struct jport *port, int add, bool always)
 {
        int vv = port->id;
-       if (vv == JPORT_CUSTOM || vv == JPORT_NONE)
+       if (vv == JPORT_NONE)
                return;
        if (vv >= JSEM_JOYS && vv < JSEM_MICE) {
                vv -= JSEM_JOYS;
@@ -7420,6 +8028,12 @@ static void fixjport (struct jport *port, int add, bool always)
                if (vv >= JSEM_LASTKBD)
                        vv = 0;
                vv += JSEM_KBDLAYOUT;
+       } else if (vv >= JSEM_CUSTOM && vv < JSEM_CUSTOM + MAX_JPORTS_CUSTOM) {
+               vv -= JSEM_CUSTOM;
+               vv += add;
+               if (vv >= MAX_JPORTS_CUSTOM)
+                       vv = 0;
+               vv += JSEM_CUSTOM;
        }
        if (port->id != vv || always) {
                if (vv >= JSEM_JOYS && vv < JSEM_MICE) {
@@ -7439,42 +8053,77 @@ static void fixjport (struct jport *port, int add, bool always)
        port->id = vv;
 }
 
-void inputdevice_validate_jports (struct uae_prefs *p, int changedport)
+static void inputdevice_get_previous_joy(struct uae_prefs *p, int portnum)
 {
-       int i, j;
-       for (i = 0; i < MAX_JPORTS; i++)
+       bool found = false;
+       int idx = 0;
+       for (;;) {
+               struct jport *jp = inputdevice_get_used_device(portnum, idx);
+               if (!jp)
+                       break;
+               if (jp->configname[0]) {
+                       found = inputdevice_joyport_config(p, jp->configname, portnum, jp->mode, 2) != 0;
+               } else if (jp->id < JSEM_JOYS) {
+                       p->jports[portnum].id = jp->id;
+                       found = true;
+               }
+               if (found) {
+                       inputdevice_set_newest_used_device(portnum, jp);
+                       break;
+               }
+               idx++;
+       }
+       if (!found) {
+               if (default_keyboard_layout[portnum] > 0) {
+                       p->jports[portnum].id = default_keyboard_layout[portnum] - 1;
+               } else {
+                       p->jports[portnum].id = JPORT_NONE;
+               }
+       }
+}
+
+void inputdevice_validate_jports (struct uae_prefs *p, int changedport, bool *fixedports)
+{
+       for (int i = 0; i < MAX_JPORTS; i++) {
                fixjport (&p->jports[i], 0, changedport == i);
-       for (i = 0; i < MAX_JPORTS; i++) {
+       }
+
+       for (int i = 0; i < MAX_JPORTS; i++) {
                if (p->jports[i].id < 0)
                        continue;
-               for (j = 0; j < MAX_JPORTS; j++) {
+               for (int j = 0; j < MAX_JPORTS; j++) {
                        if (p->jports[j].id < 0)
                                continue;
                        if (j == i)
                                continue;
                        if (p->jports[i].id == p->jports[j].id) {
-                               if (i == changedport) {
-                                       //write_log(_T("inputdevice_validate_jports restore i %d %d\n"), i, j);
-                                       restore_inputdevice_config (p, j);
-                               } else if (j == changedport) {
-                                       //write_log(_T("inputdevice_validate_jports restore j %d %d\n"), i, j);
-                                       restore_inputdevice_config (p, i);
-                               }
                                int cnt = 0;
                                while (p->jports[i].id == p->jports[j].id) {
                                        int k;
                                        if (i == changedport) {
                                                k = j;
+                                               if (fixedports && fixedports[k]) {
+                                                       k = i;
+                                               }
                                        } else {
                                                k = i;
                                        }
+                                       if (cnt >= 0) {
+                                               struct jport *jp = inputdevice_get_used_device(k, cnt);
+                                               if (jp) {
+                                                       memcpy(&p->jports[k].id, jp, sizeof(struct jport));
+                                                       cnt++;
+                                                       continue;
+                                               }
+                                               cnt = -1;
+                                       }
                                        fixjport (&p->jports[k], 1, true);
-                                       cnt++;
-                                       if (cnt 10) {
+                                       cnt--;
+                                       if (cnt < -10) {
                                                p->jports[k].id = JSEM_KBDLAYOUT;
                                                fixjport (&p->jports[k], 1, true);
                                        }
-                                       if (cnt 20)
+                                       if (cnt < -20)
                                                break;
                                }
                        }
@@ -7482,24 +8131,7 @@ void inputdevice_validate_jports (struct uae_prefs *p, int changedport)
        }
 }
 
-static void inputdevice_inserted (struct uae_prefs *p, int portnum, int id, int type)
-{
-       for (int k = 0; k < MAX_JPORTS; k++) {
-               if (p->jports[k].id == id && k != portnum) {
-                       if (type == IDTYPE_JOYSTICK) {
-                               // if this joystick is already in port 0, reset port 0 back to original
-                               if (k == 0 && portnum == 1) {
-                                       memcpy (&p->jports[0], &stored_ports[0], sizeof (struct jport));
-                                       return;
-                               }
-                       } else if (type == IDTYPE_MOUSE) {
-                               return;
-                       }
-                       return;
-               }
-       }
-}
-
+#if 0
 void store_inputdevice_config (struct uae_prefs *p)
 {
        for (int i = 0; i < MAX_JPORTS; i++) {
@@ -7510,8 +8142,31 @@ void restore_inputdevice_config (struct uae_prefs *p, int portnum)
 {
        memcpy (&p->jports[portnum], &stored_ports[portnum], sizeof (struct jport));
 }
+#endif
+
+struct jport_config
+{
+       TCHAR name[MAX_JPORTNAME];
+       TCHAR configname[MAX_JPORTNAME];
+       TCHAR id[MAX_JPORTNAME];
+       int mode;
+};
+static struct jport_config jport_config_store[MAX_JPORTS];
+
+void inputdevice_joyport_config_store(struct uae_prefs *p, const TCHAR *value, int portnum, int mode, int type)
+{
+       struct jport_config *jp = &jport_config_store[portnum];
+       if (type == 2) {
+               _tcscpy(jp->name, value);
+       } else if (type == 1) {
+               _tcscpy(jp->configname, value);
+       } else {
+               _tcscpy(jp->id, value);
+       }
+       jp->mode = mode;
+}
 
-int inputdevice_joyport_config (struct uae_prefs *p, const TCHAR *value, int portnum, int mode, int type, bool validate)
+int inputdevice_joyport_config (struct uae_prefs *p, const TCHAR *value, int portnum, int mode, int type)
 {
        switch (type)
        {
@@ -7535,8 +8190,6 @@ int inputdevice_joyport_config (struct uae_prefs *p, const TCHAR *value, int por
                                for (i = 0; i < idf->get_num (); i++) {
                                        TCHAR *name2 = idf->get_uniquename (i);
                                        if (name2 && !_tcscmp (name2, value)) {
-                                               if (validate)
-                                                       inputdevice_inserted (p, portnum, idnum + i, type);
                                                p->jports[portnum].id = idnum + i;
                                                if (mode >= 0)
                                                        p->jports[portnum].mode = mode;
@@ -7547,8 +8200,6 @@ int inputdevice_joyport_config (struct uae_prefs *p, const TCHAR *value, int por
                                for (i = 0; i < idf->get_num (); i++) {
                                        TCHAR *name1 = idf->get_friendlyname (i);
                                        if (name1 && !_tcscmp (name1, value)) {
-                                               if (validate)
-                                                       inputdevice_inserted (p, portnum, idnum + i, type);
                                                p->jports[portnum].id = idnum + i;
                                                if (mode >= 0)
                                                        p->jports[portnum].mode = mode;
@@ -7563,12 +8214,20 @@ int inputdevice_joyport_config (struct uae_prefs *p, const TCHAR *value, int por
                {
                        int start = JPORT_NONE, got = 0, max = -1;
                        int type = -1;
-                       const TCHAR *pp = 0;
+                       const TCHAR *pp = NULL;
                        if (_tcsncmp (value, _T("kbd"), 3) == 0) {
                                start = JSEM_KBDLAYOUT;
                                pp = value + 3;
                                got = 1;
                                max = JSEM_LASTKBD;
+                       } else if (_tcscmp(value, _T("joydefault")) == 0) {
+                               type = IDTYPE_JOYSTICK;
+                               start = JSEM_JOYS;
+                               got = 1;
+                       } else if (_tcscmp(value, _T("mousedefault")) == 0) {
+                               type = IDTYPE_MOUSE;
+                               start = JSEM_MICE;
+                               got = 1;
                        } else if (_tcsncmp (value, _T("joy"), 3) == 0) {
                                type = IDTYPE_JOYSTICK;
                                start = JSEM_JOYS;
@@ -7581,11 +8240,18 @@ int inputdevice_joyport_config (struct uae_prefs *p, const TCHAR *value, int por
                                pp = value + 5;
                                got = 1;
                                max = idev[IDTYPE_MOUSE].get_num ();
-                       } else if (_tcscmp (value, _T("none")) == 0) {
+                       } else if (_tcscmp(value, _T("none")) == 0) {
                                got = 2;
                        } else if (_tcscmp (value, _T("custom")) == 0) {
+                               // obsolete custom
+                               start = JSEM_CUSTOM + portnum;
+                               got = 3;
+                       } else if (_tcsncmp(value, _T("custom"), 6) == 0) {
+                               // new custom
+                               start = JSEM_CUSTOM;
+                               pp = value + 6;
                                got = 2;
-                               start = JPORT_CUSTOM;
+                               max = MAX_JPORTS_CUSTOM;
                        }
                        if (got) {
                                if (pp && max != 0) {
@@ -7601,24 +8267,25 @@ int inputdevice_joyport_config (struct uae_prefs *p, const TCHAR *value, int por
                                                }
                                        }
                                }
-                               if (got == 2) {
-                                       if (validate)
-                                               inputdevice_inserted (p, portnum, start, type);
+                               if (got >= 2) {
                                        p->jports[portnum].id = start;
                                        if (mode >= 0)
                                                p->jports[portnum].mode = mode;
                                        if (start < JSEM_JOYS)
                                                default_keyboard_layout[portnum] = start + 1;
+                                       if (got == 2) {
+                                               inputdevice_store_used_device(p, portnum);
+                                       }
+                                       if (got == 3) {
+                                               // mark for old custom handling
+                                               _tcscpy(p->jports_custom[portnum].custom, _T("#"));
+                                       }
                                        set_config_changed ();
                                        return 1;
                                }
-                               // joystick not found, select default
+                               // joystick not found, select previously used or default
                                if (start == JSEM_JOYS && p->jports[portnum].id < JSEM_JOYS) {
-                                       if (default_keyboard_layout[portnum] > 0) {
-                                               p->jports[portnum].id = default_keyboard_layout[portnum] - 1;
-                                       } else {
-                                               p->jports[portnum].id = JPORT_NONE;
-                                       }
+                                       inputdevice_get_previous_joy(p, portnum);
                                        set_config_changed ();
                                        return 1;
                                }
@@ -7632,11 +8299,7 @@ int inputdevice_joyport_config (struct uae_prefs *p, const TCHAR *value, int por
 int inputdevice_getjoyportdevice (int port, int val)
 {
        int idx;
-       if (val == JPORT_CUSTOM) {
-               idx = inputdevice_get_device_total (IDTYPE_JOYSTICK) + JSEM_LASTKBD;
-               if (port < 2)
-                       idx += inputdevice_get_device_total (IDTYPE_MOUSE);
-       } else if (val < 0) {
+       if (val < 0) {
                idx = -1;
        } else if (val >= JSEM_MICE) {
                idx = val - JSEM_MICE;
@@ -7650,12 +8313,86 @@ int inputdevice_getjoyportdevice (int port, int val)
                if (idx >= inputdevice_get_device_total (IDTYPE_JOYSTICK))
                        idx = 0;
                idx += JSEM_LASTKBD;
+       } else if (val >= JSEM_CUSTOM) {
+               idx = val - JSEM_CUSTOM;
+               if (idx >= MAX_JPORTS_CUSTOM)
+                       idx = 0;
+               if (port >= 2) {
+                       idx += JSEM_LASTKBD + inputdevice_get_device_total(IDTYPE_JOYSTICK);
+               } else {
+                       idx += JSEM_LASTKBD + inputdevice_get_device_total(IDTYPE_MOUSE) + inputdevice_get_device_total(IDTYPE_JOYSTICK);
+               }
        } else {
                idx = val - JSEM_KBDLAYOUT;
        }
        return idx;
 }
 
+void inputdevice_fix_prefs(struct uae_prefs *p)
+{
+       // Convert old style custom mapping to new style
+       for (int i = 0; i < MAX_JPORTS_CUSTOM; i++) {
+               struct jport_custom *jpc = &p->jports_custom[i];
+               if (!_tcscmp(jpc->custom, _T("#"))) {
+                       TCHAR tmp[16];
+                       _stprintf(tmp, _T("custom%d"), i);
+                       inputdevice_joyport_config(p, tmp, i, -1, 0);
+                       inputdevice_generate_jport_custom(p, i);
+               }
+       }
+       bool matched[MAX_JPORTS];
+       // configname first
+       for (int i = 0; i < MAX_JPORTS; i++) {
+               struct jport_config *jp = &jport_config_store[i];
+               matched[i] = false;
+               if (jp->configname[0]) {
+                       if (inputdevice_joyport_config(p, jp->configname, i, jp->mode, 1)) {
+                               inputdevice_validate_jports(p, i, matched);
+                               inputdevice_store_used_device(p, i);
+                               matched[i] = true;
+                       }
+               }
+       }
+       // friendly name next
+       for (int i = 0; i < MAX_JPORTS; i++) {
+               if (!matched[i]) {
+                       struct jport_config *jp = &jport_config_store[i];
+                       if (jp->name[0]) {
+                               if (inputdevice_joyport_config(p, jp->configname, i, jp->mode, 2)) {
+                                       inputdevice_validate_jports(p, i, matched);
+                                       inputdevice_store_used_device(p, i);
+                                       matched[i] = true;
+                               }
+                       }
+               }
+       }
+       // joyportX last
+       for (int i = 0; i < MAX_JPORTS; i++) {
+               if (!matched[i]) {
+                       struct jport_config *jp = &jport_config_store[i];
+                       if (jp->id[0]) {
+                               if (inputdevice_joyport_config(p, jp->configname, i, jp->mode, 0)) {
+                                       inputdevice_validate_jports(p, i, matched);
+                                       inputdevice_store_used_device(p, i);
+                                       matched[i] = true;
+                               }
+                       }
+               }
+       }
+       for (int i = 0; i < MAX_JPORTS; i++) {
+               struct jport_config *jp = &jport_config_store[i];
+               memset(jp, 0, sizeof(struct jport_config));
+       }
+}
+
+void inputdevice_config_load_start(struct uae_prefs *p)
+{
+       for (int i = 0; i < MAX_JPORTS; i++) {
+               struct jport_config *jp = &jport_config_store[i];
+               memset(jp, 0, sizeof(struct jport_config));
+       }
+}
+
 // for state recorder use only!
 
 uae_u8 *save_inputstate (int *len, uae_u8 *dstptr)
index c27f1ed096f590f505735c2432017563733a83c4..b9495c2b3adbb5a88597da8126c9c938f3bb1fef 100644 (file)
@@ -4,15 +4,15 @@ DEFEVENT(JOYPORT1_START,_T("[Joystick port 1]"), AM_INFO, 0,1,0)
 
 DEFEVENT(MOUSE1_FIRST, _T(""), AM_DUMMY, 0,0,0)
 
-DEFEVENT(MOUSE1_HORIZ,_T("Mouse1 Horizontal"),AM_MOUSE_AXIS|AM_JOY_AXIS,8,1,0)
-DEFEVENT(MOUSE1_VERT,_T("Mouse1 Vertical"),AM_MOUSE_AXIS|AM_JOY_AXIS,8,1,1)
-DEFEVENT(MOUSE1_HORIZ_INV,_T("Mouse1 Horizontal (inverted)"),AM_MOUSE_AXIS|AM_JOY_AXIS,8,1,0|IE_INVERT)
-DEFEVENT(MOUSE1_VERT_INV,_T("Mouse1 Vertical (inverted)"),AM_MOUSE_AXIS|AM_JOY_AXIS,8,1,1|IE_INVERT)
-DEFEVENT(MOUSE1_UP,_T("Mouse1 Up"),AM_KEY|AM_JOY_BUT|AM_MOUSE_BUT,32,1,DIR_UP)
-DEFEVENT(MOUSE1_DOWN,_T("Mouse1 Down"),AM_KEY|AM_JOY_BUT|AM_MOUSE_BUT,32,1,DIR_DOWN)
-DEFEVENT(MOUSE1_LEFT,_T("Mouse1 Left"),AM_KEY|AM_JOY_BUT|AM_MOUSE_BUT,64,1,DIR_LEFT)
-DEFEVENT(MOUSE1_RIGHT,_T("Mouse1 Right"),AM_KEY|AM_JOY_BUT|AM_MOUSE_BUT,64,1,DIR_RIGHT)
-DEFEVENT(MOUSE1_WHEEL,_T("Mouse1 Wheel"),AM_MOUSE_AXIS|AM_JOY_AXIS,8,1,2)
+DEFEVENT2(MOUSE1_HORIZ,_T("Mouse1 Horizontal"),_T("Horiz"),AM_MOUSE_AXIS|AM_JOY_AXIS,8,1,0,101)
+DEFEVENT2(MOUSE1_VERT,_T("Mouse1 Vertical"),_T("Vert"),AM_MOUSE_AXIS|AM_JOY_AXIS,8,1,1,102)
+DEFEVENT2(MOUSE1_HORIZ_INV,_T("Mouse1 Horizontal (inverted)"),_T("Horiz Inv"),AM_MOUSE_AXIS|AM_JOY_AXIS,8,1,0|IE_INVERT,103)
+DEFEVENT2(MOUSE1_VERT_INV,_T("Mouse1 Vertical (inverted)"),_T("Vert Inv"),AM_MOUSE_AXIS|AM_JOY_AXIS,8,1,1|IE_INVERT,104)
+DEFEVENT2(MOUSE1_UP,_T("Mouse1 Up"),_T("Up"),AM_KEY|AM_JOY_BUT|AM_MOUSE_BUT,32,1,DIR_UP,105)
+DEFEVENT2(MOUSE1_DOWN,_T("Mouse1 Down"),_T("Down"),AM_KEY|AM_JOY_BUT|AM_MOUSE_BUT,32,1,DIR_DOWN,106)
+DEFEVENT2(MOUSE1_LEFT,_T("Mouse1 Left"),_T("Left"),AM_KEY|AM_JOY_BUT|AM_MOUSE_BUT,64,1,DIR_LEFT,107)
+DEFEVENT2(MOUSE1_RIGHT,_T("Mouse1 Right"),_T("Right"),AM_KEY|AM_JOY_BUT|AM_MOUSE_BUT,64,1,DIR_RIGHT,108)
+DEFEVENT2(MOUSE1_WHEEL,_T("Mouse1 Wheel"),_T("Wheel"),AM_MOUSE_AXIS|AM_JOY_AXIS,8,1,2,109)
 
 DEFEVENT(MOUSE1_LAST, _T(""), AM_DUMMY, 0,0,0)
 
@@ -23,32 +23,32 @@ DEFEVENT(MOUSE_CDTV_DOWN,_T("CDTV Mouse Down"),AM_KEY|AM_JOY_BUT|AM_MOUSE_BUT,32
 DEFEVENT(MOUSE_CDTV_LEFT,_T("CDTV Mouse Left"),AM_KEY|AM_JOY_BUT|AM_MOUSE_BUT,64,1,DIR_LEFT|IE_CDTV)
 DEFEVENT(MOUSE_CDTV_RIGHT,_T("CDTV Mouse Right"),AM_KEY|AM_JOY_BUT|AM_MOUSE_BUT,64,1,DIR_RIGHT|IE_CDTV)
 
-DEFEVENT(JOY1_HORIZ,_T("Joy1 Horizontal"),AM_JOY_AXIS,0,1,DIR_LEFT|DIR_RIGHT)
-DEFEVENT(JOY1_VERT,_T("Joy1 Vertical"),AM_JOY_AXIS,0,1,DIR_UP|DIR_DOWN)
-DEFEVENT(JOY1_HORIZ_POT,_T("Joy1 Horizontal (Analog)"),AM_JOY_AXIS,128,1,1)
-DEFEVENT(JOY1_VERT_POT,_T("Joy1 Vertical (Analog)"),AM_JOY_AXIS,128,1,0)
-DEFEVENT(JOY1_HORIZ_POT_INV,_T("Joy1 Horizontal (Analog, inverted)"),AM_JOY_AXIS,128,1,1|IE_INVERT)
-DEFEVENT(JOY1_VERT_POT_INV,_T("Joy1 Vertical (Analog, inverted)"),AM_JOY_AXIS,128,1,0|IE_INVERT)
-
-DEFEVENT(JOY1_LEFT,_T("Joy1 Left"),AM_K,16,1,DIR_LEFT)
-DEFEVENT(JOY1_RIGHT,_T("Joy1 Right"),AM_K,16,1,DIR_RIGHT)
-DEFEVENT(JOY1_UP,_T("Joy1 Up"),AM_K,16,1,DIR_UP)
-DEFEVENT(JOY1_DOWN,_T("Joy1 Down"),AM_K,16,1,DIR_DOWN)
-DEFEVENT(JOY1_LEFT_UP,_T("Joy1 Left+Up"),AM_K,16,1,DIR_LEFT|DIR_UP)
-DEFEVENT(JOY1_LEFT_DOWN,_T("Joy1 Left+Down"),AM_K,16,1,DIR_LEFT|DIR_DOWN)
-DEFEVENT(JOY1_RIGHT_UP,_T("Joy1 Right+Up"),AM_K,16,1,DIR_RIGHT|DIR_UP)
-DEFEVENT(JOY1_RIGHT_DOWN,_T("Joy1 Right+Down"),AM_K,16,1,DIR_RIGHT|DIR_DOWN)
-
-DEFEVENT(JOY1_FIRE_BUTTON,_T("Joy1 Fire/Mouse1 Left Button"),AM_K,4,1,JOYBUTTON_1)
-DEFEVENT(JOY1_2ND_BUTTON,_T("Joy1 2nd Button/Mouse1 Right Button"),AM_K,4,1,JOYBUTTON_2)
-DEFEVENT(JOY1_3RD_BUTTON,_T("Joy1 3rd Button/Mouse1 Middle Button"),AM_K,4,1,JOYBUTTON_3)
-DEFEVENT(JOY1_CD32_PLAY,_T("Joy1 CD32 Play"),AM_K,4,1,JOYBUTTON_CD32_PLAY)
-DEFEVENT(JOY1_CD32_RWD,_T("Joy1 CD32 RWD"),AM_K,4,1,JOYBUTTON_CD32_RWD)
-DEFEVENT(JOY1_CD32_FFW,_T("Joy1 CD32 FFW"),AM_K,4,1,JOYBUTTON_CD32_FFW)
-DEFEVENT(JOY1_CD32_GREEN,_T("Joy1 CD32 Green"),AM_K,4,1,JOYBUTTON_CD32_GREEN)
-DEFEVENT(JOY1_CD32_YELLOW,_T("Joy1 CD32 Yellow"),AM_K,4,1,JOYBUTTON_CD32_YELLOW)
-DEFEVENT(JOY1_CD32_RED,_T("Joy1 CD32 Red"),AM_K,4,1,JOYBUTTON_CD32_RED)
-DEFEVENT(JOY1_CD32_BLUE,_T("Joy1 CD32 Blue"),AM_K,4,1,JOYBUTTON_CD32_BLUE)
+DEFEVENT2(JOY1_HORIZ,_T("Joy1 Horizontal"),_T("Horiz"),AM_JOY_AXIS,0,1,DIR_LEFT|DIR_RIGHT,1)
+DEFEVENT2(JOY1_VERT,_T("Joy1 Vertical"),_T("Vert"),AM_JOY_AXIS,0,1,DIR_UP|DIR_DOWN,2)
+DEFEVENT2(JOY1_HORIZ_POT,_T("Joy1 Horizontal (Analog)"),_T("Horiz Analog"),AM_JOY_AXIS,128,1,1,3)
+DEFEVENT2(JOY1_VERT_POT,_T("Joy1 Vertical (Analog)"),_T("Vert Analog"),AM_JOY_AXIS,128,1,0,4)
+DEFEVENT2(JOY1_HORIZ_POT_INV,_T("Joy1 Horizontal (Analog, inverted)"),_T("Horiz Analog Inv"),AM_JOY_AXIS,128,1,1|IE_INVERT,5)
+DEFEVENT2(JOY1_VERT_POT_INV,_T("Joy1 Vertical (Analog, inverted)"),_T("Vert Analog Inv"),AM_JOY_AXIS,128,1,0|IE_INVERT,6)
+
+DEFEVENT2(JOY1_LEFT,_T("Joy1 Left"),_T("Left"),AM_K,16,1,DIR_LEFT,7)
+DEFEVENT2(JOY1_RIGHT,_T("Joy1 Right"),_T("Right"),AM_K,16,1,DIR_RIGHT,8)
+DEFEVENT2(JOY1_UP,_T("Joy1 Up"),_T("UP"),AM_K,16,1,DIR_UP,9)
+DEFEVENT2(JOY1_DOWN,_T("Joy1 Down"),_T("Down"),AM_K,16,1,DIR_DOWN,10)
+DEFEVENT2(JOY1_LEFT_UP,_T("Joy1 Left+Up"),_T("Left+Up"),AM_K,16,1,DIR_LEFT|DIR_UP,11)
+DEFEVENT2(JOY1_LEFT_DOWN,_T("Joy1 Left+Down"),_T("Left+Down"),AM_K,16,1,DIR_LEFT|DIR_DOWN,12)
+DEFEVENT2(JOY1_RIGHT_UP,_T("Joy1 Right+Up"),_T("Right+Up"),AM_K,16,1,DIR_RIGHT|DIR_UP,13)
+DEFEVENT2(JOY1_RIGHT_DOWN,_T("Joy1 Right+Down"),_T("Right+Down"),AM_K,16,1,DIR_RIGHT|DIR_DOWN,14)
+
+DEFEVENT2(JOY1_FIRE_BUTTON,_T("Joy1 Fire/Mouse1 Left Button"),_T("B1"),AM_K,4,1,JOYBUTTON_1,15)
+DEFEVENT2(JOY1_2ND_BUTTON,_T("Joy1 2nd Button/Mouse1 Right Button"),_T("B2"),AM_K,4,1,JOYBUTTON_2,16)
+DEFEVENT2(JOY1_3RD_BUTTON,_T("Joy1 3rd Button/Mouse1 Middle Button"),_T("B3"),AM_K,4,1,JOYBUTTON_3,17)
+DEFEVENT2(JOY1_CD32_PLAY,_T("Joy1 CD32 Play"),_T("CD32 PLAY"),AM_K,4,1,JOYBUTTON_CD32_PLAY,18)
+DEFEVENT2(JOY1_CD32_RWD,_T("Joy1 CD32 RWD"),_T("CD32 RWD"),AM_K,4,1,JOYBUTTON_CD32_RWD,19)
+DEFEVENT2(JOY1_CD32_FFW,_T("Joy1 CD32 FFW"),_T("CD32 FFW"),AM_K,4,1,JOYBUTTON_CD32_FFW,20)
+DEFEVENT2(JOY1_CD32_GREEN,_T("Joy1 CD32 Green"),_T("CD32 G"),AM_K,4,1,JOYBUTTON_CD32_GREEN,21)
+DEFEVENT2(JOY1_CD32_YELLOW,_T("Joy1 CD32 Yellow"),_T("CD32 Y"),AM_K,4,1,JOYBUTTON_CD32_YELLOW,22)
+DEFEVENT2(JOY1_CD32_RED,_T("Joy1 CD32 Red"),_T("CD32 R"),AM_K,4,1,JOYBUTTON_CD32_RED,23)
+DEFEVENT2(JOY1_CD32_BLUE,_T("Joy1 CD32 Blue"),_T("CD32 B"),AM_K,4,1,JOYBUTTON_CD32_BLUE,24)
 
 /* joystick/mouse port 2 */
 
@@ -56,43 +56,43 @@ DEFEVENT(JOYPORT2_START,_T("[Joystick port 2]"), AM_INFO, 0,2,0)
 
 DEFEVENT(MOUSE2_FIRST, _T(""), AM_DUMMY, 0,0,0)
 
-DEFEVENT(MOUSE2_HORIZ,_T("Mouse2 Horizontal"),AM_MOUSE_AXIS|AM_JOY_AXIS,8,2,0)
-DEFEVENT(MOUSE2_VERT,_T("Mouse2 Vertical"),AM_MOUSE_AXIS|AM_JOY_AXIS,8,2,1)
-DEFEVENT(MOUSE2_HORIZ_INV,_T("Mouse2 Horizontal (inverted)"),AM_MOUSE_AXIS|AM_JOY_AXIS,8,2,0|IE_INVERT)
-DEFEVENT(MOUSE2_VERT_INV,_T("Mouse2 Vertical (inverted)"),AM_MOUSE_AXIS|AM_JOY_AXIS,8,2,1|IE_INVERT)
-DEFEVENT(MOUSE2_UP,_T("Mouse2 Up"),AM_KEY|AM_JOY_BUT|AM_MOUSE_BUT,32,2,DIR_UP)
-DEFEVENT(MOUSE2_DOWN,_T("Mouse2 Down"),AM_KEY|AM_JOY_BUT|AM_MOUSE_BUT,32,2,DIR_DOWN)
-DEFEVENT(MOUSE2_LEFT,_T("Mouse2 Left"),AM_KEY|AM_JOY_BUT|AM_MOUSE_BUT,64,2,DIR_LEFT)
-DEFEVENT(MOUSE2_RIGHT,_T("Mouse2 Right"),AM_KEY|AM_JOY_BUT|AM_MOUSE_BUT,64,2,DIR_RIGHT)
+DEFEVENT2(MOUSE2_HORIZ,_T("Mouse2 Horizontal"),_T("Horiz"),AM_MOUSE_AXIS|AM_JOY_AXIS,8,2,0,101)
+DEFEVENT2(MOUSE2_VERT,_T("Mouse2 Vertical"),_T("Vert"),AM_MOUSE_AXIS|AM_JOY_AXIS,8,2,1,102)
+DEFEVENT2(MOUSE2_HORIZ_INV,_T("Mouse2 Horizontal (inverted)"),_T("Horiz Inv"),AM_MOUSE_AXIS|AM_JOY_AXIS,8,2,0|IE_INVERT,103)
+DEFEVENT2(MOUSE2_VERT_INV,_T("Mouse2 Vertical (inverted)"),_T("Vert Inv"),AM_MOUSE_AXIS|AM_JOY_AXIS,8,2,1|IE_INVERT,104)
+DEFEVENT2(MOUSE2_UP,_T("Mouse2 Up"),_T("UP"),AM_KEY|AM_JOY_BUT|AM_MOUSE_BUT,32,2,DIR_UP,105)
+DEFEVENT2(MOUSE2_DOWN,_T("Mouse2 Down"),_T("Down"),AM_KEY|AM_JOY_BUT|AM_MOUSE_BUT,32,2,DIR_DOWN,106)
+DEFEVENT2(MOUSE2_LEFT,_T("Mouse2 Left"),_T("Left"),AM_KEY|AM_JOY_BUT|AM_MOUSE_BUT,64,2,DIR_LEFT,107)
+DEFEVENT2(MOUSE2_RIGHT,_T("Mouse2 Right"),_T("Right"),AM_KEY|AM_JOY_BUT|AM_MOUSE_BUT,64,2,DIR_RIGHT,108)
 
 DEFEVENT(MOUSE2_LAST, _T(""), AM_DUMMY, 0,0,0)
 
-DEFEVENT(JOY2_HORIZ,_T("Joy2 Horizontal"),AM_JOY_AXIS,0,2,DIR_LEFT|DIR_RIGHT)
-DEFEVENT(JOY2_VERT,_T("Joy2 Vertical"),AM_JOY_AXIS,0,2,DIR_UP|DIR_DOWN)
-DEFEVENT(JOY2_HORIZ_POT,_T("Joy2 Horizontal (Analog)"),AM_JOY_AXIS,128,2,1)
-DEFEVENT(JOY2_VERT_POT,_T("Joy2 Vertical (Analog)"),AM_JOY_AXIS,128,2,0)
-DEFEVENT(JOY2_HORIZ_POT_INV,_T("Joy2 Horizontal (Analog, inverted)"),AM_JOY_AXIS,128,2,1|IE_INVERT)
-DEFEVENT(JOY2_VERT_POT_INV,_T("Joy2 Vertical (Analog, inverted)"),AM_JOY_AXIS,128,2,0|IE_INVERT)
-
-DEFEVENT(JOY2_LEFT,_T("Joy2 Left"),AM_K,16,2,DIR_LEFT)
-DEFEVENT(JOY2_RIGHT,_T("Joy2 Right"),AM_K,16,2,DIR_RIGHT)
-DEFEVENT(JOY2_UP,_T("Joy2 Up"),AM_K,16,2,DIR_UP)
-DEFEVENT(JOY2_DOWN,_T("Joy2 Down"),AM_K,16,2,DIR_DOWN)
-DEFEVENT(JOY2_LEFT_UP,_T("Joy2 Left+Up"),AM_K,16,2,DIR_LEFT|DIR_UP)
-DEFEVENT(JOY2_LEFT_DOWN,_T("Joy2 Left+Down"),AM_K,16,2,DIR_LEFT|DIR_DOWN)
-DEFEVENT(JOY2_RIGHT_UP,_T("Joy2 Right+Up"),AM_K,16,2,DIR_RIGHT|DIR_UP)
-DEFEVENT(JOY2_RIGHT_DOWN,_T("Joy2 Right+Down"),AM_K,16,2,DIR_RIGHT|DIR_DOWN)
-
-DEFEVENT(JOY2_FIRE_BUTTON,_T("Joy2 Fire/Mouse2 Left Button"),AM_K,4,2,JOYBUTTON_1)
-DEFEVENT(JOY2_2ND_BUTTON,_T("Joy2 2nd Button/Mouse2 Right Button"),AM_K,4,2,JOYBUTTON_2)
-DEFEVENT(JOY2_3RD_BUTTON,_T("Joy2 3rd Button/Mouse2 Middle Button"),AM_K,4,2,JOYBUTTON_3)
-DEFEVENT(JOY2_CD32_PLAY,_T("Joy2 CD32 Play"),AM_K,4,2,JOYBUTTON_CD32_PLAY)
-DEFEVENT(JOY2_CD32_RWD,_T("Joy2 CD32 RWD"),AM_K,4,2,JOYBUTTON_CD32_RWD)
-DEFEVENT(JOY2_CD32_FFW,_T("Joy2 CD32 FFW"),AM_K,4,2,JOYBUTTON_CD32_FFW)
-DEFEVENT(JOY2_CD32_GREEN,_T("Joy2 CD32 Green"),AM_K,4,2,JOYBUTTON_CD32_GREEN)
-DEFEVENT(JOY2_CD32_YELLOW,_T("Joy2 CD32 Yellow"),AM_K,4,2,JOYBUTTON_CD32_YELLOW)
-DEFEVENT(JOY2_CD32_RED,_T("Joy2 CD32 Red"),AM_K,4,2,JOYBUTTON_CD32_RED)
-DEFEVENT(JOY2_CD32_BLUE,_T("Joy2 CD32 Blue"),AM_K,4,2,JOYBUTTON_CD32_BLUE)
+DEFEVENT2(JOY2_HORIZ,_T("Joy2 Horizontal"),_T("Horiz"),AM_JOY_AXIS,0,2,DIR_LEFT|DIR_RIGHT,1)
+DEFEVENT2(JOY2_VERT,_T("Joy2 Vertical"),_T("Vert"),AM_JOY_AXIS,0,2,DIR_UP|DIR_DOWN,2)
+DEFEVENT2(JOY2_HORIZ_POT,_T("Joy2 Horizontal (Analog)"),_T("Horiz Analog"),AM_JOY_AXIS,128,2,1,3)
+DEFEVENT2(JOY2_VERT_POT,_T("Joy2 Vertical (Analog)"),_T("Vert Analog"),AM_JOY_AXIS,128,2,0,4)
+DEFEVENT2(JOY2_HORIZ_POT_INV,_T("Joy2 Horizontal (Analog, inverted)"),_T("Horiz Analog Inv"),AM_JOY_AXIS,128,2,1|IE_INVERT,5)
+DEFEVENT2(JOY2_VERT_POT_INV,_T("Joy2 Vertical (Analog, inverted)"),_T("Vert Analog Inv"),AM_JOY_AXIS,128,2,0|IE_INVERT,6)
+
+DEFEVENT2(JOY2_LEFT,_T("Joy2 Left"),_T("Left"),AM_K,16,2,DIR_LEFT,7)
+DEFEVENT2(JOY2_RIGHT,_T("Joy2 Right"),_T("Right"),AM_K,16,2,DIR_RIGHT,8)
+DEFEVENT2(JOY2_UP,_T("Joy2 Up"),_T("Up"),AM_K,16,2,DIR_UP,9)
+DEFEVENT2(JOY2_DOWN,_T("Joy2 Down"),_T("Down"),AM_K,16,2,DIR_DOWN,10)
+DEFEVENT2(JOY2_LEFT_UP,_T("Joy2 Left+Up"),_T("Left+Up"),AM_K,16,2,DIR_LEFT|DIR_UP,11)
+DEFEVENT2(JOY2_LEFT_DOWN,_T("Joy2 Left+Down"),_T("Left+Down"),AM_K,16,2,DIR_LEFT|DIR_DOWN,12)
+DEFEVENT2(JOY2_RIGHT_UP,_T("Joy2 Right+Up"),_T("Right+Up"),AM_K,16,2,DIR_RIGHT|DIR_UP,13)
+DEFEVENT2(JOY2_RIGHT_DOWN,_T("Joy2 Right+Down"),_T("J Right+Down"),AM_K,16,2,DIR_RIGHT|DIR_DOWN,14)
+
+DEFEVENT2(JOY2_FIRE_BUTTON,_T("Joy2 Fire/Mouse2 Left Button"),_T("B1"),AM_K,4,2,JOYBUTTON_1,15)
+DEFEVENT2(JOY2_2ND_BUTTON,_T("Joy2 2nd Button/Mouse2 Right Button"),_T("B2"),AM_K,4,2,JOYBUTTON_2,16)
+DEFEVENT2(JOY2_3RD_BUTTON,_T("Joy2 3rd Button/Mouse2 Middle Button"),_T("B3"),AM_K,4,2,JOYBUTTON_3,17)
+DEFEVENT2(JOY2_CD32_PLAY,_T("Joy2 CD32 Play"),_T("CD32 PLAY"),AM_K,4,2,JOYBUTTON_CD32_PLAY,18)
+DEFEVENT2(JOY2_CD32_RWD,_T("Joy2 CD32 RWD"),_T("CD32 RWD"),AM_K,4,2,JOYBUTTON_CD32_RWD,19)
+DEFEVENT2(JOY2_CD32_FFW,_T("Joy2 CD32 FFW"),_T("CD32 FFW"),AM_K,4,2,JOYBUTTON_CD32_FFW,20)
+DEFEVENT2(JOY2_CD32_GREEN,_T("Joy2 CD32 Green"),_T("CD32 G"),AM_K,4,2,JOYBUTTON_CD32_GREEN,21)
+DEFEVENT2(JOY2_CD32_YELLOW,_T("Joy2 CD32 Yellow"),_T("CD32 Y"),AM_K,4,2,JOYBUTTON_CD32_YELLOW,22)
+DEFEVENT2(JOY2_CD32_RED,_T("Joy2 CD32 Red"),_T("CD32 R"),AM_K,4,2,JOYBUTTON_CD32_RED,23)
+DEFEVENT2(JOY2_CD32_BLUE,_T("Joy2 CD32 Blue"),_T("CD32 B"),AM_K,4,2,JOYBUTTON_CD32_BLUE,24)
 
 DEFEVENT(LIGHTPEN_FIRST, _T(""), AM_DUMMY, 0,0,0)
 
@@ -109,33 +109,33 @@ DEFEVENT(LIGHTPEN_LAST, _T(""), AM_DUMMY, 0,0,0)
 
 DEFEVENT(PAR_JOY1_START, _T("[Parallel port joystick adapter]"), AM_INFO, 0,3,0)
 
-DEFEVENT(PAR_JOY1_HORIZ,_T("Parallel Joy1 Horizontal"),AM_JOY_AXIS,0,3,DIR_LEFT|DIR_RIGHT)
-DEFEVENT(PAR_JOY1_VERT,_T("Parallel Joy1 Vertical"),AM_JOY_AXIS,0,3,DIR_UP|DIR_DOWN)
-DEFEVENT(PAR_JOY1_LEFT,_T("Parallel Joy1 Left"),AM_K,16,3,DIR_LEFT)
-DEFEVENT(PAR_JOY1_RIGHT,_T("Parallel Joy1 Right"),AM_K,16,3,DIR_RIGHT)
-DEFEVENT(PAR_JOY1_UP,_T("Parallel Joy1 Up"),AM_K,16,3,DIR_UP)
-DEFEVENT(PAR_JOY1_DOWN,_T("Parallel Joy1 Down"),AM_K,16,3,DIR_DOWN)
-DEFEVENT(PAR_JOY1_LEFT_UP,_T("Parallel Joy1 Left+Up"),AM_K,16,3,DIR_LEFT|DIR_UP)
-DEFEVENT(PAR_JOY1_LEFT_DOWN,_T("Parallel Joy1 Left+Down"),AM_K,16,3,DIR_LEFT|DIR_DOWN)
-DEFEVENT(PAR_JOY1_RIGHT_UP,_T("Parallel Joy1 Right+Up"),AM_K,16,3,DIR_RIGHT|DIR_UP)
-DEFEVENT(PAR_JOY1_RIGHT_DOWN,_T("Parallel Joy1 Right+Down"),AM_K,16,3,DIR_RIGHT|DIR_DOWN)
-DEFEVENT(PAR_JOY1_FIRE_BUTTON,_T("Parallel Joy1 Fire Button"),AM_K,4,3,JOYBUTTON_1)
-DEFEVENT(PAR_JOY1_2ND_BUTTON,_T("Parallel Joy1 Spare/2nd Button"),AM_K,4,3,JOYBUTTON_2)
+DEFEVENT2(PAR_JOY1_HORIZ,_T("Parallel Joy1 Horizontal"),_T("Horiz"),AM_JOY_AXIS,0,3,DIR_LEFT|DIR_RIGHT,1)
+DEFEVENT2(PAR_JOY1_VERT,_T("Parallel Joy1 Vertical"),_T("Vert"),AM_JOY_AXIS,0,3,DIR_UP|DIR_DOWN,2)
+DEFEVENT2(PAR_JOY1_LEFT,_T("Parallel Joy1 Left"),_T("Left"),AM_K,16,3,DIR_LEFT,7)
+DEFEVENT2(PAR_JOY1_RIGHT,_T("Parallel Joy1 Right"),_T("Right"),AM_K,16,3,DIR_RIGHT,8)
+DEFEVENT2(PAR_JOY1_UP,_T("Parallel Joy1 Up"),_T("Up"),AM_K,16,3,DIR_UP,9)
+DEFEVENT2(PAR_JOY1_DOWN,_T("Parallel Joy1 Down"),_T("Down"),AM_K,16,3,DIR_DOWN,10)
+DEFEVENT2(PAR_JOY1_LEFT_UP,_T("Parallel Joy1 Left+Up"),_T("Left+Up"),AM_K,16,3,DIR_LEFT|DIR_UP,11)
+DEFEVENT2(PAR_JOY1_LEFT_DOWN,_T("Parallel Joy1 Left+Down"),_T("Left+Down"),AM_K,16,3,DIR_LEFT|DIR_DOWN,12)
+DEFEVENT2(PAR_JOY1_RIGHT_UP,_T("Parallel Joy1 Right+Up"),_T("Right+Up"),AM_K,16,3,DIR_RIGHT|DIR_UP,13)
+DEFEVENT2(PAR_JOY1_RIGHT_DOWN,_T("Parallel Joy1 Right+Down"),_T("Right+Down"),AM_K,16,3,DIR_RIGHT|DIR_DOWN,14)
+DEFEVENT2(PAR_JOY1_FIRE_BUTTON,_T("Parallel Joy1 Fire Button"),_T("B1"),AM_K,4,3,JOYBUTTON_1,15)
+DEFEVENT2(PAR_JOY1_2ND_BUTTON,_T("Parallel Joy1 Spare/2nd Button"),_T("B2"),AM_K,4,3,JOYBUTTON_2,16)
 
 DEFEVENT(PAR_JOY2_START, _T(""), AM_DUMMY, 0,4,0)
 
-DEFEVENT(PAR_JOY2_HORIZ,_T("Parallel Joy2 Horizontal"),AM_JOY_AXIS,0,4,DIR_LEFT|DIR_RIGHT)
-DEFEVENT(PAR_JOY2_VERT,_T("Parallel Joy2 Vertical"),AM_JOY_AXIS,0,4,DIR_UP|DIR_DOWN)
-DEFEVENT(PAR_JOY2_LEFT,_T("Parallel Joy2 Left"),AM_K,16,4,DIR_LEFT)
-DEFEVENT(PAR_JOY2_RIGHT,_T("Parallel Joy2 Right"),AM_K,16,4,DIR_RIGHT)
-DEFEVENT(PAR_JOY2_UP,_T("Parallel Joy2 Up"),AM_K,16,4,DIR_UP)
-DEFEVENT(PAR_JOY2_DOWN,_T("Parallel Joy2 Down"),AM_K,16,4,DIR_DOWN)
-DEFEVENT(PAR_JOY2_LEFT_UP,_T("Parallel Joy2 Left+Up"),AM_K,16,4,DIR_LEFT|DIR_UP)
-DEFEVENT(PAR_JOY2_LEFT_DOWN,_T("Parallel Joy2 Left+Down"),AM_K,16,4,DIR_LEFT|DIR_DOWN)
-DEFEVENT(PAR_JOY2_RIGHT_UP,_T("Parallel Joy2 Right+Up"),AM_K,16,4,DIR_RIGHT|DIR_UP)
-DEFEVENT(PAR_JOY2_RIGHT_DOWN,_T("Parallel Joy2 Right+Down"),AM_K,16,4,DIR_RIGHT|DIR_DOWN)
-DEFEVENT(PAR_JOY2_FIRE_BUTTON,_T("Parallel Joy2 Fire Button"),AM_K,4,4,JOYBUTTON_1)
-DEFEVENT(PAR_JOY2_2ND_BUTTON,_T("Parallel Joy2 Spare/2nd Button"),AM_K,4,4,JOYBUTTON_2)
+DEFEVENT2(PAR_JOY2_HORIZ,_T("Parallel Joy2 Horizontal"),_T("Horiz"),AM_JOY_AXIS,0,4,DIR_LEFT|DIR_RIGHT,1)
+DEFEVENT2(PAR_JOY2_VERT,_T("Parallel Joy2 Vertical"),_T("Vert"),AM_JOY_AXIS,0,4,DIR_UP|DIR_DOWN,2)
+DEFEVENT2(PAR_JOY2_LEFT,_T("Parallel Joy2 Left"),_T("Left"),AM_K,16,4,DIR_LEFT,7)
+DEFEVENT2(PAR_JOY2_RIGHT,_T("Parallel Joy2 Right"),_T("Right"),AM_K,16,4,DIR_RIGHT,8)
+DEFEVENT2(PAR_JOY2_UP,_T("Parallel Joy2 Up"),_T("Up"),AM_K,16,4,DIR_UP,9)
+DEFEVENT2(PAR_JOY2_DOWN,_T("Parallel Joy2 Down"),_T("Down"),AM_K,16,4,DIR_DOWN,10)
+DEFEVENT2(PAR_JOY2_LEFT_UP,_T("Parallel Joy2 Left+Up"),_T("Left+Up"),AM_K,16,4,DIR_LEFT|DIR_UP,11)
+DEFEVENT2(PAR_JOY2_LEFT_DOWN,_T("Parallel Joy2 Left+Down"),_T("Left+Down"),AM_K,16,4,DIR_LEFT|DIR_DOWN,12)
+DEFEVENT2(PAR_JOY2_RIGHT_UP,_T("Parallel Joy2 Right+Up"),_T("Right+Up"),AM_K,16,4,DIR_RIGHT|DIR_UP,13)
+DEFEVENT2(PAR_JOY2_RIGHT_DOWN,_T("Parallel Joy2 Right+Down"),_T("Right+Down"),AM_K,16,4,DIR_RIGHT|DIR_DOWN,14)
+DEFEVENT2(PAR_JOY2_FIRE_BUTTON,_T("Parallel Joy2 Fire Button"),_T("B1"),AM_K,4,4,JOYBUTTON_1,15)
+DEFEVENT2(PAR_JOY2_2ND_BUTTON,_T("Parallel Joy2 Spare/2nd Button"),_T("B2"),AM_K,4,4,JOYBUTTON_2,16)
 
 DEFEVENT(PAR_JOY_END, _T(""), AM_DUMMY, 0,0,0)
 
@@ -368,6 +368,7 @@ DEFEVENT(SPC_DECREASE_REFRESHRATE,_T("Decrease emulation speed"),AM_K,0,0,AKS_DE
 DEFEVENT(SPC_INCREASE_REFRESHRATE,_T("Increase emulation speed"),AM_K,0,0,AKS_INCREASEREFRESHRATE)
 DEFEVENT(SPC_SWITCHINTERPOL,_T("Switch between audio interpolation methods"),AM_KT,0,0,AKS_SWITCHINTERPOL)
 DEFEVENT(SPC_TOGGLERTG,_T("Toggle chipset/RTG screen"),AM_KT,0,0,AKS_TOGGLERTG)
+DEFEVENT(SPC_SWAPJOYPORTS,_T("Swap joystick ports"),AM_KT,0,0,AKS_SWAPJOYPORTS)
 
 DEFEVENT(SPC_DISKSWAPPER_NEXT,_T("Next slot in Disk Swapper"),AM_K,0,0,AKS_DISKSWAPPER_NEXT)
 DEFEVENT(SPC_DISKSWAPPER_PREV,_T("Previous slot in Disk Swapper"),AM_K,0,0,AKS_DISKSWAPPER_PREV)
index 003b6f557f6111ffb610964a6b80f9eff3cad4f8..a54436ea13c8b67326bfab733289451ffd24d03f 100644 (file)
@@ -17,7 +17,8 @@ bool check_prefs_changed_comp (bool checkonly)
                currprefs.comp_hardflush != changed_prefs.comp_hardflush ||
                currprefs.comp_constjump != changed_prefs.comp_constjump ||
                currprefs.compfpu != changed_prefs.compfpu ||
-               currprefs.fpu_strict != changed_prefs.fpu_strict)
+               currprefs.fpu_strict != changed_prefs.fpu_strict ||
+               currprefs.cachesize != changed_prefs.cachesize)
                changed = 1;
 
        if (checkonly)
index 51508613780df09c44e53da757a3aed800d5169f..03312d02c2c85d99c844907ec82caee5e9558cb3 100644 (file)
@@ -2926,7 +2926,7 @@ void freescratch(void)
 {
        int i;
        for (i=0;i<N_REGS;i++)
-               if (live.nat[i].locked && i!=4) {
+               if (live.nat[i].locked && i!=4 && i!= 12) {
                        jit_log("Warning! %d is locked",i);
        }
 
@@ -3608,7 +3608,7 @@ static inline int block_check_checksum(blockinfo* bi)
                bi->handler_to_use=bi->handler;
                set_dhtu(bi,bi->direct_handler);
                bi->status=BI_CHECKING;
-               isgood=called_check_checksum(bi);
+               isgood=called_check_checksum(bi) != 0;
        }
        if (isgood) {
                jit_log2("reactivate %p/%p (%x %x/%x %x)",bi,bi->pc_p, c1,c2,bi->c1,bi->c2);
@@ -4331,7 +4331,7 @@ static void compile_block(cpu_history* pc_hist, int blocklen)
                int was_comp=0;
                uae_u8 liveflags[MAXRUN+1];
 #if USE_CHECKSUM_INFO
-               bool trace_in_rom = isinrom((uintptr)pc_hist[0].location);
+               bool trace_in_rom = isinrom((uintptr)pc_hist[0].location) != 0;
                uintptr max_pcp=(uintptr)pc_hist[blocklen - 1].location;
                uintptr min_pcp=max_pcp;
 #else
index 8cf96f82e948b0f54e1c211fac0bb196324386c9..c36cdf78bdbb7c24f4630f14f3230d45fed75731 100644 (file)
@@ -424,6 +424,9 @@ static int handle_access(uintptr_t fault_addr, CONTEXT_T context)
                (addr >= 0x50000000)) {
                        write_log (_T("JIT: Suspicious address 0x%x in SEGV handler.\n"), addr);
        }
+       addrbank *ab = &get_mem_bank(addr);
+       if (ab)
+               write_log(_T("JIT: Address bank: %s, address %08x\n"), ab->name ? ab->name : _T("NONE"), addr);
 #endif
 
        uae_u8* original_target = target;
index 6bd156447fe9d4e80bd9daa0084e7a0c68be1e8a..6a07db5610fe1a492e92129e509aded2ed467c94 100644 (file)
--- a/main.cpp
+++ b/main.cpp
@@ -346,11 +346,15 @@ void fixup_prefs (struct uae_prefs *p)
                        p->custom_memory_sizes[1] = p->cpuboardmem1_size / 2;
                        p->custom_memory_addrs[0] = 0x18000000 - p->custom_memory_sizes[0];
                        p->custom_memory_addrs[1] = 0x18000000;
+                       p->custom_memory_mask[0] = 0x10000000;
+                       p->custom_memory_mask[1] = 0x18000000;
                } else {
                        p->custom_memory_sizes[0] = p->cpuboardmem1_size;
                        p->custom_memory_sizes[1] = 0;
                        p->custom_memory_addrs[0] = 0x18000000 - p->custom_memory_sizes[0];
                        p->custom_memory_addrs[1] = 0;
+                       p->custom_memory_mask[0] = 0x10000000;
+                       p->custom_memory_mask[1] = 0;
                }
        }
 
@@ -712,6 +716,7 @@ void fixup_prefs (struct uae_prefs *p)
 
        built_in_chipset_prefs (p);
        blkdev_fix_prefs (p);
+       inputdevice_fix_prefs(p);
        target_fixup_options (p);
 }
 
index 132c03e16d21fc3bc66fcff27995b8aafe9da200..dd8698258ee9948acf90c81392ee92e1d1db94b5 100644 (file)
@@ -767,14 +767,18 @@ static void a2410_rethink(void)
                INTREQ_0(0x8000 | 0x0008);
 }
 
-void tms_vsync_handler(void)
+bool tms_vsync_handler(void)
 {
+       bool flushed = false;
        if (!a2410_enabled)
                tms_vsync_handler2(false);
 
-       if (a2410_surface)
+       if (a2410_surface) {
                gfx_unlock_picasso(false);
+               flushed = true;
+       }
        a2410_surface = NULL;
+       return flushed;
 }
 
 static void tms_hsync_handler2(void)
index cdf317f44b12fbb0b658531563c6ef287d9d10c7..2417963ad9b994bd7ffad642ec86e5f7ae662c8a 100644 (file)
@@ -539,11 +539,6 @@ void REGPARAM2 chipmem_lput (uaecptr addr, uae_u32 l)
        do_put_mem_long (m, l);
 }
 
-#if 0
-static int tables[256];
-static int told, toldv;
-#endif
-
 void REGPARAM2 chipmem_wput (uaecptr addr, uae_u32 w)
 {
        uae_u16 *m;
@@ -551,17 +546,6 @@ void REGPARAM2 chipmem_wput (uaecptr addr, uae_u32 w)
        addr &= chipmem_bank.mask;
        m = (uae_u16 *)(chipmem_bank.baseaddr + addr);
        do_put_mem_word (m, w);
-#if 0
-       if (addr == 4) {
-               write_log (_T("*"));
-#if 0
-               if (told)
-                       tables[toldv] += hsync_counter - told;
-               told = hsync_counter;
-               toldv = w;
-#endif
-       }
-#endif
 }
 
 void REGPARAM2 chipmem_bput (uaecptr addr, uae_u32 b)
@@ -1026,7 +1010,7 @@ addrbank chipmem_bank = {
        chipmem_lput, chipmem_wput, chipmem_bput,
        chipmem_xlate, chipmem_check, NULL, _T("chip"), _T("Chip memory"),
        chipmem_lget, chipmem_wget,
-       ABFLAG_RAM | ABFLAG_THREADSAFE, 0, 0
+       ABFLAG_RAM | ABFLAG_THREADSAFE | ABFLAG_CHIPRAM, 0, 0
 };
 
 addrbank chipmem_dummy_bank = {
@@ -1034,7 +1018,7 @@ addrbank chipmem_dummy_bank = {
        chipmem_dummy_lput, chipmem_dummy_wput, chipmem_dummy_bput,
        default_xlate, dummy_check, NULL, NULL, _T("Dummy Chip memory"),
        dummy_lgeti, dummy_wgeti,
-       ABFLAG_IO, S_READ, S_WRITE
+       ABFLAG_IO | ABFLAG_CHIPRAM, S_READ, S_WRITE
 };
 
 
@@ -1044,7 +1028,7 @@ addrbank chipmem_bank_ce2 = {
        chipmem_lput_ce2, chipmem_wput_ce2, chipmem_bput_ce2,
        chipmem_xlate, chipmem_check, NULL, NULL, _T("Chip memory (68020 'ce')"),
        chipmem_lget_ce2, chipmem_wget_ce2,
-       ABFLAG_RAM, S_READ, S_WRITE
+       ABFLAG_RAM | ABFLAG_CHIPRAM, S_READ, S_WRITE
 };
 #endif
 
@@ -1426,12 +1410,26 @@ static bool load_kickstart_replacement (void)
 
        zfile_fclose (f);
 
-       changed_prefs.custom_memory_addrs[0] = currprefs.custom_memory_addrs[0] = 0xa80000;
-       changed_prefs.custom_memory_sizes[0] = currprefs.custom_memory_sizes[0] = 512 * 1024;
-       changed_prefs.custom_memory_addrs[1] = currprefs.custom_memory_addrs[1] = 0xb00000;
-       changed_prefs.custom_memory_sizes[1] = currprefs.custom_memory_sizes[1] = 512 * 1024;
-
        seriallog = -1;
+
+       // 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.mbresmem_high_size == 0 &&
+               currprefs.mbresmem_low_size == 0 &&
+               currprefs.cpuboardmem1_size == 0) {
+
+               changed_prefs.custom_memory_addrs[0] = currprefs.custom_memory_addrs[0] = 0xa80000;
+               changed_prefs.custom_memory_sizes[0] = currprefs.custom_memory_sizes[0] = 512 * 1024;
+               changed_prefs.custom_memory_mask[0] = currprefs.custom_memory_mask[0] = 0;
+               changed_prefs.custom_memory_addrs[1] = currprefs.custom_memory_addrs[1] = 0xb00000;
+               changed_prefs.custom_memory_sizes[1] = currprefs.custom_memory_sizes[1] = 512 * 1024;
+               changed_prefs.custom_memory_mask[1] = currprefs.custom_memory_mask[1] = 0;
+
+       }
+
        return true;
 }
 
@@ -2027,7 +2025,7 @@ static void fill_ce_banks (void)
        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);
 
-       if (&get_mem_bank (0) == &chipmem_bank) {
+       if (get_mem_bank (0).flags & ABFLAG_CHIPRAM) {
                for (i = 0; i < (0x200000 >> 16); i++) {
                        ce_banktype[i] = (currprefs.cs_mbdmac || (currprefs.chipset_mask & CSMASK_AGA)) ? CE_MEMBANK_CHIP32 : CE_MEMBANK_CHIP16;
                }
@@ -2044,7 +2042,7 @@ static void fill_ce_banks (void)
                addrbank *b;
                ce_banktype[i] = CE_MEMBANK_CIA;
                b = &get_mem_bank (i << 16);
-               if (b != &cia_bank) {
+               if (!(b->flags & ABFLAG_CIA)) {
                        ce_banktype[i] = CE_MEMBANK_FAST32;
                        ce_cachable[i] = 1;
                }
@@ -2472,18 +2470,19 @@ void memory_reset (void)
 #endif
 #endif
 
-       if (currprefs.custom_memory_sizes[0]) {
-               map_banks (&custmem1_bank,
-                       currprefs.custom_memory_addrs[0] >> 16,
-                       currprefs.custom_memory_sizes[0] >> 16, 0);
-       }
-       if (currprefs.custom_memory_sizes[1]) {
-               map_banks (&custmem2_bank,
-                       currprefs.custom_memory_addrs[1] >> 16,
-                       currprefs.custom_memory_sizes[1] >> 16, 0);
+       for (int i = 0; i < 2; i++) {
+               if (currprefs.custom_memory_sizes[i]) {
+                       map_banks (i == 0 ? &custmem1_bank : &custmem2_bank,
+                               currprefs.custom_memory_addrs[i] >> 16,
+                               currprefs.custom_memory_sizes[i] >> 16, 0);
+                       if (currprefs.custom_memory_mask[i]) {
+                               for (int j = currprefs.custom_memory_addrs[i]; j & currprefs.custom_memory_mask[i]; j += currprefs.custom_memory_sizes[i]) {
+                                       map_banks(i == 0 ? &custmem1_bank : &custmem2_bank, j >> 16, currprefs.custom_memory_sizes[i] >> 16, 0);
+                               }
+                       }
+               }
        }
 
-
        if (mem_hardreset) {
                memory_clear ();
        }
@@ -2785,13 +2784,14 @@ static void ppc_generate_map_banks(addrbank *bank, int start, int size)
                        uae_u32 addr = bankaddr + i;
                        addrbank *ab2 = get_sub_bank(&addr);
                        if (ab2 != ab && ab != NULL) {
-                               ppc_map_banks(subbankaddr, (bankaddr + i) - subbankaddr, ab->name, ab->baseaddr, ab == &dummy_bank);
+                               ppc_map_banks(subbankaddr, (bankaddr + i) - subbankaddr, ab->name, (ab->flags & ABFLAG_PPCIOSPACE) ? NULL : ab->baseaddr, ab == &dummy_bank);
                                subbankaddr = bankaddr + i;
                        }
                        ab = ab2;
                }
        } else {
-               ppc_map_banks(bankaddr, banksize, bank->name, bank->baseaddr, bank == &dummy_bank);
+               // ABFLAG_PPCIOSPACE = map as indirect even if baseaddr is non-NULL
+               ppc_map_banks(bankaddr, banksize, bank->name, (bank->flags & ABFLAG_PPCIOSPACE) ? NULL: bank->baseaddr, bank == &dummy_bank);
        }
 }
 #endif
index e2bc2013900bb10a90d5afb684dd53692c5caffa..6fdf3b38d0c2c64b696c2071e859a644ebc99b00 100644 (file)
@@ -821,7 +821,7 @@ static void set_x_funcs (void)
                        x_do_cycles_post = do_cycles_ce_post;
                } else if (currprefs.cpu_memory_cycle_exact) {
                        // cpu_memory_cycle_exact + cpu_compatible
-                       x_prefetch = get_word_prefetch;
+                       x_prefetch = get_word_000_prefetch;
                        x_get_ilong = NULL;
                        x_get_iword = get_iiword;
                        x_get_ibyte = get_iibyte;
@@ -838,7 +838,7 @@ static void set_x_funcs (void)
                        x_do_cycles_post = do_cycles_post;
                } else if (currprefs.cpu_compatible) {
                        // cpu_compatible only
-                       x_prefetch = get_word_prefetch;
+                       x_prefetch = get_word_000_prefetch;
                        x_get_ilong = NULL;
                        x_get_iword = get_iiword;
                        x_get_ibyte = get_iibyte;
@@ -940,7 +940,7 @@ static void set_x_funcs (void)
                } else if (currprefs.cpu_compatible) {
                        // cpu_compatible only
                        if (currprefs.cpu_model == 68020 && !currprefs.cachesize) {
-                               x_prefetch = get_word_prefetch;
+                               x_prefetch = get_word_020_prefetch;
                                x_get_ilong = get_long_020_prefetch;
                                x_get_iword = get_word_020_prefetch;
                                x_get_ibyte = NULL;
@@ -956,7 +956,7 @@ static void set_x_funcs (void)
                                x_do_cycles_pre = do_cycles;
                                x_do_cycles_post = do_cycles_post;
                        } else if (currprefs.cpu_model == 68030 && !currprefs.cachesize) {
-                               x_prefetch = get_word_prefetch;
+                               x_prefetch = get_word_020_prefetch;
                                x_get_ilong = get_long_030_prefetch;
                                x_get_iword = get_word_030_prefetch;
                                x_get_ibyte = NULL;
@@ -3440,11 +3440,21 @@ static void do_trace (void)
 static void check_uae_int_request(void)
 {
        if (uae_int_requested || uaenet_int_requested) {
-               if ((uae_int_requested & 0x00ff) || uaenet_int_requested)
+               bool irq = false;
+               if ((uae_int_requested & 0x00ff) || uaenet_int_requested) {
                        INTREQ_f(0x8000 | 0x0008);
-               if (uae_int_requested & 0xff00)
+                       irq = true;
+               }
+               if (uae_int_requested & 0xff00) {
                        INTREQ_f(0x8000 | 0x2000);
-               set_special(SPCFLAG_INT);
+                       irq = true;
+               }
+               if (uae_int_requested & 0xff0000) {
+                       if (!cpuboard_is_ppcboard_irq())
+                               uae_int_requested &= ~0x010000;
+               }
+               if (irq)
+                       set_special(SPCFLAG_INT);
        }
 }
 
@@ -6862,7 +6872,7 @@ uae_u32 mem_access_delay_wordi_read (uaecptr addr)
        {
        case CE_MEMBANK_CHIP16:
        case CE_MEMBANK_CHIP32:
-               v = wait_cpu_cycle_read (addr, 1);
+               v = wait_cpu_cycle_read (addr, 2);
                break;
        case CE_MEMBANK_FAST16:
        case CE_MEMBANK_FAST32:
@@ -7180,15 +7190,15 @@ uae_u32 mem_access_delay_longi_read_ce020 (uaecptr addr)
        switch (ce_banktype[addr >> 16])
        {
        case CE_MEMBANK_CHIP16:
-               v  = wait_cpu_cycle_read_ce020 (addr + 0, 1) << 16;
-               v |= wait_cpu_cycle_read_ce020 (addr + 2, 1) <<  0;
+               v  = wait_cpu_cycle_read_ce020 (addr + 0, 2) << 16;
+               v |= wait_cpu_cycle_read_ce020 (addr + 2, 2) <<  0;
                break;
        case CE_MEMBANK_CHIP32:
                if ((addr & 3) != 0) {
-                       v  = wait_cpu_cycle_read_ce020 (addr + 0, 1) << 16;
-                       v |= wait_cpu_cycle_read_ce020 (addr + 2, 1) <<  0;
+                       v  = wait_cpu_cycle_read_ce020 (addr + 0, 2) << 16;
+                       v |= wait_cpu_cycle_read_ce020 (addr + 2, 2) <<  0;
                } else {
-                       v = wait_cpu_cycle_read_ce020 (addr, -1);
+                       v = wait_cpu_cycle_read_ce020 (addr, -2);
                }
                break;
        case CE_MEMBANK_FAST32:
index 01e05d186344630c36fd2b7c4b3b5ca91405dd3b..eb7ef9e7e1f0aebd459d07ccce631065c1c204b3 100644 (file)
@@ -1976,11 +1976,11 @@ static bool initialize_rawinput (void)
                struct didata *did = di_keyboard + num_keyboard;
                num_keyboard++;
                rnum_kb++;
-               did->name = my_strdup (_T("WinUAE null keyboard"));
+               did->name = my_strdup (_T("WinUAE keyboard"));
                did->rawinput = NULL;
                did->connection = DIDC_RAW;
                did->sortname = my_strdup (_T("NULLKEYBOARD"));
-               did->priority = -3;
+               did->priority = 2;
                did->configname = my_strdup (_T("NULLKEYBOARD"));
                addrkblabels (did);
        }
@@ -2417,11 +2417,10 @@ static void handle_rawinput_2 (RAWINPUT *raw)
                        if (did->acquired) {
                                if (did->rawinput == h)
                                        break;
-                               if (h == NULL && num_keyboard == 1)
-                                       break;
                        }
                }
                if (num == num_keyboard) {
+                       // find winuae keyboard
                        for (num = 0; num < num_keyboard; num++) {
                                did = &di_keyboard[num];
                                if (did->connection == DIDC_RAW && did->acquired && did->rawinput == NULL)
@@ -2435,7 +2434,7 @@ static void handle_rawinput_2 (RAWINPUT *raw)
                }
 
                // More complex press/release check because we want to support
-               // keys that never return releases, only pressed but also need
+               // keys that never return releases, only presses but also need
                // handle normal keys that can repeat.
 
 #if 0
@@ -2444,7 +2443,7 @@ static void handle_rawinput_2 (RAWINPUT *raw)
 #endif
 
                if (pressed) {
-                       // previously pressed key and next press is same key? Repeat. Ignore it.
+                       // previously pressed key and current press is same key? Repeat. Ignore it.
                        if (scancode == rawprevkey)
                                return;
                        rawprevkey = scancode;
@@ -2489,8 +2488,9 @@ static void handle_rawinput_2 (RAWINPUT *raw)
                        if (isfocus () < 2 && currprefs.input_tablet >= TABLET_MOUSEHACK && currprefs.input_magic_mouse) 
                                return;
                        di_keycodes[num][scancode] = pressed;
-                       if (stopoutput == 0)
+                       if (stopoutput == 0) {
                                my_kbd_handler (num, scancode, pressed);
+                       }
                }
        }
 }
@@ -3506,6 +3506,7 @@ static void flushmsgpump (void)
 static int acquire_kb (int num, int flags)
 {
        if (num < 0) {
+               flushmsgpump();
                doregister_rawinput ();
                if (currprefs.keyboard_leds_in_use) {
                        //write_log (_T("***********************acquire_kb_led\n"));
@@ -3527,7 +3528,6 @@ static int acquire_kb (int num, int flags)
                                //write_log (_T("stored %08x -> %08x\n"), originalleds, newleds);
                        }
                        set_leds (newleds);
-                       flushmsgpump ();
                }
                return 1;
        }
@@ -4153,12 +4153,20 @@ int dinput_wmkey (uae_u32 key)
 int input_get_default_keyboard (int i)
 {
        if (rawinput_enabled_keyboard) {
-               return 1;
+               if (i < 0)
+                       return 0;
+               if (i >= num_keyboard)
+                       return 0;
+               struct didata *did = &di_keyboard[i];
+               if (did->connection == DIDC_RAW && !did->rawinput)
+                       return 1;
        } else {
+               if (i < 0)
+                       return 0;
                if (i == 0)
                        return 1;
-               return 0;
        }
+       return 0;
 }
 
 static void setid (struct uae_input_device *uid, int i, int slot, int sub, int port, int evt, bool gp)
index ae16bdebdf379122dd575c9052215e335cb52f34..7c3e4ab851b76d8ded644b46bc1dc10c2fb3bc1a 100644 (file)
@@ -1218,6 +1218,10 @@ static void generatestorageproperty (struct uae_driveinfo *udi, int ignoreduplic
        _stprintf (udi->device_name, _T("%s"), udi->device_path);
        udi->removablemedia = 1;
 }
+static bool validoffset(ULONG offset, ULONG max)
+{
+       return offset > 0 && offset < max;
+}
 
 static int getstorageproperty (PUCHAR outBuf, int returnedLength, struct uae_driveinfo *udi, int ignoreduplicates)
 {
@@ -1225,10 +1229,11 @@ static int getstorageproperty (PUCHAR outBuf, int returnedLength, struct uae_dri
        TCHAR orgname[1024];
        PUCHAR p;
        int i, j;
-       int size;
+       ULONG size, size2;
 
        devDesc = (PSTORAGE_DEVICE_DESCRIPTOR) outBuf;
        size = devDesc->Version;
+       size2 = devDesc->Size > returnedLength ? returnedLength : devDesc->Size;
        p = (PUCHAR) outBuf;
        if (offsetof(STORAGE_DEVICE_DESCRIPTOR, CommandQueueing) > size) {
                write_log (_T("too short STORAGE_DEVICE_DESCRIPTOR only %d bytes\n"), size);
@@ -1238,22 +1243,22 @@ static int getstorageproperty (PUCHAR outBuf, int returnedLength, struct uae_dri
                write_log (_T("not a direct access device, ignored (type=%d)\n"), devDesc->DeviceType);
                return -2;
        }
-       if (size > offsetof(STORAGE_DEVICE_DESCRIPTOR, VendorIdOffset) && devDesc->VendorIdOffset && p[devDesc->VendorIdOffset]) {
+       if (size > offsetof(STORAGE_DEVICE_DESCRIPTOR, VendorIdOffset) && validoffset(devDesc->VendorIdOffset, size2) && p[devDesc->VendorIdOffset]) {
                j = 0;
                for (i = devDesc->VendorIdOffset; p[i] != (UCHAR) NULL && i < returnedLength; i++)
                        udi->vendor_id[j++] = p[i];
        }
-       if (size > offsetof(STORAGE_DEVICE_DESCRIPTOR, ProductIdOffset) && devDesc->ProductIdOffset && p[devDesc->ProductIdOffset]) {
+       if (size > offsetof(STORAGE_DEVICE_DESCRIPTOR, ProductIdOffset) && validoffset(devDesc->ProductIdOffset, size2) && p[devDesc->ProductIdOffset]) {
                j = 0;
                for (i = devDesc->ProductIdOffset; p[i] != (UCHAR) NULL && i < returnedLength; i++)
                        udi->product_id[j++] = p[i];
        }
-       if (size > offsetof(STORAGE_DEVICE_DESCRIPTOR, ProductRevisionOffset) && devDesc->ProductRevisionOffset && p[devDesc->ProductRevisionOffset]) {
+       if (size > offsetof(STORAGE_DEVICE_DESCRIPTOR, ProductRevisionOffset) && validoffset(devDesc->ProductRevisionOffset, size2) && p[devDesc->ProductRevisionOffset]) {
                j = 0;
                for (i = devDesc->ProductRevisionOffset; p[i] != (UCHAR) NULL && i < returnedLength; i++)
                        udi->product_rev[j++] = p[i];
        }
-       if (size > offsetof(STORAGE_DEVICE_DESCRIPTOR, SerialNumberOffset) && devDesc->SerialNumberOffset && p[devDesc->SerialNumberOffset]) {
+       if (size > offsetof(STORAGE_DEVICE_DESCRIPTOR, SerialNumberOffset) && validoffset(devDesc->SerialNumberOffset, size2) && p[devDesc->SerialNumberOffset]) {
                j = 0;
                for (i = devDesc->SerialNumberOffset; p[i] != (UCHAR) NULL && i < returnedLength; i++)
                        udi->product_serial[j++] = p[i];
@@ -1301,6 +1306,25 @@ static int getstorageproperty (PUCHAR outBuf, int returnedLength, struct uae_dri
        return -1;
 }
 
+static void checkhdname(struct uae_driveinfo *udi)
+{
+       int cnt = 1;
+       int off = _tcslen(udi->device_name);
+       TCHAR tmp[MAX_DPATH];
+       _tcscpy(tmp, udi->device_name);
+       udi->device_name[0] = 0;
+       for (;;) {
+               if (isharddrive(tmp) < 0) {
+                       _tcscpy(udi->device_name, tmp);
+                       return;
+               }
+               tmp[off] = '_';
+               tmp[off + 1] = cnt + '0';
+               tmp[off + 2] = 0;
+               cnt++;
+       }
+}
+
 static BOOL GetDevicePropertyFromName(const TCHAR *DevicePath, DWORD Index, DWORD *index2, uae_u8 *buffer, int ignoreduplicates)
 {
        int i, nosp, geom_ok;
@@ -1394,7 +1418,7 @@ static BOOL GetDevicePropertyFromName(const TCHAR *DevicePath, DWORD Index, DWOR
        }
        udi = &uae_drives[udiindex < 0 ? *index2 : udiindex];
        memcpy (udi, &tmpudi, sizeof (struct uae_driveinfo));
-
+       struct uae_driveinfo *udi2 = udi;
 
        _tcscpy (orgname, udi->device_name);
        udi->bytespersector = 512;
@@ -1482,7 +1506,6 @@ static BOOL GetDevicePropertyFromName(const TCHAR *DevicePath, DWORD Index, DWOR
        }
        dli = (DRIVE_LAYOUT_INFORMATION*)outBuf;
        if (dli->PartitionCount) {
-               struct uae_driveinfo *udi2 = udi;
                int nonzeropart = 0;
                int gotpart = 0;
                int safepart = 0;
@@ -1502,16 +1525,18 @@ static BOOL GetDevicePropertyFromName(const TCHAR *DevicePath, DWORD Index, DWOR
                                write_log (_T("type not 0x76 or 0x30\n"));
                                continue;
                        }
+                       udi++;
+                       (*index2)++;
                        memmove (udi, udi2, sizeof (*udi));
                        udi->device_name[0] = 0;
                        udi->offset = pi->StartingOffset.QuadPart;
                        udi->size = pi->PartitionLength.QuadPart;
                        write_log (_T("used\n"));
                        _stprintf (udi->device_name, _T(":P#%d_%s"), pi->PartitionNumber, orgname);
+                       _stprintf(udi->device_full_path, _T("%s:%s"), udi->device_name, udi->device_path);
+                       checkhdname(udi);
                        udi->dangerous = -5;
                        udi->partitiondrive = true;
-                       udi++;
-                       (*index2)++;
                        safepart = 1;
                        gotpart = 1;
                }
@@ -1531,17 +1556,10 @@ static BOOL GetDevicePropertyFromName(const TCHAR *DevicePath, DWORD Index, DWOR
                        goto end;
        }
 amipartfound:
-       _stprintf (udi->device_name, _T(":%s"), orgname);
-       _stprintf (udi->device_full_path, _T("%s:%s"), udi->device_name, udi->device_path);
+       _stprintf (udi2->device_name, _T(":%s"), orgname);
+       _stprintf (udi2->device_full_path, _T("%s:%s"), udi2->device_name, udi2->device_path);
+       checkhdname(udi2);
        if (udiindex < 0) {
-               int cnt = 1;
-               int off = _tcslen (udi->device_name);
-               while (isharddrive (udi->device_name) >= 0) {
-                       udi->device_name[off] = '_';
-                       udi->device_name[off + 1] = cnt + '0';
-                       udi->device_name[off + 2] = 0;
-                       cnt++;
-               }
                (*index2)++;
        }
 end:
@@ -1742,17 +1760,18 @@ int hdf_getnumharddrives (void)
 
 TCHAR *hdf_getnameharddrive (int index, int flags, int *sectorsize, int *dangerousdrive)
 {
+       struct uae_driveinfo *udi = &uae_drives[index];
        static TCHAR name[512];
        TCHAR tmp[32];
-       uae_u64 size = uae_drives[index].size;
-       int nomedia = uae_drives[index].nomedia;
+       uae_u64 size = udi->size;
+       int nomedia = udi->nomedia;
        TCHAR *dang = _T("?");
        TCHAR *rw = _T("RW");
        bool noaccess = false;
 
        if (dangerousdrive)
                *dangerousdrive = 0;
-       switch (uae_drives[index].dangerous)
+       switch (udi->dangerous)
        {
        case -10:
                dang = _T("[???]");
@@ -1793,7 +1812,7 @@ TCHAR *hdf_getnameharddrive (int index, int flags, int *sectorsize, int *dangero
                if (dangerousdrive)
                        *dangerousdrive = -1;
                if (flags & 1) {
-                       _stprintf (name, _T("[ACCESS DENIED] %s"), uae_drives[index].device_name + 1);
+                       _stprintf (name, _T("[ACCESS DENIED] %s"), udi->device_name + 1);
                        return name;
                }
        } else {
@@ -1803,14 +1822,14 @@ TCHAR *hdf_getnameharddrive (int index, int flags, int *sectorsize, int *dangero
                                *dangerousdrive &= ~1;
                }
 
-               if (uae_drives[index].readonly) {
+               if (udi->readonly) {
                        rw = _T("RO");
                        if (dangerousdrive && !nomedia)
                                *dangerousdrive |= 2;
                }
 
                if (sectorsize)
-                       *sectorsize = uae_drives[index].bytespersector;
+                       *sectorsize = udi->bytespersector;
                if (flags & 1) {
                        if (nomedia) {
                                _tcscpy (tmp, _T("N/A"));
@@ -1822,15 +1841,15 @@ TCHAR *hdf_getnameharddrive (int index, int flags, int *sectorsize, int *dangero
                                else
                                        _stprintf (tmp, _T("%.1fM"), ((double)(uae_u32)(size / (1024))) / 1024.0);
                        }
-                       _stprintf (name, _T("%10s [%s,%s] %s"), dang, tmp, rw, uae_drives[index].device_name + 1);
+                       _stprintf (name, _T("%10s [%s,%s] %s"), dang, tmp, rw, udi->device_name + 1);
                        return name;
                }
        }
        if (flags & 4)
-               return uae_drives[index].device_full_path;
+               return udi->device_full_path;
        if (flags & 2)
-               return uae_drives[index].device_path;
-       return uae_drives[index].device_name;
+               return udi->device_path;
+       return udi->device_name;
 }
 
 static int hmc (struct hardfiledata *hfd)
index 9e1fdf799ad623a57218c99d688d7dd6b798aa2d..5b7767175687df717ac34c64181aa6ce5c2448f0 100644 (file)
@@ -86,7 +86,7 @@ static struct uae_input_device_kbr_default keytrans_amiga[] = {
        { DIK_G, INPUTEVENT_KEY_G },
        { DIK_H, INPUTEVENT_KEY_H },
        { DIK_I, INPUTEVENT_KEY_I },
-       { DIK_J, INPUTEVENT_KEY_J },
+       { DIK_J, INPUTEVENT_KEY_J, 0, INPUTEVENT_SPC_SWAPJOYPORTS, ID_FLAG_QUALIFIER_SPECIAL },
        { DIK_K, INPUTEVENT_KEY_K },
        { DIK_L, INPUTEVENT_KEY_L },
        { DIK_M, INPUTEVENT_KEY_M },
@@ -320,15 +320,12 @@ static int kb_cd32_se[] = { DIK_A, -1, DIK_D, -1, DIK_W, -1, DIK_S, -1, -1, DIK_
 
 static int kb_cdtv[] = { DIK_NUMPAD1, -1, DIK_NUMPAD3, -1, DIK_NUMPAD7, -1, DIK_NUMPAD9, -1, -1 };
 
-static int kb_xa1[] = { DIK_NUMPAD4, -1, DIK_NUMPAD6, -1, DIK_NUMPAD8, -1, DIK_NUMPAD2, DIK_NUMPAD5, -1, DIK_LCONTROL, -1, DIK_LMENU, -1, DIK_SPACE, -1, -1 };
-static int kb_xa2[] = { DIK_D, -1, DIK_G, -1, DIK_R, -1, DIK_F, -1, DIK_A, -1, DIK_S, -1, DIK_Q, -1 };
 static int kb_arcadia[] = { DIK_F2, -1, DIK_1, -1, DIK_2, -1, DIK_5, -1, DIK_6, -1, -1 };
-static int kb_arcadiaxa[] = { DIK_1, -1, DIK_2, -1, DIK_3, -1, DIK_4, -1, DIK_6, -1, DIK_LBRACKET, DIK_LSHIFT, -1, DIK_RBRACKET, -1, DIK_C, -1, DIK_5, -1, DIK_Z, -1, DIK_X, -1, -1 };
 
 static int *kbmaps[] = {
        kb_np, kb_ck, kb_se, kb_np3, kb_ck3, kb_se3,
        kb_cd32_np, kb_cd32_ck, kb_cd32_se,
-       kb_xa1, kb_xa2, kb_arcadia, kb_arcadiaxa, kb_cdtv
+       kb_arcadia, kb_cdtv
 };
 
 static bool specialpressed (void)
@@ -389,7 +386,7 @@ static const int np[] = {
        DIK_NUMPAD3, 3, DIK_NUMPAD4, 4, DIK_NUMPAD5, 5, DIK_NUMPAD6, 6, DIK_NUMPAD7, 7,
        DIK_NUMPAD8, 8, DIK_NUMPAD9, 9, -1 };
 
-void my_kbd_handler (int keyboard, int scancode, int newstate)
+bool my_kbd_handler (int keyboard, int scancode, int newstate)
 {
        int code = 0;
        int scancode_new;
@@ -426,7 +423,7 @@ void my_kbd_handler (int keyboard, int scancode, int newstate)
        if (scancode == DIK_F9 && specialpressed ()) {
                if (newstate)
                        toggle_rtg (-1);
-               return;
+               return true;
        }
 
        scancode_new = scancode;
@@ -437,7 +434,7 @@ void my_kbd_handler (int keyboard, int scancode, int newstate)
                int defaultguikey = amode ? DIK_F12 : DIK_NUMLOCK;
                if (currprefs.win32_guikey >= 0x100) {
                        if (scancode_new == DIK_F12)
-                               return;
+                               return true;
                } else if (currprefs.win32_guikey >= 0) {
                        if (scancode_new == defaultguikey && currprefs.win32_guikey != scancode_new) {
                                scancode = 0;
@@ -607,7 +604,7 @@ void my_kbd_handler (int keyboard, int scancode, int newstate)
 
        if (code) {
                inputdevice_add_inputcode (code, 1);
-               return;
+               return true;
        }
 
 
@@ -629,10 +626,10 @@ void my_kbd_handler (int keyboard, int scancode, int newstate)
 
        if (special) {
                inputdevice_checkqualifierkeycode (keyboard, scancode, newstate);
-               return;
+               return true;
        }
 
-       inputdevice_translatekeycode (keyboard, scancode, newstate);
+       return inputdevice_translatekeycode (keyboard, scancode, newstate) != 0;
 }
 
 void keyboard_settrans (void)
index 4bad5d62802bcc930a1159ac7df55f855f1f0c68..9af19c1ec3e69e8de51d0adf5175d7240e09d5f6 100644 (file)
@@ -892,6 +892,10 @@ void protect_roms (bool protect)
                        write_log (_T("protect_roms VP %08lX - %08lX %x (%dk) failed %d\n"),
                                (uae_u8*)shm->attached - natmem_offset, (uae_u8*)shm->attached - natmem_offset + shm->size,
                                shm->size, shm->size >> 10, GetLastError ());
+               } else {
+                       write_log(_T("ROM VP %08lX - %08lX %x (%dk) %s\n"),
+                               (uae_u8*)shm->attached - natmem_offset, (uae_u8*)shm->attached - natmem_offset + shm->size,
+                               shm->size, shm->size >> 10, protect ? _T("WPROT") : _T("UNPROT"));
                }
        }
 }
index 1aeccaad1c998b1360bb43a6af67ffed11244001..bf476a702fdc8de97759154dd7b714cbd8154697 100644 (file)
@@ -84,28 +84,28 @@ static HMODULE gsdll;
 static void *gsinstance;
 static int gs_exitcode;
 
-typedef int (CALLBACK* GSAPI_REVISION)(gsapi_revision_t *pr, int len);
+typedef int (GSDLLAPI* GSAPI_REVISION)(gsapi_revision_t *pr, int len);
 static GSAPI_REVISION ptr_gsapi_revision;
-typedef int (CALLBACK* GSAPI_NEW_INSTANCE)(void **pinstance, void *caller_handle);
+typedef int (GSDLLAPI* GSAPI_NEW_INSTANCE)(void **pinstance, void *caller_handle);
 static GSAPI_NEW_INSTANCE ptr_gsapi_new_instance;
-typedef void (CALLBACK* GSAPI_DELETE_INSTANCE)(void *instance);
+typedef void (GSDLLAPI* GSAPI_DELETE_INSTANCE)(void *instance);
 static GSAPI_DELETE_INSTANCE ptr_gsapi_delete_instance;
-typedef int (CALLBACK* GSAPI_SET_STDIO)(void *instance,
+typedef int (GSDLLAPI* GSAPI_SET_STDIO)(void *instance,
        int (GSDLLCALLPTR stdin_fn)(void *caller_handle, char *buf, int len),
        int (GSDLLCALLPTR stdout_fn)(void *caller_handle, const char *str, int len),
        int (GSDLLCALLPTR stderr_fn)(void *caller_handle, const char *str, int len));
 static GSAPI_SET_STDIO ptr_gsapi_set_stdio;
-typedef int (CALLBACK* GSAPI_INIT_WITH_ARGS)(void *instance, int argc, char **argv);
-static GSAPI_INIT_WITH_ARGS ptr_gsapi_init_with_args;
+typedef int (GSDLLAPI* GSAPI_INIT_WITH_ARGSW)(void *instance, int argc, wchar_t **argv);
+static GSAPI_INIT_WITH_ARGSW ptr_gsapi_init_with_argsW;
 
-typedef int (CALLBACK* GSAPI_EXIT)(void *instance);
+typedef int (GSDLLAPI* GSAPI_EXIT)(void *instance);
 static GSAPI_EXIT ptr_gsapi_exit;
 
-typedef int (CALLBACK* GSAPI_RUN_STRING_BEGIN)(void *instance, int user_errors, int *pexit_code);
+typedef int (GSDLLAPI* GSAPI_RUN_STRING_BEGIN)(void *instance, int user_errors, int *pexit_code);
 static GSAPI_RUN_STRING_BEGIN ptr_gsapi_run_string_begin;
-typedef int (CALLBACK* GSAPI_RUN_STRING_CONTINUE)(void *instance, const char *str, unsigned int length, int user_errors, int *pexit_code);
+typedef int (GSDLLAPI* GSAPI_RUN_STRING_CONTINUE)(void *instance, const char *str, unsigned int length, int user_errors, int *pexit_code);
 static GSAPI_RUN_STRING_CONTINUE ptr_gsapi_run_string_continue;
-typedef int (CALLBACK* GSAPI_RUN_STRING_END)(void *instance, int user_errors, int *pexit_code);
+typedef int (GSDLLAPI* GSAPI_RUN_STRING_END)(void *instance, int user_errors, int *pexit_code);
 static GSAPI_RUN_STRING_END ptr_gsapi_run_string_end;
 
 static uae_u8 **psbuffer;
@@ -135,32 +135,32 @@ static int openprinter_ps (void)
        int gsargc, gsargc2, i;
        TCHAR *tmpparms[100];
        TCHAR tmp[MAX_DPATH];
-       char *gsparms[100];
+       TCHAR *gsparms[100];
 
        if (ptr_gsapi_new_instance (&gsinstance, NULL) < 0)
                return 0;
        cmdlineparser (currprefs.ghostscript_parameters, tmpparms, 100 - 10);
 
        gsargc2 = 0;
-       gsparms[gsargc2++] = ua (_T("WinUAE"));
+       gsparms[gsargc2++] = my_strdup(_T("WinUAE"));
        for (gsargc = 0; gsargv[gsargc]; gsargc++) {
-               gsparms[gsargc2++] = ua (gsargv[gsargc]);
+               gsparms[gsargc2++] = my_strdup(gsargv[gsargc]);
        }
        for (i = 0; tmpparms[i]; i++)
-               gsparms[gsargc2++] = ua (tmpparms[i]);
+               gsparms[gsargc2++] = my_strdup(tmpparms[i]);
        if (currprefs.prtname[0]) {
                _stprintf (tmp, _T("-sOutputFile=%%printer%%%s"), currprefs.prtname);
-               gsparms[gsargc2++] = ua (tmp);
+               gsparms[gsargc2++] = my_strdup(tmp);
        }
        if (postscript_print_debugging) {
                for (i = 0; i < gsargc2; i++) {
-                       TCHAR *parm = au (gsparms[i]);
+                       TCHAR *parm = gsparms[i];
                        write_log (_T("GSPARM%d: '%s'\n"), i, parm);
                        xfree (parm);
                }
        }
        __try {
-               int rc = ptr_gsapi_init_with_args (gsinstance, gsargc2, gsparms);
+               int rc = ptr_gsapi_init_with_argsW (gsinstance, gsargc2, gsparms);
                for (i = 0; i < gsargc2; i++) {
                        xfree (gsparms[i]);
                }
@@ -212,10 +212,10 @@ static void *prt_thread (void *p)
                                ptr_gsapi_run_string_end (gsinstance, 0, &gs_exitcode);
                        }
                } else {
-                       write_log (_T("gsdll32.dll failed to initialize\n"));
+                       write_log (_T("gsdllxx.dll failed to initialize\n"));
                }
        } else {
-               write_log (_T("gsdll32.dll failed to load\n"));
+               write_log (_T("gsdllxx.dll failed to load\n"));
        }
        unload_ghostscript ();
        prt_running--;
@@ -437,10 +437,10 @@ int load_ghostscript (void)
        ptr_gsapi_run_string_begin = (GSAPI_RUN_STRING_BEGIN)GetProcAddress (gsdll, "gsapi_run_string_begin");
        ptr_gsapi_run_string_continue = (GSAPI_RUN_STRING_CONTINUE)GetProcAddress (gsdll, "gsapi_run_string_continue");
        ptr_gsapi_run_string_end = (GSAPI_RUN_STRING_END)GetProcAddress (gsdll, "gsapi_run_string_end");
-       ptr_gsapi_init_with_args = (GSAPI_INIT_WITH_ARGS)GetProcAddress (gsdll, "gsapi_init_with_args");
+       ptr_gsapi_init_with_argsW = (GSAPI_INIT_WITH_ARGSW)GetProcAddress (gsdll, "gsapi_init_with_argsW");
        if (!ptr_gsapi_new_instance || !ptr_gsapi_delete_instance || !ptr_gsapi_exit ||
                !ptr_gsapi_run_string_begin || !ptr_gsapi_run_string_continue || !ptr_gsapi_run_string_end ||
-               !ptr_gsapi_init_with_args) {
+               !ptr_gsapi_init_with_argsW) {
                        unload_ghostscript ();
                        write_log (_T("incompatible %s! (3)\n"), path);
                        return -3;
index 41fad86362bd9452986d4c69849b7acbf49e53dd..802d46b4eff685bee55a9cbff2a80e57a76db3ff 100644 (file)
@@ -686,7 +686,7 @@ static bool rtg_render (void)
                if (uaegfx) {
                        flushed = picasso_flushpixels (gfxmem_bank.start + natmem_offset, picasso96_state.XYOffset - gfxmem_bank.start);
                } else {
-                       gfxboard_vsync_handler ();
+                       flushed = gfxboard_vsync_handler ();
                }
        }
        return flushed;
index bebc2eb13db1aec6b5a9779a1f54187247c5e021..b9a88fc588b7f0550cf030e15e2c76f1f003d18e 100644 (file)
@@ -504,7 +504,6 @@ BEGIN
     PUSHBUTTON      "Remap / Test [] Remap or test Port 2 configuration.",IDC_PORT1_REMAP,310,74,78,14
     PUSHBUTTON      "Swap ports [] Swap ports 1 and 2.",IDC_SWAP,45,100,78,14
     LTEXT           "Emulated parallel port joystick adapter",IDC_STATIC,10,124,179,15,SS_CENTERIMAGE
-    RTEXT           "X-Arcade layout information []#1",IDC_STATIC,217,124,170,15,SS_NOTIFY | SS_CENTERIMAGE
     COMBOBOX        IDC_PORT2_JOYS,45,142,342,130,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
     PUSHBUTTON      "Remap [] Remap Parallel port joystick port 1 configurarion.",IDC_PORT2_REMAP,352,159,36,14
     COMBOBOX        IDC_PORT3_JOYS,45,178,342,130,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
@@ -1297,8 +1296,8 @@ END
 //
 
 VS_VERSION_INFO VERSIONINFO
- FILEVERSION 3,2,2,0
- PRODUCTVERSION 3,2,2,0
+ FILEVERSION 3,3,0,0
+ PRODUCTVERSION 3,3,0,0
  FILEFLAGSMASK 0x3fL
 #ifdef _DEBUG
  FILEFLAGS 0x1L
@@ -1314,12 +1313,12 @@ BEGIN
         BLOCK "040904b0"
         BEGIN
             VALUE "FileDescription", "WinUAE"
-            VALUE "FileVersion", "3.2.2.0"
+            VALUE "FileVersion", "3.3.0.0"
             VALUE "InternalName", "WinUAE"
-            VALUE "LegalCopyright", "© 1996-2015 under the GNU Public License (GPL)"
+            VALUE "LegalCopyright", "© 1996-2016 under the GNU Public License (GPL)"
             VALUE "OriginalFilename", "WinUAE.exe"
             VALUE "ProductName", "WinUAE"
-            VALUE "ProductVersion", "3.2.2.0"
+            VALUE "ProductVersion", "3.3.0.0"
         END
     END
     BLOCK "VarFileInfo"
@@ -1438,8 +1437,6 @@ IDR_DRIVE_SPINND_A500_1 WAVE                    "drive_spinnd.wav"
 // Bitmap
 //
 
-IDB_XARCADE             BITMAP                  "xarcade-winuae.bmp"
-
 IDB_LCD160X43           BITMAP                  "lcd.bmp"
 
 
@@ -1854,7 +1851,7 @@ BEGIN
     IDS_SOUND_4CHANNEL      "4 Channels"
     IDS_HF_FS_CUSTOM        "Custom"
     IDS_SELECTFS            "Select file system handler (FFS, PFS, SFS, etc.)"
-    IDS_KEYJOY              "Keyboard Layout A (Numeric keypad, 0 and 5 = Fire)\nKeyboard Layout B (Cursor keys, Right CTRL and ALT = Fire)\nKeyboard Layout C (W=Up S=Down A=Left D=Right, Left ALT = Fire)\nX-Arcade (Left)\nX-Arcade (Right)"
+    IDS_KEYJOY              "Keyboard Layout A (Numeric keypad, 0 and 5 = Fire)\nKeyboard Layout B (Cursor keys, Right CTRL and ALT = Fire)\nKeyboard Layout C (W=Up S=Down A=Left D=Right, Left ALT = Fire)"
     IDS_STATEFILE_UNCOMPRESSED "Uncompressed"
     IDS_STATEFILE_RAMDUMP   "RAM dump"
     IDS_STATEFILE_WAVE      "Wave audio dump"
index c7cf05c3cadd6ae05ee024e83abf6c4997b3c748..9ce8e32aa06b730619aef6509d8dd7cfd886226e 100644 (file)
@@ -377,7 +377,7 @@ static int port_insert (int inputmap_port, int devicetype, DWORD flags, const TC
        inputdevice_compa_clear (&changed_prefs, inputmap_port);
        
        if (_tcslen (name) == 0) {
-               inputdevice_joyport_config (&changed_prefs, _T("none"), inputmap_port, 0, 0, true);
+               inputdevice_joyport_config (&changed_prefs, _T("none"), inputmap_port, 0, 0);
                return TRUE;
        }
        devicetype2 = -1;
@@ -399,10 +399,10 @@ static int port_insert (int inputmap_port, int devicetype, DWORD flags, const TC
                _stprintf (tmp2, _T("KeyboardLayout%d"), i);
                if (!_tcscmp (tmp2, name)) {
                        _stprintf (tmp2, _T("kbd%d"), i + 1);
-                       return inputdevice_joyport_config (&changed_prefs, tmp2, inputmap_port, devicetype2, 0, true);
+                       return inputdevice_joyport_config (&changed_prefs, tmp2, inputmap_port, devicetype2, 0);
                }
        }
-       return inputdevice_joyport_config (&changed_prefs, name, inputmap_port, devicetype2, 1, true);
+       return inputdevice_joyport_config (&changed_prefs, name, inputmap_port, devicetype2, 1);
 }
 
 static int cd_insert (int num, const TCHAR *name)
@@ -647,6 +647,7 @@ static void get_screenmode (struct RPScreenMode *sm, struct uae_prefs *p, bool g
                else if (p->gf[0].gfx_filter_autoscale == AUTOSCALE_RESIZE || p->gf[0].gfx_filter_autoscale == AUTOSCALE_NORMAL)
                        cf |= RP_CLIPFLAGS_AUTOCLIP;
        }
+
        if (full) {
                m &= ~RP_SCREENMODE_DISPLAYMASK;
                m |= p->gfx_apmode[rtg ? APMODE_RTG : APMODE_NATIVE].gfx_display << 8;
@@ -739,6 +740,7 @@ static void set_screenmode (struct RPScreenMode *sm, struct uae_prefs *p)
                                vmult *= 1 << (vres - max_vert_dbl);
                                vres = max_vert_dbl;
                        }
+
                } else {
 
                        half = false;
@@ -819,6 +821,18 @@ static void set_screenmode (struct RPScreenMode *sm, struct uae_prefs *p)
        p->gfx_xcenter_size = -1;
        p->gfx_ycenter_size = -1;
 
+       int m = 1;
+       if (fs < 2) {
+               if (smm == RP_SCREENMODE_SCALE_2X) {
+                       m = 2;
+               } else if (smm == RP_SCREENMODE_SCALE_3X) {
+                       m = 3;
+               } else if (smm == RP_SCREENMODE_SCALE_4X) {
+                       m = 4;
+               }
+       }
+       p->rtg_horiz_zoom_mult = p->rtg_vert_zoom_mult = m;
+
        if (WIN32GFX_IsPicassoScreen ()) {
 
                int m = 1;
@@ -834,7 +848,7 @@ static void set_screenmode (struct RPScreenMode *sm, struct uae_prefs *p)
                                m = 4;
                        }
                }
-               p->rtg_horiz_zoom_mult = p->rtg_vert_zoom_mult = m;
+
                p->gfx_size_win.width = picasso_vidinfo.width * m;
                p->gfx_size_win.height = picasso_vidinfo.height * m;
 
@@ -842,6 +856,7 @@ static void set_screenmode (struct RPScreenMode *sm, struct uae_prefs *p)
                vmult = m;
 
        } else {
+
                if (stretch) {
                        hmult = vmult = 0;
                } else if (integerscale) {
@@ -1372,7 +1387,8 @@ void rp_fixup_options (struct uae_prefs *p)
 
        fixup_size (p);
        get_screenmode (&sm, p, false);
-       sm.dwScreenMode = rp_screenmode;
+       sm.dwScreenMode &= ~RP_SCREENMODE_SCALEMASK;
+       sm.dwScreenMode |= rp_screenmode;
        set_screenmode (&sm, &currprefs);
        set_screenmode (&sm, &changed_prefs);
 
@@ -1469,7 +1485,7 @@ void rp_input_change (int num)
                return;
 
        name[0] = 0;
-       if (currprefs.jports[num].id == JPORT_CUSTOM) {
+       if (JSEM_ISCUSTOM(num, &currprefs)) {
                port_get_custom (num, name);
        } else if (k >= 0) {
                _stprintf (name, _T("KeyboardLayout%d"), k);
index a9082d535cfb259fe840e28d6582a6741e1a37bd..651aed43f3bc658427ddb7abde9941178c89ddd7 100644 (file)
@@ -193,12 +193,12 @@ cd ..
 
 cd ..
 
-zip -9 -r winuaesrc *
+7z a -r winuaesrc *
 
-copy winuaesrc.zip e:\amiga\winuaepackets\winuaesrc%1.zip
-move winuaesrc.zip e:\amiga
+copy winuaesrc.7z e:\amiga\winuaepackets\winuaesrc%1.7z
+move winuaesrc.7z e:\amiga
 cd c:\projects\winuae\src\od-win32
-zip -9 winuaedebug%1 winuae_msvc14\fullrelease\winuae.pdb winuae_msvc14\x64\fullrelease\winuae.pdb
-move winuaedebug%1.zip e:\amiga\winuaepackets\debug\
+7z a winuaedebug%1 winuae_msvc14\fullrelease\winuae.pdb winuae_msvc14\x64\fullrelease\winuae.pdb
+move winuaedebug%1.7z e:\amiga\winuaepackets\debug\
 copy winuae_msvc14\fullrelease\winuae.pdb winuae_msvc14\x64\fullrelease\winuae.pdb d:\amiga\dump
 copy d:\amiga\winuae.exe d:\amiga\dump
index dccb870483f6655862489b6cda34cfa7f946c28d..4213f2436b3c3747545b2bd63e7c2c53b78e2096 100644 (file)
@@ -11,6 +11,7 @@
 #define MOUSECLIP_LOG 0
 #define MOUSECLIP_HIDE 1
 #define TOUCH_SUPPORT 1
+#define TOUCH_DEBUG 1
 
 #include <stdlib.h>
 #include <stdarg.h>
@@ -182,6 +183,8 @@ static int timermode, timeon;
 static int timehandlecounter;
 static HANDLE timehandle[MAX_TIMEHANDLES];
 static bool timehandleinuse[MAX_TIMEHANDLES];
+static HANDLE cpu_wakeup_event;
+static volatile bool cpu_wakeup_event_triggered;
 int sleep_resolution;
 static CRITICAL_SECTION cs_time;
 
@@ -252,19 +255,32 @@ static int init_mmtimer (void)
        sleep_resolution = 1000 / mm_timerres;
        for (i = 0; i < MAX_TIMEHANDLES; i++)
                timehandle[i] = CreateEvent (NULL, TRUE, FALSE, NULL);
+       cpu_wakeup_event = CreateEvent(NULL, FALSE, FALSE, NULL);
        InitializeCriticalSection (&cs_time);
        timehandlecounter = 0;
        return 1;
 }
 
+void sleep_cpu_wakeup(void)
+{
+       if (!cpu_wakeup_event_triggered) {
+               cpu_wakeup_event_triggered = true;
+               SetEvent(cpu_wakeup_event);
+       }
+}
+
 static void sleep_millis2 (int ms, bool main)
 {
        UINT TimerEvent;
        int start = 0;
        int cnt;
 
-       if (main)
+       if (main) {
+               if (WaitForSingleObject(cpu_wakeup_event, 0) == WAIT_OBJECT_0) {
+                       return;
+               }
                start = read_processor_time ();
+       }
        EnterCriticalSection (&cs_time);
        for (;;) {
                timehandlecounter++;
@@ -278,7 +294,15 @@ 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);
-       WaitForSingleObject (timehandle[cnt], ms);
+       if (main) {
+               HANDLE evt[2];
+               evt[0] = timehandle[cnt];
+               evt[1] = cpu_wakeup_event;
+               DWORD status = WaitForMultipleObjects(2, evt, FALSE, ms);
+               cpu_wakeup_event_triggered = false;
+       } else {
+               WaitForSingleObject(timehandle[cnt], ms);
+       }
        ResetEvent (timehandle[cnt]);
        timeKillEvent (TimerEvent);
        timehandleinuse[cnt] = false;
@@ -949,8 +973,11 @@ void setmouseactivexy (int x, int y, int dir)
 
 int isfocus (void)
 {
-       if (isfullscreen () > 0)
-               return 2;
+       if (isfullscreen () > 0) {
+               if (!minimized)
+                       return 2;
+               return 0;
+       }
        if (currprefs.input_tablet >= TABLET_MOUSEHACK && currprefs.input_magic_mouse) {
                if (mouseinside)
                        return 2;
@@ -1034,7 +1061,6 @@ static void add_media_insert_queue(HWND hwnd, const TCHAR *drvname, int retrycnt
 }
 
 #if TOUCH_SUPPORT
-#define TOUCH_DEBUG 0
 static int touch_touched;
 static DWORD touch_time;
 
@@ -2880,7 +2906,7 @@ void logging_init (void)
                SystemInfo.wProcessorArchitecture, SystemInfo.wProcessorLevel, SystemInfo.wProcessorRevision,
                SystemInfo.dwNumberOfProcessors, filedate, os_touch);
        write_log (_T("\n(c) 1995-2001 Bernd Schmidt   - Core UAE concept and implementation.")
-               _T("\n(c) 1998-2015 Toni Wilen      - Win32 port, core code updates.")
+               _T("\n(c) 1998-2016 Toni Wilen      - Win32 port, core code updates.")
                _T("\n(c) 1996-2001 Brian King      - Win32 port, Picasso96 RTG, and GUI.")
                _T("\n(c) 1996-1999 Mathias Ortmann - Win32 port and bsdsocket support.")
                _T("\n(c) 2000-2001 Bernd Meyer     - JIT engine.")
index 8fc11cece91af96cbb1b6a660cf4d3e818a0634b..20a144ae68329540957f3b3eb034abdb017c6684 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 0
+#define LANG_DLL_FULL_VERSION_MATCH 1
 
 #if WINUAEPUBLICBETA
-#define WINUAEBETA _T("")
+#define WINUAEBETA _T("1")
 #else
 #define WINUAEBETA _T("")
 #endif
 
-#define WINUAEDATE MAKEBD(2015, 12, 21)
+#define WINUAEDATE MAKEBD(2016, 1, 9)
 
 //#define WINUAEEXTRA _T("AmiKit Preview")
 //#define WINUAEEXTRA _T("Amiga Forever Edition")
@@ -53,7 +53,7 @@ extern TCHAR start_path_exe[MAX_DPATH];
 extern TCHAR start_path_data[MAX_DPATH];
 extern TCHAR start_path_plugins[MAX_DPATH];
 
-extern void my_kbd_handler (int, int, int);
+extern bool my_kbd_handler (int, int, int);
 extern void clearallkeys (void);
 extern int getcapslock (void);
 
index 9cc2d6b96a403cb8625593d4c59a51b1c104da47..755d63997e5fdd96a7c772f92adc2aa68b48d1a8 100644 (file)
@@ -1927,8 +1927,8 @@ int check_prefs_changed_gfx (void)
                //c |= gf->gfx_filter_ != gfc->gfx_filter_ ? (1|8) : 0;
        }
 
-       c |= currprefs.rtg_horiz_zoom_mult != changed_prefs.rtg_horiz_zoom_mult ? (1) : 0;
-       c |= currprefs.rtg_vert_zoom_mult != changed_prefs.rtg_vert_zoom_mult ? (1) : 0;
+       c |= currprefs.rtg_horiz_zoom_mult != changed_prefs.rtg_horiz_zoom_mult ? 16 : 0;
+       c |= currprefs.rtg_vert_zoom_mult != changed_prefs.rtg_vert_zoom_mult ? 16 : 0;
 
        c |= currprefs.gfx_luminance != changed_prefs.gfx_luminance ? (1 | 256) : 0;
        c |= currprefs.gfx_contrast != changed_prefs.gfx_contrast ? (1 | 256) : 0;
@@ -2420,6 +2420,7 @@ static int reopen (int full, bool unacquire)
        currprefs.gfx_size_win.height = changed_prefs.gfx_size_win.height;
        currprefs.gfx_size_win.x = changed_prefs.gfx_size_win.x;
        currprefs.gfx_size_win.y = changed_prefs.gfx_size_win.y;
+
        currprefs.gfx_apmode[0].gfx_fullscreen = changed_prefs.gfx_apmode[0].gfx_fullscreen;
        currprefs.gfx_apmode[1].gfx_fullscreen = changed_prefs.gfx_apmode[1].gfx_fullscreen;
        currprefs.gfx_apmode[0].gfx_vsync = changed_prefs.gfx_apmode[0].gfx_vsync;
@@ -2427,6 +2428,10 @@ static int reopen (int full, bool unacquire)
        currprefs.gfx_apmode[0].gfx_vsyncmode = changed_prefs.gfx_apmode[0].gfx_vsyncmode;
        currprefs.gfx_apmode[1].gfx_vsyncmode = changed_prefs.gfx_apmode[1].gfx_vsyncmode;
        currprefs.gfx_apmode[0].gfx_refreshrate = changed_prefs.gfx_apmode[0].gfx_refreshrate;
+
+       currprefs.rtg_horiz_zoom_mult = changed_prefs.rtg_horiz_zoom_mult;
+       currprefs.rtg_vert_zoom_mult = changed_prefs.rtg_vert_zoom_mult;
+
 #if 0
        currprefs.gfx_apmode[1].gfx_refreshrate = changed_prefs.gfx_apmode[1].gfx_refreshrate;
 #endif
index c41b1e670d14b4d8672c2efa3dfe658e624c689c..7e71acadee8d77515a42fe9bcb4d7256e457b8e6 100644 (file)
@@ -1368,7 +1368,7 @@ static const int msi_cpuboard[] = { 0, 5, 6, 7, 8, 9, 10, 11, 12, 13 };
 #define MIN_M68K_PRIORITY 1
 #define MAX_M68K_PRIORITY 16
 #define MIN_CACHE_SIZE 0
-#define MAX_CACHE_SIZE 8
+#define MAX_CACHE_SIZE 9
 #define MIN_REFRESH_RATE 1
 #define MAX_REFRESH_RATE 10
 #define MIN_SOUND_MEM 0
@@ -2008,8 +2008,8 @@ struct ConfigStruct {
        FILETIME t;
 };
 
-static TCHAR *configreg[] = { _T("ConfigFile"), _T("ConfigFileHardware"), _T("ConfigFileHost") };
-static TCHAR *configreg2[] = { _T(""), _T("ConfigFileHardware_Auto"), _T("ConfigFileHost_Auto") };
+static const TCHAR *configreg[] = { _T("ConfigFile"), _T("ConfigFileHardware"), _T("ConfigFileHost") };
+static const TCHAR *configreg2[] = { _T(""), _T("ConfigFileHardware_Auto"), _T("ConfigFileHost_Auto") };
 static struct ConfigStruct **configstore;
 static int configstoresize, configstoreallocated, configtype, configtypepanel;
 
@@ -3876,7 +3876,7 @@ static int inputmap_handle (HWND list, int currentdevnum, int currentwidgetnum,
                if (inputdevice_get_compatibility_input (&workprefs, portnum, &mode, events, &axistable) > 0) {
                        int evtnum;
                        for (int i = 0; (evtnum = events[i]) >= 0; i++) {
-                               struct inputevent *evt = inputdevice_get_eventinfo (evtnum);
+                               const struct inputevent *evt = inputdevice_get_eventinfo (evtnum);
                                LV_ITEM lvstruct = { 0 };
                                int devnum;
                                int status;
@@ -4033,7 +4033,7 @@ struct miscentry
        int ival, imask;
 };
 
-static struct miscentry misclist[] = { 
+static const struct miscentry misclist[] = { 
        { 0, 1, _T("Untrap = middle button"),  &workprefs.win32_middle_mouse },
        { 0, 0, _T("Show GUI on startup"), &workprefs.start_gui },
        { 0, 1, _T("Use CTRL-F11 to quit"), &workprefs.win32_ctrl_F11_is_quit },
@@ -4254,7 +4254,7 @@ void InitializeListView (HWND hDlg)
                listview_column_width[0] = 150;
                for (i = 0; misclist[i].name; i++) {
                        TCHAR tmpentry[MAX_DPATH], itemname[MAX_DPATH];
-                       struct miscentry *me = &misclist[i];
+                       const struct miscentry *me = &misclist[i];
                        int type = me->type;
                        bool checked = false;
 
@@ -10131,7 +10131,7 @@ static INT_PTR MiscDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
                        if (nmlistview->hdr.code == LVN_ITEMCHANGED) {
                                int item = nmlistview->iItem;
                                if (item >= 0) {
-                                       struct miscentry *me = &misclist[item];
+                                       const struct miscentry *me = &misclist[item];
                                        bool checked = (nmlistview->uNewState & LVIS_STATEIMAGEMASK) == 0x2000;
                                        if (me->b) {
                                                *me->b = checked;
@@ -10346,9 +10346,9 @@ static INT_PTR CALLBACK MiscDlgProc2 (HWND hDlg, UINT msg, WPARAM wParam, LPARAM
        return MiscDlgProc (hDlg, msg, wParam, lParam);
 }
 
-static int cpu_ids[]   = { IDC_CPU0, IDC_CPU1, IDC_CPU2, IDC_CPU3, IDC_CPU4, IDC_CPU5 };
-static int fpu_ids[]   = { IDC_FPU0, IDC_FPU1, IDC_FPU2, IDC_FPU3 };
-static int trust_ids[] = { IDC_TRUST0, IDC_TRUST1, IDC_TRUST1, IDC_TRUST1 };
+static const int cpu_ids[]   = { IDC_CPU0, IDC_CPU1, IDC_CPU2, IDC_CPU3, IDC_CPU4, IDC_CPU5 };
+static const int fpu_ids[]   = { IDC_FPU0, IDC_FPU1, IDC_FPU2, IDC_FPU3 };
+static const int trust_ids[] = { IDC_TRUST0, IDC_TRUST1, IDC_TRUST1, IDC_TRUST1 };
 
 static void enable_for_cpudlg (HWND hDlg)
 {
@@ -10568,7 +10568,7 @@ static void values_from_cpudlg (HWND hDlg)
                trust_prev = workprefs.comptrustbyte;
                workprefs.cachesize = 0;
        } else if (jitena && !oldcache) {
-               workprefs.cachesize = 8192;
+               workprefs.cachesize = MAX_JIT_CACHE;
                workprefs.cpu_cycle_exact = false;
                workprefs.cpu_memory_cycle_exact = false;
                if (!cachesize_prev)
@@ -13863,9 +13863,10 @@ static void enable_for_portsdlg (HWND hDlg)
        ew (hDlg, IDC_PS_PARAMS, full_property_sheet && ghostscript_available && isprinter);
 }
 
-static int joys[] = { IDC_PORT0_JOYS, IDC_PORT1_JOYS, IDC_PORT2_JOYS, IDC_PORT3_JOYS };
-static int joysm[] = { IDC_PORT0_JOYSMODE, IDC_PORT1_JOYSMODE, -1, -1 };
-static int joysaf[] = { IDC_PORT0_AF, IDC_PORT1_AF, -1, -1 };
+static const int joys[] = { IDC_PORT0_JOYS, IDC_PORT1_JOYS, IDC_PORT2_JOYS, IDC_PORT3_JOYS };
+static const int joysm[] = { IDC_PORT0_JOYSMODE, IDC_PORT1_JOYSMODE, -1, -1 };
+static const int joysaf[] = { IDC_PORT0_AF, IDC_PORT1_AF, -1, -1 };
+static const int joyremap[] = { IDC_PORT0_REMAP, IDC_PORT1_REMAP, IDC_PORT2_REMAP, IDC_PORT3_REMAP };
 
 static void updatejoyport (HWND hDlg, int changedport)
 {
@@ -13921,9 +13922,11 @@ static void updatejoyport (HWND hDlg, int changedport)
                        for (j = 0; j < inputdevice_get_device_total (IDTYPE_MOUSE); j++, total++)
                                SendDlgItemMessage (hDlg, id, CB_ADDSTRING, 0, (LPARAM)inputdevice_get_device_name (IDTYPE_MOUSE, j));
                }
-               if (v == JPORT_CUSTOM) {
-                       SendDlgItemMessage (hDlg, id, CB_ADDSTRING, 0, (LPARAM)_T("<Custom mapping>"));
-                       total++;
+               for (j = 0; j < MAX_JPORTS_CUSTOM; j++, total++) {
+                       _stprintf(tmp2, _T("<%s>"), szNone.c_str());
+                       inputdevice_parse_jport_custom(&workprefs, j, i, tmp2);
+                       _stprintf(tmp, _T("Custom %d: %s"), j + 1, tmp2);
+                       SendDlgItemMessage(hDlg, id, CB_ADDSTRING, 0, (LPARAM)tmp);
                }
 
                idx = inputdevice_getjoyportdevice (i, v);
@@ -13936,6 +13939,8 @@ static void updatejoyport (HWND hDlg, int changedport)
                SendDlgItemMessage (hDlg, id, CB_SETCURSEL, idx, 0);
                if (joysaf[i] >= 0)
                        SendDlgItemMessage (hDlg, joysaf[i], CB_SETCURSEL, workprefs.jports[i].autofire, 0);
+
+               ew(hDlg, joyremap[i], idx >= 2);
        }
 }
 
@@ -13975,18 +13980,19 @@ static void values_from_gameportsdlg (HWND hDlg, int d, int changedport)
                        if (i < 2)
                                max += inputdevice_get_device_total (IDTYPE_MOUSE);
                        v -= 2;
-                       if (v < 0)
+                       if (v < 0) {
                                *port = JPORT_NONE;
-                       else if (v >= max && prevport == JPORT_CUSTOM)
-                               *port = JPORT_CUSTOM;
-                       else if (v >= max)
+                       } else if (v >= max + MAX_JPORTS_CUSTOM) {
                                *port = JPORT_NONE;
-                       else if (v < JSEM_LASTKBD)
+                       } else if (v >= max) {
+                               *port = JSEM_CUSTOM + v - max;
+                       } else if (v < JSEM_LASTKBD) {
                                *port = JSEM_KBDLAYOUT + (int)v;
-                       else if (v >= JSEM_LASTKBD + inputdevice_get_device_total (IDTYPE_JOYSTICK))
+                       } else if (v >= JSEM_LASTKBD + inputdevice_get_device_total (IDTYPE_JOYSTICK)) {
                                *port = JSEM_MICE + (int)v - inputdevice_get_device_total (IDTYPE_JOYSTICK) - JSEM_LASTKBD;
-                       else
+                       } else {
                                *port = JSEM_JOYS + (int)v - JSEM_LASTKBD;
+                       }
                }
                if (idm >= 0) {
                        v = SendDlgItemMessage (hDlg, idm, CB_GETCURSEL, 0, 0L);
@@ -14003,7 +14009,7 @@ static void values_from_gameportsdlg (HWND hDlg, int d, int changedport)
                        changed = 1;
        }
        if (changed)
-               inputdevice_validate_jports (&workprefs, changedport);
+               inputdevice_validate_jports (&workprefs, changedport, NULL);
 }
 
 static int midi2dev (struct midiportinfo **mid, int idx, int def)
@@ -14788,9 +14794,13 @@ static void doinputcustom (HWND hDlg, int newcustom)
                &flags, &port, NULL, custom1, input_selected_sub_num);
        if (_tcslen (custom1) > 0 || newcustom) {
                if (askinputcustom (hDlg, custom1, sizeof custom1 / sizeof (TCHAR), IDS_SB_CUSTOMEVENT)) {
-                       if (custom1[0])
-                       inputdevice_set_mapping (input_selected_device, input_selected_widget,
-                               NULL, custom1, flags, port, input_selected_sub_num);
+                       if (custom1[0]) {
+                               inputdevice_set_mapping (input_selected_device, input_selected_widget,
+                                       NULL, custom1, flags, port, input_selected_sub_num);
+                       } else {
+                               inputdevice_set_mapping(input_selected_device, input_selected_widget,
+                                       NULL, NULL, 0, -1, input_selected_sub_num);
+                       }
                }
        }
 }
@@ -15045,6 +15055,7 @@ static void CALLBACK timerfunc (HWND hDlg, UINT uMsg, UINT_PTR idEvent, DWORD dw
                                        }
                                }
                                inputmap_remap_event = 0;
+                               inputdevice_generate_jport_custom(&workprefs, inputmap_port);
                                InitializeListView (myDlg);
                                input_find (hDlg, myDlg, 0, FALSE, false);
                                return;
@@ -15165,6 +15176,9 @@ static void CALLBACK timerfunc (HWND hDlg, UINT uMsg, UINT_PTR idEvent, DWORD dw
 //                             write_log (_T("%d %d %d\n"), input_selected_device, input_selected_widget, evtnum);
                                if (evtnum >= 0)
                                        inputdevice_set_gameports_mapping (&workprefs, input_selected_device, input_selected_widget, evtnum, 0, inputmap_port, workprefs.input_selected_setting);
+
+                               inputdevice_generate_jport_custom(&workprefs, inputmap_port);
+
                                InitializeListView (hDlg);
                                inputmap_remap_counter++;
                                if (inputmap_remap_counter >= max || inputmap_oneshot) {
@@ -15309,7 +15323,7 @@ static void input_find (HWND hDlg, HWND mainDlg, int mode, int set, bool oneshot
                inputmap_oneshot = oneshot;
                inputmap_disable (hDlg, true);
                inputdevice_settest (TRUE);
-               inputdevice_acquire (-1);
+               inputdevice_acquire (mode ? -1 : -2);
                TCHAR tmp2[MAX_DPATH];
                GetWindowText (guiDlg, tmp, sizeof tmp / sizeof (TCHAR));
                WIN32GUI_LoadUIString (IDS_REMAPTITLE, tmp2, sizeof tmp2 / sizeof (TCHAR));
@@ -15438,7 +15452,7 @@ static void fillinputmapadd (HWND hDlg)
        int evt = 1;
        for (;;) {
                bool ignore = false;
-               struct inputevent *ie = inputdevice_get_eventinfo (evt);
+               const struct inputevent *ie = inputdevice_get_eventinfo (evt);
                if (!ie)
                        break;
                if (_tcslen (ie->name) == 0) {
@@ -15482,10 +15496,11 @@ static INT_PTR CALLBACK InputMapDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPA
                fillinputmapadd (hDlg);
                inputdevice_updateconfig (NULL, &workprefs);
                InitializeListView (hDlg);
-               if (workprefs.jports[inputmap_port].id != JPORT_CUSTOM) {
-                       ew (hDlg, IDC_INPUTMAP_CAPTURE, FALSE);
-                       ew (hDlg, IDC_INPUTMAP_DELETE, FALSE);
-                       ew (hDlg, IDC_INPUTMAP_CUSTOM, FALSE);
+               if (!JSEM_ISCUSTOM(inputmap_port, &workprefs)) {
+                       ew(hDlg, IDC_INPUTMAP_CAPTURE, FALSE);
+                       ew(hDlg, IDC_INPUTMAP_DELETE, FALSE);
+                       ew(hDlg, IDC_INPUTMAP_DELETEALL, FALSE);
+                       ew(hDlg, IDC_INPUTMAP_CUSTOM, FALSE);
                }
                break;
        }
@@ -15507,7 +15522,7 @@ static INT_PTR CALLBACK InputMapDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPA
                                        if (lv->iItem >= 0) {
                                                inputmap_selected = lv->iItem;
                                                inputmap_remap_counter = getremapcounter (lv->iItem);
-                                               if (workprefs.jports[inputmap_port].id == JPORT_CUSTOM) {
+                                               if (JSEM_ISCUSTOM(inputmap_port, &workprefs)) {
                                                        input_find (hDlg, hDlg, 1, true, true);
                                                }
                                        }
@@ -15545,39 +15560,36 @@ static INT_PTR CALLBACK InputMapDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPA
                        if (inputmap_remap_counter < 0)
                                inputmap_remap_counter = 0;
                        inputmap_port_remap = inputmap_port;
-                       if (workprefs.jports[inputmap_port].id != JPORT_CUSTOM) {
-                               inputdevice_compa_prepare_custom (&workprefs, inputmap_port, -1, false);
-                               inputdevice_updateconfig (NULL, &workprefs);
-                               InitializeListView (hDlg);
-                       }
+                       inputdevice_compa_prepare_custom (&workprefs, inputmap_port, -1, false);
+                       inputdevice_updateconfig (NULL, &workprefs);
+                       InitializeListView (hDlg);
                        ListView_EnsureVisible (h, inputmap_remap_counter, FALSE);
                        ListView_SetItemState (h, -1, 0, LVIS_SELECTED | LVIS_FOCUSED);
                        ListView_SetItemState (h, inputmap_remap_counter, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
                        input_find (hDlg, hDlg, 1, true, false);
                        break;
                        case IDC_INPUTMAP_CUSTOM:
-                       if (workprefs.jports[inputmap_port].id == JPORT_CUSTOM) {
-                               tmp[0] = 0;
-                               SendDlgItemMessage (hDlg, IDC_INPUTMAPADD, WM_GETTEXT, (WPARAM)sizeof tmp / sizeof (TCHAR), (LPARAM)tmp);
-                               i = 1;
-                               for (;;) {
-                                       struct inputevent *ie = inputdevice_get_eventinfo (i);
-                                       if (!ie)
-                                               break;
-                                       if (_tcslen (ie->name) > 0 && !_tcsicmp (tmp, ie->name)) {
-                                               inputmap_remap_counter = -2;
-                                               inputmap_remap_event = i;
-                                               inputmap_port_remap = inputmap_port;
-                                               input_find (hDlg, hDlg, 1, true, false);
-                                               break;
-                                       }
-                                       i++;
+                       tmp[0] = 0;
+                       SendDlgItemMessage (hDlg, IDC_INPUTMAPADD, WM_GETTEXT, (WPARAM)sizeof tmp / sizeof (TCHAR), (LPARAM)tmp);
+                       i = 1;
+                       for (;;) {
+                               const struct inputevent *ie = inputdevice_get_eventinfo (i);
+                               if (!ie)
+                                       break;
+                               if (_tcslen (ie->name) > 0 && !_tcsicmp (tmp, ie->name)) {
+                                       inputmap_remap_counter = -2;
+                                       inputmap_remap_event = i;
+                                       inputmap_port_remap = inputmap_port;
+                                       input_find (hDlg, hDlg, 1, true, false);
+                                       break;
                                }
+                               i++;
                        }
                        break;
                        case IDC_INPUTMAP_DELETE:
-                       if (workprefs.jports[inputmap_port].id == JPORT_CUSTOM) {
+                       if (JSEM_ISCUSTOM(inputmap_port, &workprefs)) {
                                update_listview_inputmap (hDlg, inputmap_selected);
+                               inputdevice_generate_jport_custom(&workprefs, inputmap_port);
                                InitializeListView (hDlg);
                        }
                        break;
@@ -15646,7 +15658,7 @@ static void input_togglesetmode (void)
        evtnum = inputdevice_get_mapping (input_selected_device, input_selected_widget,
                &flags, NULL, name, custom, input_selected_sub_num);
        if (evtnum) {
-               struct inputevent *evt = inputdevice_get_eventinfo (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);
@@ -18983,7 +18995,9 @@ int gui_init (void)
        int ret;
 
        read_rom_list ();
-       inputdevice_updateconfig (NULL, &workprefs);
+       default_prefs(&workprefs, 0);
+       prefs_to_gui(&changed_prefs);
+       inputdevice_updateconfig(NULL, &workprefs);
        for (;;) {
                ret = GetSettings (1, currprefs.win32_notaskbarbutton ? hHiddenWnd : NULL);
                if (!restart_requested)
index c5bae0faa675f7f4c321ff0574c2c901268b8104..f7aa08e4f97e8491bb91506f32f1ced4ec107872 100644 (file)
@@ -1,4 +1,62 @@
 
+
+- Added extra validation checks for STORAGE_DEVICE_DESCRIPTOR, buggy drivers may return invalid (negative) offset
+  values.
+- 64-bit JIT harmless "Warning! 12 is locked" log spamming disabled.
+- Updated copper/blitter cycle conflict emulation. It only triggers when CPU writes to COPJMP, Copper is waiting and
+  Copper DMA is enabled (and blitter uses same cycle). If Copper DMA was off, bug won't trigger, even if DMA gets
+  enabled few cycles later. Copper bug emulation is again always enabled if 68000 and cycle-exact config.
+- Cancel main thread sleep state immediately (Sleep due to CPU idle or similar) if PPC thread caused mainboard interrupt-
+  This should reduce PPC to M68K interrupt emulation latency.
+- Hardware RTG emulation rendered same frame twice in some situations. Caused very slow performance in triple buffered mode.
+- Debugger keyboard presses were buffered and output to Amiga-side when debugger was exited.
+- Starting disk DMA does not flush Paula internal 16 bit buffer. Poll DSKBYTR for DSKSYNC, immediately start disk DMA with
+  WORDSYNC enabled: following sync word must not be missed. (Original Virus really slow loading in cycle-exact mode)
+- Chip ram was marked as 16-bit Fast RAM for the CPU (no DMA contention emulation) if any memwatch point was active.
+- Amithlon partition type (0x78/0x30) support was broken, partitions were detected but it was not possible to mount them.
+- Added SX32 Pro board and ROM image. (Not all RAM sizes are correctly mapped)
+- Only unmap Z3 Fast RAM at reset if Z3 mapping mode is "Real" for better compatibility with old configs that assume
+  Z3 RAM does not temporarily disappear at boot.
+- JIT on/off on the fly change without other CPU settings changed at the same time with uae-configuration didn't work.
+- Hardware emulation autoconfig board UAE interface first working feature: uae-configuration now works under OS4
+  Requires also updated uae-configuration, interface can also work under other non-m68k AmigaOS operating systems,
+  only requirement is simple native uae-configuration port. Interface design is not final yet.
+- If CSPPC or BPPC is booted with empty or zero size flash rom image, fake resident idtag is automatically added that
+  fools official flash rom updater to detect working board, "updating" the empty flash with full image (updater
+  contains full flash rom image in encrypted format)
+- Debugger memwatch points can now match only CPU instruction (CPUI) or only CPU data accesses (CPUD, CPUDR, CPUDW)
+- "Heat map" debugger added, shows optional visual heatmap of CPU and DMA accesses. Can list highest addresses used by
+  CPU instruction fetches or all addresses that single device accessed (Some DMA channel, CPU)
+- Some AGA modes were incorrectly detected as overrunning causing screen corruption.
+- AROS ROM updated.
+
+Input system and mapping updates:
+
+- Added SPC_SWAPJOYPORTS input event, swaps gameports joystick ports.
+- Added END+J default mapping = SPC_SWAPJOYPORTS.
+- Device autoswitch didn't ignore button release without matching press.
+- Device autoswitch switches to new Game Ports custom event if it has fire button mapped to mouse or gamepad.
+- "WinUAE null keyboard" renamed to "WinUAE keyboard", this is now the default global virtual keyboard. GamePorts panel
+  only uses this keyboard, multiple keyboards are only supported in Input panel mode and only if manually enabled.
+  Reduces complexity and confusion when moving configurations between systems with different number of keyboards.
+- Game Ports custom mapping rewritten. Now Game Ports list has 6 custom slots which can me inserted to any joystick port.
+  New custom mapping data is also saved to separate config entries, one per slot.
+- Old Game Ports custom config is automatically converted to new custom mapping system.
+- Removed X-Arcade built-in layouts. Re-create them with new custom mapping system if needed.
+- Cleared custom input event string equals setting event to "<none>".
+- Fixed since the beginning bug that caused incorrectly matched input device(s) and input config when config was loaded
+  with different connected input devices and order of devices was also different.
+- Rewritten game ports validation (Detect and fix if same device in multiple ports etc..).
+- Old config files should still work like previously except: game Ports custom mapping and first keyboard input config
+  goes to WinUAE keyboard slot.
+- Last few Game Ports panel inserted devices (layout or real input device) are remembered. For example if config is loaded
+  with joypad A inserted in port 2 but pad is not plugged in, then user manually changes it to joypad B. Now if pad A is
+  later reinserted and pad B is removed, A is automatically put in port 2. It also works with keyboard layouts or new
+  custom layouts, if keyboard layout was previously selected, then it was later replaced with gamepad, if gamepad is unplugged
+  on the fly, previous keyboard layout is automatically selected.
+
+Game Ports panel "simple" custom mapping should be finally very intuitive to use.
+
 3.2.2
 
 - JIT x64 R12 special case fix.
index f0857c63f3bde458c2da58259a129e4d0d294e5b..f57bf1e54c11f9b686c80fd25f588da58b5e3633 100644 (file)
@@ -108,6 +108,15 @@ static void getconsole (void)
        }
 }
 
+static void flushmsgpump(void)
+{
+       MSG msg;
+       while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
+               TranslateMessage(&msg);
+               DispatchMessage(&msg);
+       }
+}
+
 void activate_console (void)
 {
        if (!consoleopen)
@@ -350,6 +359,7 @@ void console_out (const TCHAR *txt)
 
 bool console_isch (void)
 {
+       flushmsgpump();
        if (console_buffer) {
                return 0;
        } else if (realconsole) {
@@ -364,6 +374,7 @@ bool console_isch (void)
 
 TCHAR console_getch (void)
 {
+       flushmsgpump();
        if (console_buffer) {
                return 0;
        } else if (realconsole) {
@@ -386,6 +397,7 @@ int console_get (TCHAR *out, int maxlen)
 {
        *out = 0;
 
+       flushmsgpump();
        set_console_input_mode(1);
        if (consoleopen > 0) {
                return console_get_gui (out, maxlen);
index 8e9f8639e77afd4ee6ebb3979e1088831e73e6b9..ad41d4847cf45254ed116b263457b6f7b52eaa35 100644 (file)
@@ -455,6 +455,13 @@ bool uae_self_is_ppc(void)
        return impl.in_cpu_thread();
 }
 
+void uae_ppc_wakeup_main(void)
+{
+       if (uae_self_is_ppc()) {
+               sleep_cpu_wakeup();
+       }
+}
+
 void ppc_map_banks(uae_u32 start, uae_u32 size, const TCHAR *name, void *addr, bool remove)
 {
        if (ppc_state == PPC_STATE_INACTIVE || !impl.map_memory)
@@ -603,6 +610,7 @@ STATIC_INLINE bool spinlock_pre(uaecptr addr)
 {
        addrbank *ab = &get_mem_bank(addr);
        if ((ab->flags & ABFLAG_THREADSAFE) == 0) {
+               sleep_cpu_wakeup();
                uae_ppc_spinlock_get();
                return true;
        }
@@ -641,6 +649,21 @@ bool UAECALL uae_ppc_io_mem_write(uint32_t addr, uint32_t data, int size)
                put_byte(addr, data);
                break;
        }
+
+       if (addr >= 0xdff000 && addr < 0xe00000) {
+               int reg = addr & 0x1fe;
+               switch (reg) {
+                       case 0x09c: // INTREQ
+                       case 0x09a: // INTENA
+                       if (data & 0x8000) {
+                               // possible interrupt change:
+                               // make sure M68K thread reacts to it ASAP.
+                               uae_int_requested |= 0x010000;
+                       }
+                       break;
+               }
+       }
+
        spinlock_post(locked);
 
 #if PPC_ACCESS_LOG >= 2
@@ -658,12 +681,13 @@ bool UAECALL uae_ppc_io_mem_read(uint32_t addr, uint32_t *data, int size)
        while (ppc_thread_running && ppc_cpu_lock_state < 0 && ppc_state);
 
        if (addr >= 0xdff000 && addr < 0xe00000) {
+               int reg = addr & 0x1fe;
                // shortcuts for common registers
-               if (addr == 0xdff01c) { // INTENAR
+               switch (reg) {
+                       case 0x01c: // INTENAR
                        *data = intena;
                        return true;
-               }
-               if (addr == 0xdff01e) { // INTREQR
+                       case 0x01e: // INTREQR
                        *data = intreq;
                        return true;
                }
@@ -692,7 +716,8 @@ bool UAECALL uae_ppc_io_mem_read(uint32_t addr, uint32_t *data, int size)
        }
 #endif
 #if PPC_ACCESS_LOG >= 2
-       write_log(_T("PPC read %08x=%08x %d\n"), addr, v, size);
+       if (addr < 0xb00000 || addr > 0xc00000)
+               write_log(_T("PPC read %08x=%08x %d\n"), addr, v, size);
 #endif
        return true;
 }
index 7a5f4333d896a54bc6439777289f72aaf28c46fb..b53068ace234527830a1fa43258781ce37af1a3e 100644 (file)
@@ -95,7 +95,7 @@ struct romdata *getromdatabypath (const TCHAR *path)
        return NULL;
 }
 
-#define NEXT_ROM_ID 160
+#define NEXT_ROM_ID 161
 
 #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 },
@@ -368,6 +368,8 @@ static struct romdata roms[] = {
        0xb2dae8c4, 0xcdfe2d96, 0xe44d4f8d, 0x3833a5e8, 0xb6c832fd, 0xc7b341a9, NULL, NULL },
        { _T("M-Tec E-Matrix 530"), 0, 0, 0, 0, _T("EMATRIX530\0"), 65536, 144, 0, 0, ROMTYPE_CB_EMATRIX, 0, 0, NULL,
        0x3942d827, 0x5aaf118f, 0x61fc3083, 0x1435b87c, 0x8bdab6a4, 0x59b4ee22, NULL, NULL },
+       { _T("SX32 Pro"), 0, 0, 0, 0, _T("SX32PRO\0"), 65536, 160, 0, 0, ROMTYPE_CB_SX32PRO, 0, 0, NULL,
+       0xbfd68a88, 0x84a50880, 0x76917549, 0xadf33b16, 0x8a869adb, 0x9e5a6fac, NULL, NULL },
 
        { _T("Preferred Technologies Nexus"), 1, 0, 1, 0, _T("PTNEXUS\0"), 8192, 139, 0, 0, ROMTYPE_PTNEXUS, 0, 0, NULL,
        0xf495879a, 0xa3bd0202, 0xe14aa5b6, 0x49d3ce88, 0x22975950, 0x6500dbc2, NULL, NULL },
index 9cdd3f5b78b4acaecc4a1015c5e75131d0f84341..57a1b9bda05bcc82a973f4aaba965b9a79b97603 100644 (file)
@@ -360,71 +360,58 @@ static int native_dos_op (uae_u32 mode, uae_u32 p1, uae_u32 p2, uae_u32 p3)
        return 0;
 }
 
-static uae_u32 REGPARAM2 uaelib_demux2 (TrapContext *context)
+static uae_u32 uaelib_demux_common(uae_u32 ARG0, uae_u32 ARG1, uae_u32 ARG2, uae_u32 ARG3, uae_u32 ARG4, uae_u32 ARG5)
 {
-#define ARG0 (get_long (m68k_areg (regs, 7) + 4))
-#define ARG1 (get_long (m68k_areg (regs, 7) + 8))
-#define ARG2 (get_long (m68k_areg (regs, 7) + 12))
-#define ARG3 (get_long (m68k_areg (regs, 7) + 16))
-#define ARG4 (get_long (m68k_areg (regs, 7) + 20))
-#define ARG5 (get_long (m68k_areg (regs, 7) + 24))
-
-#ifdef PICASSO96
-       if (ARG0 >= 16 && ARG0 <= 39)
-               return picasso_demux (ARG0, context);
-#endif
-
-       switch (ARG0)
-       {
-       case 0: return emulib_GetVersion ();
-       case 1: return emulib_GetUaeConfig (ARG1);
-       case 2: return emulib_SetUaeConfig (ARG1);
-       case 3: return emulib_HardReset ();
-       case 4: return emulib_Reset ();
-       case 5: return emulib_InsertDisk (ARG1, ARG2);
-       case 6: return emulib_EnableSound (ARG1);
-       case 7: return emulib_EnableJoystick (ARG1);
-       case 8: return emulib_SetFrameRate (ARG1);
-       case 9: return emulib_ChgCMemSize (ARG1);
-       case 10: return emulib_ChgSMemSize (ARG1);
-       case 11: return emulib_ChgFMemSize (ARG1);
-       case 12: return emulib_ChangeLanguage (ARG1);
-               /* The next call brings bad luck */
-       case 13: return emulib_ExitEmu ();
-       case 14: return emulib_GetDisk (ARG1, ARG2);
-       case 15: return emulib_Debug ();
-
-       case 68: return emulib_Minimize ();
-       case 69: return emulib_ExecuteNativeCode ();
-
-       case 70: return 0; /* RESERVED. Something uses this.. */
-
-       case 80:
+       switch (ARG0) {
+               case 0: return emulib_GetVersion();
+               case 1: return emulib_GetUaeConfig(ARG1);
+               case 2: return emulib_SetUaeConfig(ARG1);
+               case 3: return emulib_HardReset();
+               case 4: return emulib_Reset();
+               case 5: return emulib_InsertDisk(ARG1, ARG2);
+               case 6: return emulib_EnableSound(ARG1);
+               case 7: return emulib_EnableJoystick(ARG1);
+               case 8: return emulib_SetFrameRate(ARG1);
+               case 9: return emulib_ChgCMemSize(ARG1);
+               case 10: return emulib_ChgSMemSize(ARG1);
+               case 11: return emulib_ChgFMemSize(ARG1);
+               case 12: return emulib_ChangeLanguage(ARG1);
+                       /* The next call brings bad luck */
+               case 13: return emulib_ExitEmu();
+               case 14: return emulib_GetDisk(ARG1, ARG2);
+               case 15: return emulib_Debug();
+
+               case 68: return emulib_Minimize();
+               case 69: return emulib_ExecuteNativeCode();
+
+               case 70: return 0; /* RESERVED. Something uses this.. */
+
+               case 80:
                if (!currprefs.maprom)
                        return 0xffffffff;
                /* Disable possible ROM protection */
-               unprotect_maprom ();
+               unprotect_maprom();
                return currprefs.maprom;
-       case 81: return cfgfile_uaelib (ARG1, ARG2, ARG3, ARG4);
-       case 82: return cfgfile_uaelib_modify (ARG1, ARG2, ARG3, ARG4, ARG5);
-       case 83: currprefs.mmkeyboard = ARG1 ? 1 : 0; return currprefs.mmkeyboard;
+               case 81: return cfgfile_uaelib(ARG1, ARG2, ARG3, ARG4);
+               case 82: return cfgfile_uaelib_modify(ARG1, ARG2, ARG3, ARG4, ARG5);
+               case 83: currprefs.mmkeyboard = ARG1 ? 1 : 0; return currprefs.mmkeyboard;
 #ifdef DEBUGGER
-       case 84: return mmu_init (ARG1, ARG2, ARG3);
+               case 84: return mmu_init(ARG1, ARG2, ARG3);
 #endif
-       case 85: return native_dos_op (ARG1, ARG2, ARG3, ARG4);
-       case 86:
-               if (valid_address (ARG1, 1)) {
-                       TCHAR *s = au ((char*)get_real_address (ARG1));
-                       write_log (_T("DBG: %s\n"), s);
-                       xfree (s);
+               case 85: return native_dos_op(ARG1, ARG2, ARG3, ARG4);
+               case 86:
+               if (valid_address(ARG1, 1)) {
+                       TCHAR *s = au((char*)get_real_address(ARG1));
+                       write_log(_T("DBG: %s\n"), s);
+                       xfree(s);
                        return 1;
                }
                return 0;
-       case 87:
+               case 87:
                {
                        uae_u32 d0, d1;
-                       d0 = emulib_target_getcpurate (ARG1, &d1);
-                       m68k_dreg (regs, 1) = d1;
+                       d0 = emulib_target_getcpurate(ARG1, &d1);
+                       m68k_dreg(regs, 1) = d1;
                        return d0;
                }
 
@@ -432,6 +419,35 @@ static uae_u32 REGPARAM2 uaelib_demux2 (TrapContext *context)
        return 0;
 }
 
+uae_u32 uaeboard_demux(uae_u32 *board)
+{
+       uae_u32 arg0, arg1, arg2, arg3, arg4, arg5;
+
+       arg0 = do_get_mem_word((uae_u16*)&board[0]);
+       arg1 = do_get_mem_long(&board[2]);
+       arg2 = do_get_mem_long(&board[3]);
+       arg3 = do_get_mem_long(&board[4]);
+       arg4 = do_get_mem_long(&board[5]);
+       arg5 = do_get_mem_long(&board[6]);
+       return uaelib_demux_common(arg0, arg1, arg2, arg3, arg4, arg5);
+}
+
+static uae_u32 REGPARAM2 uaelib_demux2 (TrapContext *context)
+{
+#define ARG0 (get_long (m68k_areg (regs, 7) + 4))
+#define ARG1 (get_long (m68k_areg (regs, 7) + 8))
+#define ARG2 (get_long (m68k_areg (regs, 7) + 12))
+#define ARG3 (get_long (m68k_areg (regs, 7) + 16))
+#define ARG4 (get_long (m68k_areg (regs, 7) + 20))
+#define ARG5 (get_long (m68k_areg (regs, 7) + 24))
+
+#ifdef PICASSO96
+       if (ARG0 >= 16 && ARG0 <= 39)
+               return picasso_demux(ARG0, context);
+#endif
+       return uaelib_demux_common(ARG0, ARG1, ARG2, ARG3, ARG4, ARG5);
+}
+
 extern int uaelib_debug;
 static uae_u32 REGPARAM2 uaelib_demux (TrapContext *context)
 {