]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Bridgeboard PCem rewrite.
authorToni Wilen <twilen@winuae.net>
Sun, 19 Aug 2018 15:57:41 +0000 (18:57 +0300)
committerToni Wilen <twilen@winuae.net>
Sun, 19 Aug 2018 15:57:41 +0000 (18:57 +0300)
22 files changed:
devices.cpp
disk.cpp
expansion.cpp
gfxboard.cpp
idecontrollers.cpp
include/disk.h
include/gfxboard.h
include/idecontrollers.h
include/newcpu.h
include/rommgr.h
include/x86.h
inputdevice.cpp
main.cpp
newcpu.cpp
od-win32/win32gui.cpp
od-win32/winuae_msvc15/winuae_msvc.vcxproj
od-win32/winuae_msvc15/winuae_msvc.vcxproj.filters
pcem/pcemglue.cpp [new file with mode: 0644]
pcem/pcemglue.h [new file with mode: 0644]
qemuvga/cirrus_vga.cpp
qemuvga/qemuuaeglue.h
x86.cpp

index a11886fa467414201338b8276d5c857639e4e7d6..ddf072d639336b9353c84847756fa44e50573f92 100644 (file)
@@ -263,6 +263,7 @@ void devices_update_sound(double clk, double syncadjust)
        update_sound (clk);
        update_sndboard_sound (clk / syncadjust);
        update_cda_sound(clk / syncadjust);
+       x86_update_sound(clk / syncadjust);
 }
 
 void devices_update_sync(double svpos, double syncadjust)
index 9b7c942bcf0fbc6c29939c4affe8320df9e3ac87..d54916a3202875511d03a4edea3901c7ea68abea 100644 (file)
--- a/disk.cpp
+++ b/disk.cpp
@@ -613,8 +613,9 @@ static void drive_settype_id (drive *drv)
                drv->drive_id = DRIVE_ID_525SD;
                break;
        case DRV_NONE:
-       case DRV_PC_ONLY_40:
-       case DRV_PC_ONLY_80:
+       case DRV_PC_525_ONLY_40:
+       case DRV_PC_525_40_80:
+       case DRV_PC_35_ONLY_80:
                drv->drive_id = DRIVE_ID_NONE;
                break;
        }
@@ -688,7 +689,8 @@ static void setamax (void)
 
 static bool ispcbridgedrive(int num)
 {
-       return currprefs.floppyslots[num].dfxtype == DRV_PC_ONLY_40  || currprefs.floppyslots[num].dfxtype == DRV_PC_ONLY_80;
+       int type = currprefs.floppyslots[num].dfxtype;
+       return type == DRV_PC_525_ONLY_40 || type == DRV_PC_35_ONLY_80 || type == DRV_PC_525_40_80;
 }
 
 static void reset_drive (int num)
@@ -1287,32 +1289,35 @@ static int drive_insert (drive * drv, struct uae_prefs *p, int dnum, const TCHAR
                size == 9 * 82 * 1 * 512 || size == 18 * 82 * 1 * 512 || size == 10 * 82 * 1 * 512 || size == 20 * 82 * 1 * 512)) {
                        /* PC formatted image */
                        int side, sd;
+                       int dfxtype = p->floppyslots[dnum].dfxtype;
 
                        drv->num_secs = 9;
                        drv->ddhd = 1;
                        sd = 0;
 
-                       bool can40 = p->floppyslots[dnum].dfxtype == DRV_525_DD || p->floppyslots[dnum].dfxtype == DRV_PC_ONLY_40;
-
+                       bool can40 = dfxtype == DRV_525_DD || dfxtype == DRV_PC_525_ONLY_40 || dfxtype == DRV_PC_525_40_80;
+                       bool can80 = dfxtype == DRV_35_HD || dfxtype == DRV_PC_35_ONLY_80 || dfxtype == DRV_PC_525_40_80;
+                       bool drv525 = dfxtype == DRV_525_DD || dfxtype == DRV_PC_525_ONLY_40 || dfxtype == DRV_PC_525_40_80;
+       
                        for (side = 2; side > 0; side--) {
-                               if (drv->hard_num_cyls >= 80 && !can40) {
+                               if (drv->hard_num_cyls >= 80 && can80) {
                                        if (       size ==  9 * 80 * side * 512 || size ==  9 * 81 * side * 512 || size ==  9 * 82 * side * 512) {
                                                drv->num_secs = 9;
                                                drv->ddhd = 1;
                                                break;
-                                       } else if (size == 18 * 80 * side * 512 || size == 18 * 81 * side * 512 || size == 18 * 82 * side * 512) {
+                                       } else if (!drv525 && (size == 18 * 80 * side * 512 || size == 18 * 81 * side * 512 || size == 18 * 82 * side * 512)) {
                                                drv->num_secs = 18;
                                                drv->ddhd = 2;
                                                break;
-                                       } else if (size == 10 * 80 * side * 512 || size == 10 * 81 * side * 512 || size == 10 * 82 * side * 512) {
+                                       } else if (!drv525 && (size == 10 * 80 * side * 512 || size == 10 * 81 * side * 512 || size == 10 * 82 * side * 512)) {
                                                drv->num_secs = 10;
                                                drv->ddhd = 1;
                                                break;
-                                       } else if (size == 20 * 80 * side * 512 || size == 20 * 81 * side * 512 || size == 20 * 82 * side * 512) {
+                                       } else if (!drv525 && (size == 20 * 80 * side * 512 || size == 20 * 81 * side * 512 || size == 20 * 82 * side * 512)) {
                                                drv->num_secs = 20;
                                                drv->ddhd = 2;
                                                break;
-                                       } else if (size == 21 * 80 * side * 512 || size == 21 * 81 * side * 512 || size == 21 * 82 * side * 512) {
+                                       } else if (!drv525 && (size == 21 * 80 * side * 512 || size == 21 * 81 * side * 512 || size == 21 * 82 * side * 512)) {
                                                drv->num_secs = 21;
                                                drv->ddhd = 2;
                                                break;
@@ -2574,7 +2579,7 @@ bool disk_creatediskfile (struct uae_prefs *p, const TCHAR *name, int type, driv
                tracks = 2 * 80;
        file_size = 880 * 1024;
        sectors = 11;
-       if (adftype == DRV_PC_ONLY_40 || adftype == DRV_PC_ONLY_80) {
+       if (adftype == DRV_PC_525_ONLY_40 || adftype == DRV_PC_35_ONLY_80 || adftype == DRV_PC_525_40_80) {
                file_size = 720 * 1024;
                sectors = 9;
        }
@@ -2586,7 +2591,10 @@ bool disk_creatediskfile (struct uae_prefs *p, const TCHAR *name, int type, driv
                file_size *= 2;
                track_len *= 2;
                ddhd = 2;
-       } else if (adftype == DRV_PC_ONLY_40) {
+               if (adftype == DRV_PC_525_40_80) {
+                       file_size = 15 * 512 * 80 * 2;
+               }
+       } else if (adftype == DRV_PC_525_ONLY_40) {
                file_size /= 2;
                tracks /= 2;
        }
@@ -4917,11 +4925,16 @@ bool disk_reserved_getinfo(int num, struct floppy_reserved *fr)
                }
                fr->cyl = drv->cyl;
                fr->cyls = drv->num_tracks / 2;
-               fr->drive_cyls = currprefs.floppyslots[idx].dfxtype == DRV_PC_ONLY_40 ? 40 : 80;
+               fr->drive_cyls = currprefs.floppyslots[idx].dfxtype == DRV_PC_525_ONLY_40 ? 40 : 80;
                fr->secs = drv->num_secs;
                fr->heads = drv->num_heads;
                fr->disk_changed = drv->dskchange || fr->img == NULL;
-               if (currprefs.floppyslots[idx].dfxtype == DRV_PC_ONLY_80) {
+               if (currprefs.floppyslots[idx].dfxtype == DRV_PC_35_ONLY_80) {
+                       if (drv->num_secs > 14)
+                               fr->rate = FLOPPY_RATE_500K; // 1.2M/1.4M
+                       else
+                               fr->rate = FLOPPY_RATE_250K; // 720K
+               } else if (currprefs.floppyslots[idx].dfxtype == DRV_PC_525_40_80) {
                        if (fr->cyls < 80) {
                                if (drv->num_secs < 9)
                                        fr->rate = FLOPPY_RATE_250K; // 320k in 80 track drive
@@ -4931,7 +4944,7 @@ bool disk_reserved_getinfo(int num, struct floppy_reserved *fr)
                                if (drv->num_secs > 14)
                                        fr->rate = FLOPPY_RATE_500K; // 1.2M/1.4M
                                else
-                                       fr->rate = FLOPPY_RATE_250K; // 720K
+                                       fr->rate = FLOPPY_RATE_300K; // 720K
                        }
                } else {
                        if (drv->num_secs < 9)
index 26d29e3e4c04719e93aa08235980ecb2494c2eab..ca57539045d218a9a1b8eeba38e149e4ea1729d5 100644 (file)
@@ -4044,12 +4044,30 @@ static const struct expansionboardsettings bridge_settings[] = {
        }
 };
 
+static const struct expansionboardsettings x86vga_settings[] = {
+       {
+               _T("Chipset\0") _T("CL-GD5426\0") _T("CL-GD5429\0"),
+               _T("chipset\0") _T("cl-gd5426\0") _T("cl-gd5429\0"),
+               true
+       },
+       {
+               NULL
+       }
+};
+
+
 static const struct expansionboardsettings x86at286_bridge_settings[] = {
+       {
+               // 13
+               _T("PC Speaker emulation"),
+               _T("speaker"),
+               false, false, 13
+       },
        {
                // 14
                _T("Default video\0") _T("Monochrome\0") _T("Color\0"),
                _T("video\0") _T("mono\0") _T("color\0"),
-               true, false, 14
+               true
        },
        {
                // 15
@@ -4062,20 +4080,10 @@ static const struct expansionboardsettings x86at286_bridge_settings[] = {
                _T("memory\0") _T("1M\0") _T("2M\0") _T("4M\0") _T("8M\0") _T("16M\0"),
                true, false, 0
        },
-       {       // 19 - 20
-               _T("CPU core\0") _T("DOSBox simple\0") _T("DOSBox normal\0") _T("DOSBox full\0") _T("DOSBox auto\0"),
-               _T("cpu\0") _T("dbsimple\0") _T("dbnormal\0") _T("dbfull\0") _T("dbauto\0"),
-               true, false, 0
-       },
-       {       // 22
-               _T("FPU"),
-               _T("fpu"),
-               false, false, 1
-       },
-       {       // 23 - 25
-               _T("CPU Arch\0") _T("auto\0") _T("386\0") _T("386_prefetch\0") _T("386_slow\0") _T("486_slow\0") _T("486_prefetch\0") _T("pentium_slow\0"), 
-               _T("cpuarch\0") _T("auto\0") _T("386\0") _T("386_prefetch\0") _T("386_slow\0") _T("486_slow\0") _T("486_prefetch\0") _T("pentium_slow\0"),
-               true, false, 0
+       {
+               _T("Emulator config\0"),
+               _T("config\0"),
+               2, false, 0
        },
        {
                NULL
@@ -4083,37 +4091,34 @@ static const struct expansionboardsettings x86at286_bridge_settings[] = {
 };
 
 static const struct expansionboardsettings x86at386_bridge_settings[] = {
+       {
+               // 13
+               _T("PC Speaker emulation"),
+               _T("speaker"),
+               false, false, 13
+       },
        {
                // 15
                _T("Keyboard lock"),
                _T("keylock"),
-               false, false, 15
+               false, false, 15 - 14
        },
        {       // 16 - 18
                _T("Memory\0") _T("1M\0") _T("2M\0") _T("4M\0") _T("8M\0") _T("16M\0") _T("32M\0") _T("64M\0"),
                _T("memory\0") _T("1M\0") _T("2M\0") _T("4M\0") _T("8M\0") _T("16M\0") _T("32M\0") _T("64M\0"),
                true, false, 0
        },
-       {       // 19 - 20
-               _T("CPU core\0") _T("DOSBox simple\0") _T("DOSBox normal\0") _T("DOSBox full\0") _T("DOSBox auto\0"),
-               _T("cpu\0") _T("dbsimple\0") _T("dbnormal\0") _T("dbfull\0") _T("dbauto\0"),
-               true, false, 0
-       },
-       {       // 22
-               _T("FPU"),
-               _T("fpu"),
-               false, false, 1
-       },
-       {       // 23 - 25
-               _T("CPU Arch\0") _T("auto\0") _T("386\0") _T("386_prefetch\0") _T("386_slow\0") _T("486_slow\0") _T("486_prefetch\0") _T("pentium_slow\0"),
-               _T("cpuarch\0") _T("auto\0") _T("386\0") _T("386_prefetch\0") _T("386_slow\0") _T("486_slow\0") _T("486_prefetch\0") _T("pentium_slow\0"),
-               true, false, 0
+       {
+               _T("Emulator config\0"),
+               _T("config\0"),
+               2, false, 0
        },
        {
                NULL
        }
 };
 
+// A2088/A2088T
 static const struct expansionboardsettings x86_bridge_settings[] = {
        {
                // 2-3
@@ -4127,19 +4132,16 @@ static const struct expansionboardsettings x86_bridge_settings[] = {
                _T("video\0") _T("mono\0") _T("color40\0") _T("color80\0") _T("none\0"),
                true, false, 0
        },
-       {       // 19 - 21
-               _T("CPU core\0") _T("Fake86\0") _T("DOSBox simple\0") _T("DOSBox normal\0") _T("DOSBox full\0") _T("DOSBox auto\0"),
-               _T("cpu\0") _T("fake86\0") _T("dbsimple\0") _T("dbnormal\0") _T("dbfull\0") _T("dbauto\0"),
-               true, false, 19 - 6
-       },
-       {       // 22
-               _T("FPU (DOSBox CPU only)"),
-               _T("fpu")
+       {
+               // 13
+               _T("PC Speaker emulation"),
+               _T("speaker"),
+               false, false, 13 - 6
        },
-       {       // 23 - 25
-               _T("CPU Arch (DOSBox CPU only)\0") _T("auto") _T("386\0") _T("386_prefetch\0") _T("386_slow\0") _T("486_slow\0") _T("486_prefetch\0") _T("pentium_slow\0"),
-               _T("cpuarch\0") _T("auto") _T("386\0") _T("386_prefetch\0") _T("386_slow\0") _T("486_slow\0") _T("486_prefetch\0") _T("pentium_slow\0"),
-               true, false, 0
+       {
+               _T("Emulator config\0"),
+               _T("config\0"),
+               2, false, 0
        },
        {
                NULL
@@ -4196,19 +4198,15 @@ static const struct expansionboardsettings x86_bridge_sidecar_settings[] = {
                _T("Disable parallel port emulation (J11)"),
                _T("parport_card")
        },
-       {       // 19 - 21
-               _T("CPU core\0") _T("Fake86\0") _T("DOSBox simple\0") _T("DOSBox normal\0") _T("DOSBox full\0") _T("DOSBox auto\0"),
-               _T("cpu\0") _T("fake86\0") _T("dbsimple\0") _T("dbnormal\0") _T("dbfull\0") _T("dbauto\0"),
-               true, false, 19 - 13
-       },
-       {       // 22
-               _T("FPU (DOSBox CPU only)"),
-               _T("fpu")
+       {
+               // 13
+               _T("PC Speaker emulation"),
+               _T("speaker")
        },
-       {       // 23 - 25
-               _T("CPU Arch (DOSBox CPU only)\0") _T("auto") _T("386\0") _T("386_prefetch\0") _T("386_slow\0") _T("486_slow\0") _T("486_prefetch\0") _T("pentium_slow\0"),
-               _T("cpuarch\0") _T("auto") _T("386\0") _T("386_prefetch\0") _T("386_slow\0") _T("486_slow\0") _T("486_prefetch\0") _T("pentium_slow\0"),
-               true, false, 0
+       {
+               _T("Emulator config\0"),
+               _T("config\0"),
+               2, false, 0
        },
        {
                NULL
@@ -4344,6 +4342,53 @@ static const struct expansionboardsettings cubo_settings[] = {
        }
 };
 
+static struct expansionboardsettings x86_mouse_settings[] = {
+       {
+               _T("Amiga port\0") _T("1\0") _T("2\0"),
+               _T("port\0") _T("1\0") _T("2\0"),
+               true
+       },
+       {
+               _T("Mouse type\0") _T("Serial (COM1)\0") _T("PS/2 (2-Button)\0") _T("PS/2 (Intellimouse)"),
+               _T("type\0") _T("serial\0") _T("ps2\0") _T("im\0"),
+               true, false, 1
+       },
+       {
+               NULL
+       }
+};
+
+static struct expansionboardsettings sb_isa_settings[] = {
+       {
+               _T("Model\0") _T("Sound Blaster v1.0\0") _T("Sound Blaster v1.5\0") _T("Sound Blaster v2.0\0") _T("Sound Blaster Pro v1\0") _T("Sound Blaster Pro v2\0") _T("Sound Blaster 16\0"),
+               _T("model\0") _T("SB1\0") _T("SB15\0") _T("SB2\0") _T("SBP1\0") _T("SBP2\0") _T("SB16\0"),
+               true, false, 
+       },
+       {
+               _T("IO\0") _T("210\0") _T("220 (*)\0") _T("230\0") _T("240\0") _T("250\0") _T("260\0") _T("270\0") _T("280\0"),
+               _T("io\0") _T("210\0") _T("220\0") _T("230\0") _T("240\0") _T("250\0") _T("260\0") _T("270\0") _T("280\0"),
+               true, false,
+       },
+       {
+               _T("IRQ (SB16: not used)\0") _T("2\0") _T("3\0") _T("5\0") _T("7 (*)\0") _T("10 (SB Pro)\0"),
+               _T("irq\0") _T("irq2\0") _T("irq3\0") _T("irq5\0") _T("irq7\0") _T("irq10\0"),
+               true, false,
+       },
+       {
+               _T("DMA (SB16: not used)\0") _T("1 (*)\0") _T("3\0"),
+               _T("dma\0") _T("dma1\0") _T("dma3\0"),
+               true, false,
+       },
+       {
+               _T("OPL EMU (SB Pro v2+)\0") _T("DBOPL\0") _T("NukedOPL\0"),
+               _T("opl_emu\0") _T("dbopl\0") _T("nukedopl\0"),
+               true, false, 0
+       },
+       {
+               NULL
+       }
+};
+
 static struct expansionboardsettings ne2k_isa_settings[] = {
        {
                _T("IO\0") _T("240\0") _T("260\0") _T("280\0") _T("2A0\0") _T("300\0") _T("320\0") _T("340\0") _T("360\0"),
@@ -5205,27 +5250,12 @@ const struct expansionromtype expansionroms[] = {
                _T("amax"), _T("AMAX ROM dongle"), _T("ReadySoft"),
                NULL, NULL, NULL, NULL, ROMTYPE_AMAX | ROMTYPE_NONE, 0, 0, 0, false
        },
-
-#if 0
-       {
-               _T("x86_xt_hd"), _T("x86 XT"), _T("x86"),
-               NULL, x86_xt_hd_init, NULL, x86_add_xt_hd_unit, ROMTYPE_X86_HD | ROMTYPE_NONE, 0, 0, BOARD_NONAUTOCONFIG_AFTER_Z2, true,
-               NULL, 0,
-               false, EXPANSIONTYPE_CUSTOM | EXPANSIONTYPE_SCSI
-       },
-#endif
        {
                _T("x86athdprimary"), _T("AT IDE Primary"), _T("x86"),
                NULL, x86_at_hd_init_1, NULL, x86_add_at_hd_unit_1, ROMTYPE_X86_AT_HD1 | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_AFTER_Z2, true,
                NULL, 0,
                false, EXPANSIONTYPE_IDE
        },
-       {
-               _T("x86athdsecondary"), _T("AT IDE Secondary"), _T("x86"),
-               NULL, x86_at_hd_init_2, NULL, x86_add_at_hd_unit_2, ROMTYPE_X86_AT_HD2 | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_AFTER_Z2, true,
-               NULL, 0,
-               false, EXPANSIONTYPE_IDE
-       },
        {
                _T("x86athdxt"), _T("XTIDE Universal BIOS HD"), _T("x86"),
                NULL, x86_at_hd_init_xt, NULL, x86_add_at_hd_unit_xt, ROMTYPE_X86_XT_IDE | ROMTYPE_NONE, 0, 0, BOARD_NONAUTOCONFIG_AFTER_Z2, true,
@@ -5289,7 +5319,9 @@ const struct expansionromtype expansionroms[] = {
                _T("x86vga"), _T("x86 VGA"), _T("x86"),
                NULL, NULL, NULL, NULL, ROMTYPE_x86_VGA | ROMTYPE_NONE, 0, 0, BOARD_IGNORE, true,
                NULL, 0,
-               false, EXPANSIONTYPE_RTG
+               false, EXPANSIONTYPE_RTG,
+               0, 0, 0, false, NULL,
+               false, 0, x86vga_settings
        },
        {
                _T("harlequin"), _T("Harlequin"), _T("ACS"),
@@ -5341,6 +5373,16 @@ const struct expansionromtype expansionroms[] = {
                false, 0, NULL,
                { 0x80, 2, 0x10, 0x00, 6502 >> 8, 6502 & 255, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
        },
+       {
+               _T("sb_isa"), _T("SoundBlaster ISA (Creative)"), NULL,
+               NULL, isa_expansion_init, NULL, NULL, ROMTYPE_SBISA | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_BEFORE, true,
+               NULL, 0,
+               false, EXPANSIONTYPE_SOUND,
+               0, 0, 0, false, NULL,
+               false, 0, sb_isa_settings
+       },
+
+
 #if 0
        {
                _T("pmx"), _T("pmx"), NULL,
@@ -5540,6 +5582,14 @@ const struct expansionromtype expansionroms[] = {
                0, 0, 0, false, NULL,
                false, 0, cubo_settings,
        },
+       {
+               _T("x86_mouse"), _T("x86 Bridgeboard mouse"), NULL,
+               NULL, isa_expansion_init, NULL, NULL, ROMTYPE_X86MOUSE | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_BEFORE, true,
+               NULL, 0,
+               false, EXPANSIONTYPE_CUSTOM,
+               0, 0, 0, false, NULL,
+               false, 0, x86_mouse_settings
+       },
 
 
        {
index acd64e8e1884eabeb1594faddff79deee438e73e..c5f998bca579206768dc53dc3365778592a7e74d 100644 (file)
@@ -181,7 +181,7 @@ static const struct gfxboard boards[] =
        {
                _T("x86 bridgeboard VGA"), _T("x86"), _T("VGA"),
                0, 0, 0,
-               0x00000000, 0x00100000, 0x00100000, 0x00000000, CIRRUS_ID_CLGD5426, 0, 0, false,
+               0x00000000, 0x00100000, 0x00200000, 0x00000000, CIRRUS_ID_CLGD5426, 0, 0, false,
                ROMTYPE_x86_VGA
        },
        {
@@ -243,6 +243,7 @@ struct rtggfxboard
        int vga_width, vga_height;
        bool vga_refresh_active;
        bool vga_changed;
+       int device_settings;
 
        uae_u32 vgaioregionptr, vgavramregionptr, vgabank0regionptr, vgabank1regionptr;
 
@@ -392,9 +393,19 @@ static void init_board (struct rtggfxboard *gb)
 {
        struct rtgboardconfig *rbc = gb->rbc;
        int vramsize = gb->board->vrammax;
+       int chiptype = gb->board->chiptype;
+
+       if (gb->board->romtype == ROMTYPE_x86_VGA) {
+               struct romconfig *rc = get_device_romconfig(&currprefs, gb->board->romtype, 0);
+               chiptype = CIRRUS_ID_CLGD5426;
+               if (rc && rc->device_settings == 1) {
+                       chiptype = CIRRUS_ID_CLGD5429;
+               }
+       }
 
        gb->active = true;
        gb->vga_width = 0;
+       gb->vga_height = 0;
        mapped_free(gb->gfxmem_bank);
        gb->vram_start_offset = 0;
        if (ISP4() && !gb->p4z2) { // JIT direct compatibility hack
@@ -412,8 +423,12 @@ static void init_board (struct rtggfxboard *gb)
                gb->gfxmem_bank->label = _T("*");
                mapped_malloc(gb->gfxmem_bank);
        } else {
-               gb->gfxmem_bank->label = _T("ram_a8");
+               gb->gfxmem_bank->label = _T("*");
                gb->vram_back = xmalloc(uae_u8, vramsize);
+               if (&get_mem_bank(0x800000) == &dummy_bank)
+                       gb->gfxmem_bank->start = 0x800000;
+               else
+                       gb->gfxmem_bank->start = 0xa00000;
                gfxboard_get_a8_vram(gb->rbc->rtg_index);
        }
        gb->vram = gb->gfxmem_bank->baseaddr;
@@ -445,7 +460,7 @@ static void init_board (struct rtggfxboard *gb)
        gb->fakesurface.data = gb;
        vga_common_init(&gb->vga.vga);
        gb->vga.vga.con = (void*)gb;
-       cirrus_init_common(&gb->vga, gb->board->chiptype, 0,  NULL, NULL, gb->board->manufacturer == 0);
+       cirrus_init_common(&gb->vga, chiptype, 0,  NULL, NULL, gb->board->manufacturer == 0, gb->board->romtype == ROMTYPE_x86_VGA);
        picasso_allocatewritewatch(gb->rbc->rtg_index, gb->rbc->rtgmem_size);
 }
 
@@ -928,7 +943,7 @@ void gfxboard_vsync_handler(bool full_redraw_required, bool redraw_required)
 
                        if (gb->monswitch_keep_trying) {
                                vga_update_size(gb);
-                               if (gb->vga_width > 16 || gb->vga_height > 16) {
+                               if (gb->vga_width > 16 && gb->vga_height > 16) {
                                        gb->monswitch_keep_trying = false;
                                        gb->monswitch_new = true;
                                        gb->monswitch_delay = 0;
@@ -1285,6 +1300,20 @@ uae_u8 vga_ram_get(int board, int offset)
        offset -= 0xa0000;
        return gb->vgalowram->read(&gb->vga, offset, 1);
 }
+void vgalfb_ram_put(int board, int offset, uae_u8 v)
+{
+       struct rtggfxboard *gb = &rtggfxboards[board];
+       if (!gb->vgaram)
+               return;
+       gb->vgaram->write(&gb->vga, offset, v, 1);
+}
+uae_u8 vgalfb_ram_get(int board, int offset)
+{
+       struct rtggfxboard *gb = &rtggfxboards[board];
+       if (!gb->vgaram)
+               return 0xff;
+       return gb->vgaram->read(&gb->vga, offset, 1);
+}
 
 void *memory_region_get_ram_ptr(MemoryRegion *mr)
 {
index 3a5546228fad84383deaf57bf33da59a2221c373..8762a37c835d2f018d8c47542d7a053b1f83fcd8 100644 (file)
@@ -253,11 +253,10 @@ void idecontroller_rethink(void)
 {
        bool irq = false;
        for (int i = 0; ide_boards[i]; i++) {
-               if (ide_boards[i] == x86_at_ide_board[0] || ide_boards[i] == x86_at_ide_board[1]) {
+               if (ide_boards[i] == x86_at_ide_board[0]) {
                        bool x86irq = ide_rethink(ide_boards[i], true);
                        if (x86irq) {
-                               //write_log(_T("x86 IDE IRQ\n"));
-                               x86_doirq(ide_boards[i] == x86_at_ide_board[0] ? 14 : 15);
+                               x86_doirq(14);
                        }
                } else {
                        if (ide_rethink(ide_boards[i], false))
@@ -2376,10 +2375,6 @@ bool x86_at_hd_init_1(struct autoconfig_info *aci)
 {
        return x86_at_hd_init(aci, 0);
 }
-bool x86_at_hd_init_2(struct autoconfig_info *aci)
-{
-       return x86_at_hd_init(aci, 0);
-}
 bool x86_at_hd_init_xt(struct autoconfig_info *aci)
 {
        return x86_at_hd_init(aci, 1);
@@ -2389,13 +2384,9 @@ void x86_add_at_hd_unit_1(int ch, struct uaedev_config_info *ci, struct romconfi
 {
        add_ide_standard_unit(ch, ci, rc, &x86_at_ide_board[0], x86_AT_IDE + 0, false, false, 2);
 }
-void x86_add_at_hd_unit_2(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
-{
-       add_ide_standard_unit(ch, ci, rc, &x86_at_ide_board[1], x86_AT_IDE + 1, false, false, 2);
-}
 void x86_add_at_hd_unit_xt(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
 {
-       add_ide_standard_unit(ch, ci, rc, &x86_at_ide_board[2], x86_AT_IDE + 2, false, false, 2);
+       add_ide_standard_unit(ch, ci, rc, &x86_at_ide_board[1], x86_AT_IDE + 1, false, false, 2);
 }
 
 static int x86_ide_reg(int portnum, int *unit)
@@ -2444,10 +2435,6 @@ void x86_ide_hd_put(int portnum, uae_u16 v, int size)
        if (regnum >= 0) {
                struct ide_board *board = x86_at_ide_board[unit];
                if (board) {
-#if 0
-                       if (regnum == 0 || regnum == 8)
-                               write_log(_T("WRITE %04x = %04x %d\n"), portnum, v, size);
-#endif
                        if (size == 0) {
                                if (get_ide_is_8bit(board)) {
                                        v = get_ide_reg_8bitdata(board, regnum);
@@ -2494,10 +2481,6 @@ uae_u16 x86_ide_hd_get(int portnum, int size)
                                v = get_ide_reg(board, regnum);
                                v = (v >> 8) | (v << 8);
                        }
-#if 0
-                       if (regnum == 0 || regnum == 8)
-                               write_log(_T("READ %04x = %04x %d\n"), portnum, v, size);
-#endif
                }
        }
        return v;
index 3581ea45a0b96a6ebd28bf13a674f670792753b8..8698957dd6a6db621396b7e46b01f90fdad4370d 100644 (file)
@@ -11,7 +11,7 @@
 
 #include "uae/types.h"
 
-typedef enum { DRV_NONE = -1, DRV_35_DD = 0, DRV_35_HD, DRV_525_SD, DRV_35_DD_ESCOM, DRV_PC_ONLY_40, DRV_PC_ONLY_80, DRV_525_DD } drive_type;
+typedef enum { DRV_NONE = -1, DRV_35_DD = 0, DRV_35_HD, DRV_525_SD, DRV_35_DD_ESCOM, DRV_PC_525_ONLY_40, DRV_PC_35_ONLY_80, DRV_PC_525_40_80, DRV_525_DD } drive_type;
 
 #define HISTORY_FLOPPY 0
 #define HISTORY_CD 1
index 269e4be052d3b7228fffb575d4e1fa84d54efb7e..af4895d18bec53a3ef56e803c33bc49b72c0166d 100644 (file)
@@ -40,6 +40,8 @@ extern void vga_io_put(int board, int portnum, uae_u8 v);
 extern uae_u8 vga_io_get(int board, int portnum);
 extern void vga_ram_put(int board, int offset, uae_u8 v);
 extern uae_u8 vga_ram_get(int board, int offset);
+extern void vgalfb_ram_put(int board, int offset, uae_u8 v);
+extern uae_u8 vgalfb_ram_get(int board, int offset);
 
 void gfxboard_get_a8_vram(int index);
 void gfxboard_free_vram(int index);
index 47dec3f66fe874b62f70ec635552e01be2237fac..fe6a23d1f84a3a98499f0e40e581881899045a8e 100644 (file)
@@ -67,8 +67,6 @@ void x86_ide_hd_put(int portnum, uae_u16 v, int);
 uae_u16 x86_ide_hd_get(int portnum, int);
 bool x86_at_hd_init_1(struct autoconfig_info *aci);
 void x86_add_at_hd_unit_1(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
-bool x86_at_hd_init_2(struct autoconfig_info *aci);
-void x86_add_at_hd_unit_2(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 bool x86_at_hd_init_xt(struct autoconfig_info *aci);
 void x86_add_at_hd_unit_xt(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 
index 0e2cc30c462d959be3399e20661741d104245150..3e49e9e6d1ad04469db5a507a406549ddb23db68 100644 (file)
@@ -797,9 +797,6 @@ extern bool can_cpu_tracer (void);
 #define CPU_HALT_SSP_IN_NON_EXISTING_ADDRESS 10
 #define CPU_HALT_INVALID_START_ADDRESS 11
 
-bool execute_other_cpu(int until);
-void execute_other_cpu_single(void);
-
 uae_u32 process_cpu_indirect_memory_read(uae_u32 addr, int size);
 void process_cpu_indirect_memory_write(uae_u32 addr, uae_u32 data, int size);
 
index 6c988b961f8c1e7aee17299a8d4a782ee42ef44e..b93dddb5a23e079364b9141a914d9b19478f93e5 100644 (file)
@@ -176,6 +176,8 @@ extern int decode_cloanto_rom_do (uae_u8 *mem, int size, int real_size);
 #define ROMTYPE_ALF3           0x00100072
 #define ROMTYPE_FASTTRAK       0x00100073
 #define ROMTYPE_CDTVSRAM       0x00100074
+#define ROMTYPE_SBISA          0x00100075
+#define ROMTYPE_X86MOUSE       0x00100076
 
 #define ROMTYPE_NOT                    0x00800000
 #define ROMTYPE_QUAD           0x01000000
index 7c1d9ddbfa4485627afa68510ed679cc62bcb3f3..ca5af70d47d380c01c7afc79f653ed3cbc218aea 100644 (file)
@@ -13,13 +13,13 @@ void x86_bridge_reset(void);
 void x86_bridge_free(void);
 void x86_bridge_rethink(void);
 void x86_bridge_sync_change(void);
+void x86_update_sound(double);
+void x86_mouse(int port, int x, int y, int z, int b);
 
 #define X86_STATE_INACTIVE 0
 #define X86_STATE_STOP 1
 #define X86_STATE_ACTIVE 2
 
 int is_x86_cpu(struct uae_prefs*);
-void x86_bridge_execute_until(int until);
-extern bool x86_turbo_on;
 
 #endif /* UAE_X86_H */
index 57aed7673d31b4339d7eb018453f822e8f5c4674..e3c4abbb86318bbdaa39171afbd2cbeacd478d6a 100644 (file)
@@ -49,6 +49,7 @@
 #include "zfile.h"
 #include "cia.h"
 #include "autoconf.h"
+#include "x86.h"
 #ifdef RETROPLATFORM
 #include "rp.h"
 #endif
@@ -2930,6 +2931,8 @@ static int getbuttonstate (int joy, int button)
        return (joybutton[joy] & (1 << button)) ? 1 : 0;
 }
 
+static int pc_mouse_buttons[MAX_JPORTS];
+
 static int getvelocity (int num, int subnum, int pct)
 {
        int val;
@@ -3042,6 +3045,20 @@ static void mouseupdate (int pct, bool vsync)
                        if (!mouse_deltanoreset[i][2])
                                mouse_delta[i][2] = 0;
 
+                       if (getbuttonstate(i, JOYBUTTON_1))
+                               pc_mouse_buttons[i] |= 1;
+                       else
+                               pc_mouse_buttons[i] &= ~1;
+                       if (getbuttonstate(i, JOYBUTTON_2))
+                               pc_mouse_buttons[i] |= 2;
+                       else
+                               pc_mouse_buttons[i] &= ~2;
+                       if (getbuttonstate(i, JOYBUTTON_3))
+                               pc_mouse_buttons[i] |= 4;
+                       else
+                               pc_mouse_buttons[i] &= ~4;
+                       x86_mouse(i, v1, v2, v3, pc_mouse_buttons[i]);
+
 #if OUTPUTDEBUG
                        if (v1 || v2) {
                                TCHAR xx1[256];
@@ -5155,6 +5172,9 @@ void inputdevice_reset (void)
                lastmxy_abs[i][0] = 0;
                lastmxy_abs[i][1] = 0;
        }
+       for (int i = 0; i < MAX_JPORTS; i++) {
+               pc_mouse_buttons[i] = 0;
+       }
        lightpen_trigger2 = 0;
        cubo_flag = 0;
        alg_flag &= 1;
index 8c048ec69ad110d64b64172b6b90ea4c76627319..9d4ad58cdaafe10c87ba1ff74c61292ebfb928aa 100644 (file)
--- a/main.cpp
+++ b/main.cpp
@@ -742,6 +742,10 @@ void fixup_prefs (struct uae_prefs *p, bool userconfig)
        if (p->tod_hack && p->cs_ciaatod == 0)
                p->cs_ciaatod = p->ntscmode ? 2 : 1;
 
+       // PCem does not support max speed.
+       if (p->x86_speed_throttle < 0)
+               p->x86_speed_throttle = 0;
+
        built_in_chipset_prefs (p);
        blkdev_fix_prefs (p);
        inputdevice_fix_prefs(p, userconfig);
index 4cd135478b392fd33776a6f0c3a0f139f288288c..42faa1b5f382a7b0ef6a5cabb0733b0d555b03b0 100644 (file)
@@ -4466,27 +4466,6 @@ void safe_interrupt_set(int num, int id, bool i6)
        }
 }
 
-void execute_other_cpu_single(void)
-{
-#ifdef WITH_X86
-       if (!x86_turbo_on)
-               return;
-       x86_bridge_execute_until(0);
-#endif
-}
-
-bool execute_other_cpu(int until)
-{
-#ifdef WITH_X86
-       if (!x86_turbo_on)
-               return false;
-       if (!until)
-               until++;
-       x86_bridge_execute_until(until);
-#endif
-       return true;
-}
-
 int cpu_sleep_millis(int ms)
 {
        int ret = 0;
@@ -4496,11 +4475,11 @@ int cpu_sleep_millis(int ms)
                uae_ppc_spinlock_release();
 #endif
 #ifdef WITH_X86
-       if (x86_turbo_on) {
-               execute_other_cpu(read_processor_time() + vsynctimebase / 20);
-       } else {
+//     if (x86_turbo_on) {
+//             execute_other_cpu(read_processor_time() + vsynctimebase / 20);
+//     } else {
                ret = sleep_millis_main(ms);
-       }
+//     }
 #endif
 #ifdef WITH_PPC
        if (state)
index 22b5162ce44b5379c3b391f0f4a51388eb918be7..56dbc840c85827aec25e80ea864fe98ac4401777 100644 (file)
@@ -2695,14 +2695,14 @@ static void getcreatefloppytype(HWND hDlg, drive_type *atype, int *hd)
                *atype = DRV_35_HD;
                break;
        case 2:
-               *atype = DRV_PC_ONLY_80;
+               *atype = DRV_PC_35_ONLY_80;
                break;
        case 3:
-               *atype = DRV_PC_ONLY_80;
+               *atype = DRV_PC_35_ONLY_80;
                *hd = 1;
                break;
        case 4:
-               *atype = DRV_PC_ONLY_40;
+               *atype = DRV_PC_525_ONLY_40;
                break;
        }
 }
@@ -11783,8 +11783,8 @@ static void enable_for_cpudlg (HWND hDlg)
 
        SendDlgItemMessage(hDlg, IDC_SPEED, TBM_SETRANGE, TRUE, workprefs.m68k_speed < 0 || (workprefs.cpu_memory_cycle_exact && !workprefs.cpu_cycle_exact) ? MAKELONG(-9, 0) : MAKELONG(-9, 50));
        SendDlgItemMessage(hDlg, IDC_SPEED, TBM_SETPAGESIZE, 0, 1);
-       SendDlgItemMessage(hDlg, IDC_SPEED_x86, TBM_SETRANGE, TRUE, MAKELONG(-1, 100));
-       SendDlgItemMessage(hDlg, IDC_SPEED_x86, TBM_SETPAGESIZE, 0, 1);
+       SendDlgItemMessage(hDlg, IDC_SPEED_x86, TBM_SETRANGE, TRUE, MAKELONG(0, 1000));
+       SendDlgItemMessage(hDlg, IDC_SPEED_x86, TBM_SETPAGESIZE, 0, 10);
 }
 
 static double getcpufreq (int m)
@@ -11801,14 +11801,12 @@ static void values_to_cpudlg (HWND hDlg)
        int cpu;
 
        SendDlgItemMessage(hDlg, IDC_SPEED_x86, TBM_SETPOS, TRUE, (int)(workprefs.x86_speed_throttle / 100));
-       if (workprefs.x86_speed_throttle < 0)
-               _tcscpy(buffer, _T("Max"));
-       else
-               _stprintf(buffer, _T("%+d%%"), (int)(workprefs.x86_speed_throttle / 10));
+       _stprintf(buffer, _T("%+d%%"), (int)(workprefs.x86_speed_throttle / 10));
        SetDlgItemText(hDlg, IDC_CPUTEXT_x86, buffer);
 
        SendDlgItemMessage (hDlg, IDC_SPEED, TBM_SETPOS, TRUE, (int)(workprefs.m68k_speed_throttle / 100));
        _stprintf (buffer, _T("%+d%%"), (int)(workprefs.m68k_speed_throttle / 10));
+
        SetDlgItemText (hDlg, IDC_CPUTEXT, buffer);
        CheckDlgButton (hDlg, IDC_COMPATIBLE, workprefs.cpu_compatible);
        CheckDlgButton (hDlg, IDC_COMPATIBLE24, workprefs.address_space_24);
@@ -14729,7 +14727,7 @@ static void addcdtype (HWND hDlg, int id)
 
 static int fromdfxtype(int dfx)
 {
-       if (dfx == 6)
+       if (dfx == 7)
                dfx = 3;
        else if (dfx >= 3)
                dfx++;
@@ -14741,12 +14739,21 @@ static int todfxtype(int val)
 {
        val--;
        if (val == 3)
-               val = 6;
+               val = 7;
        else if (val > 3)
                val--;
        return val;
 }
 
+static int swapdrives(int v)
+{
+       if (v == 7)
+               v = 8;
+       else if (v == 8)
+               v = 7;
+       return v;
+}
+
 static void addfloppytype (HWND hDlg, int n)
 {
        int state, chk;
@@ -14810,8 +14817,9 @@ static void addfloppytype (HWND hDlg, int n)
                state = FALSE;
        else
                state = TRUE;
-       if (f_type >= 0)
-               SendDlgItemMessage (hDlg, f_type, CB_SETCURSEL, nn, 0);
+       if (f_type >= 0) {
+               SendDlgItemMessage(hDlg, f_type, CB_SETCURSEL, swapdrives(nn), 0);
+       }
        if (f_si >= 0) {
                TCHAR *path = DISK_get_saveimagepath(text, -2);
                ShowWindow (GetDlgItem(hDlg, f_si), !showcd && zfile_exists (path) ? SW_SHOW : SW_HIDE);
@@ -14832,7 +14840,7 @@ static void addfloppytype (HWND hDlg, int n)
                CheckDlgButton (hDlg, f_enable, state ? BST_CHECKED : BST_UNCHECKED);
                TCHAR tmp[10];
                tmp[0] = 0;
-               if (n < 2 || ((nn - 1 != 5) && (nn  - 1 != 6))) {
+               if (n < 2 || ((nn - 1 != 5) && (nn  - 1 != 6) && ( nn - 1 != 7))) {
                        if (!showcd || n != 1)
                                _stprintf(tmp, _T("DF%d:"), n);
                } else {
@@ -14860,6 +14868,8 @@ static void getfloppytype (HWND hDlg, int n)
        int f_type = floppybuttons[n][3];
        LRESULT val = SendDlgItemMessage (hDlg, f_type, CB_GETCURSEL, 0, 0L);
 
+       val = swapdrives(val);
+
        if (val != CB_ERR && workprefs.floppyslots[n].dfxtype != todfxtype(val)) {
                workprefs.floppyslots[n].dfxtype = todfxtype(val);
                addfloppytype (hDlg, n);
@@ -15078,8 +15088,9 @@ static INT_PTR CALLBACK FloppyDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARA
                                SendDlgItemMessage (hDlg, f_type, CB_ADDSTRING, 0, (LPARAM)_T("5.25\" (80)"));
                                SendDlgItemMessage (hDlg, f_type, CB_ADDSTRING, 0, (LPARAM)ft35ddescom);
                                if (i >= 2) {
-                                       SendDlgItemMessage(hDlg, f_type, CB_ADDSTRING, 0, (LPARAM)_T("PC Bridge (40)"));
-                                       SendDlgItemMessage(hDlg, f_type, CB_ADDSTRING, 0, (LPARAM)_T("PC Bridge (80)"));
+                                       SendDlgItemMessage(hDlg, f_type, CB_ADDSTRING, 0, (LPARAM)_T("Bridge 5.25\" 40"));
+                                       SendDlgItemMessage(hDlg, f_type, CB_ADDSTRING, 0, (LPARAM)_T("Bridge 5.25\" 80"));
+                                       SendDlgItemMessage(hDlg, f_type, CB_ADDSTRING, 0, (LPARAM)_T("Bridge 3.5\"  80"));
                                }
                        }
                        setmultiautocomplete (hDlg, df0texts);
index 32e08070a98480c5b3a4b6e531b3ed564af45d00..43e11cf3d3aede672d5ffed293daee137cfcc377 100644 (file)
     <ClCompile Include="..\..\def_icons.cpp" />
     <ClCompile Include="..\..\devices.cpp" />
     <ClCompile Include="..\..\dlopen.cpp" />
-    <ClCompile Include="..\..\dosbox\cmos.cpp" />
-    <ClCompile Include="..\..\dosbox\core_full.cpp" />
-    <ClCompile Include="..\..\dosbox\core_normal.cpp" />
-    <ClCompile Include="..\..\dosbox\core_simple.cpp" />
-    <ClCompile Include="..\..\dosbox\cpu.cpp" />
-    <ClCompile Include="..\..\dosbox\db_memory.cpp" />
-    <ClCompile Include="..\..\dosbox\flags.cpp" />
-    <ClCompile Include="..\..\dosbox\fpu.cpp" />
-    <ClCompile Include="..\..\dosbox\keyboard.cpp" />
-    <ClCompile Include="..\..\dosbox\modrm.cpp" />
-    <ClCompile Include="..\..\dosbox\paging.cpp" />
-    <ClCompile Include="..\..\dosbox\pic.cpp" />
-    <ClCompile Include="..\..\dosbox\timer.cpp" />
     <ClCompile Include="..\..\ethernet.cpp" />
     <ClCompile Include="..\..\events.cpp" />
-    <ClCompile Include="..\..\fake86_cpu.cpp" />
     <ClCompile Include="..\..\flashrom.cpp" />
     <ClCompile Include="..\..\fpp_native.cpp" />
     <ClCompile Include="..\..\fpp_softfloat.cpp" />
     <ClCompile Include="..\..\mame\tm34010\tms34010.cpp" />
     <ClCompile Include="..\..\ncr9x_scsi.cpp" />
     <ClCompile Include="..\..\newcpu_common.cpp" />
+    <ClCompile Include="..\..\pcem\386.cpp" />
+    <ClCompile Include="..\..\pcem\386_dynarec.cpp" />
+    <ClCompile Include="..\..\pcem\808x.cpp" />
+    <ClCompile Include="..\..\pcem\cpu.cpp" />
+    <ClCompile Include="..\..\pcem\dma.cpp" />
+    <ClCompile Include="..\..\pcem\dosbox\dbopl.cpp" />
+    <ClCompile Include="..\..\pcem\dosbox\nukedopl.cpp" />
+    <ClCompile Include="..\..\pcem\keyboard.cpp" />
+    <ClCompile Include="..\..\pcem\keyboard_at.cpp" />
+    <ClCompile Include="..\..\pcem\mem.cpp" />
+    <ClCompile Include="..\..\pcem\mouse_ps2.cpp" />
+    <ClCompile Include="..\..\pcem\mouse_serial.cpp" />
+    <ClCompile Include="..\..\pcem\pcemglue.cpp" />
+    <ClCompile Include="..\..\pcem\pcemnvr.cpp" />
+    <ClCompile Include="..\..\pcem\pcemrtc.cpp" />
+    <ClCompile Include="..\..\pcem\pic.cpp" />
+    <ClCompile Include="..\..\pcem\pit.cpp" />
+    <ClCompile Include="..\..\pcem\serial.cpp" />
+    <ClCompile Include="..\..\pcem\sound_cms.cpp" />
+    <ClCompile Include="..\..\pcem\sound_dbopl.cpp" />
+    <ClCompile Include="..\..\pcem\sound_mpu401_uart.cpp" />
+    <ClCompile Include="..\..\pcem\sound_opl.cpp" />
+    <ClCompile Include="..\..\pcem\sound_sb.cpp" />
+    <ClCompile Include="..\..\pcem\sound_sb_dsp.cpp" />
+    <ClCompile Include="..\..\pcem\sound_speaker.cpp" />
+    <ClCompile Include="..\..\pcem\timer.cpp" />
+    <ClCompile Include="..\..\pcem\x86seg.cpp" />
+    <ClCompile Include="..\..\pcem\x87.cpp" />
     <ClCompile Include="..\..\pci.cpp" />
     <ClCompile Include="..\..\ppc\ppc.cpp" />
     <ClCompile Include="..\..\ppc\ppcd.cpp" />
index 64828597019e8accd1de4cdbcd23f403ccf7ab79..58ec397670835faf558e73727cbc5bc8927a751f 100644 (file)
     <ClCompile Include="..\..\mame\a2410.cpp">
       <Filter>mame</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\dosbox\core_normal.cpp">
-      <Filter>x86</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\dosbox\cpu.cpp">
-      <Filter>x86</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\dosbox\flags.cpp">
-      <Filter>x86</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\dosbox\paging.cpp">
-      <Filter>x86</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\dosbox\core_full.cpp">
-      <Filter>x86</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\dosbox\core_simple.cpp">
-      <Filter>x86</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\dosbox\modrm.cpp">
-      <Filter>x86</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\dosbox\cmos.cpp">
-      <Filter>x86</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\dosbox\keyboard.cpp">
-      <Filter>x86</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\dosbox\db_memory.cpp">
-      <Filter>x86</Filter>
-    </ClCompile>
     <ClCompile Include="..\..\x86.cpp">
       <Filter>x86</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\dosbox\pic.cpp">
-      <Filter>x86</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\dosbox\fpu.cpp">
-      <Filter>x86</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\dosbox\timer.cpp">
-      <Filter>x86</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\fake86_cpu.cpp">
-      <Filter>x86</Filter>
-    </ClCompile>
     <ClCompile Include="..\..\vm.cpp">
       <Filter>common</Filter>
     </ClCompile>
     <ClCompile Include="..\machdep\m68k.cpp">
       <Filter>common</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\pcem\386.cpp">
+      <Filter>x86</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\pcem\808x.cpp">
+      <Filter>x86</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\pcem\cpu.cpp">
+      <Filter>x86</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\pcem\keyboard.cpp">
+      <Filter>x86</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\pcem\keyboard_at.cpp">
+      <Filter>x86</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\pcem\mem.cpp">
+      <Filter>x86</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\pcem\pcemglue.cpp">
+      <Filter>x86</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\pcem\pcemnvr.cpp">
+      <Filter>x86</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\pcem\pcemrtc.cpp">
+      <Filter>x86</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\pcem\pic.cpp">
+      <Filter>x86</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\pcem\pit.cpp">
+      <Filter>x86</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\pcem\timer.cpp">
+      <Filter>x86</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\pcem\x86seg.cpp">
+      <Filter>x86</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\pcem\x87.cpp">
+      <Filter>x86</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\pcem\sound_speaker.cpp">
+      <Filter>x86</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\pcem\dma.cpp">
+      <Filter>x86</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\pcem\sound_sb.cpp">
+      <Filter>x86</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\pcem\sound_sb_dsp.cpp">
+      <Filter>x86</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\pcem\sound_opl.cpp">
+      <Filter>x86</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\pcem\sound_dbopl.cpp">
+      <Filter>x86</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\pcem\dosbox\dbopl.cpp">
+      <Filter>x86</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\pcem\dosbox\nukedopl.cpp">
+      <Filter>x86</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\pcem\sound_cms.cpp">
+      <Filter>x86</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\pcem\sound_mpu401_uart.cpp">
+      <Filter>x86</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\pcem\mouse_serial.cpp">
+      <Filter>x86</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\pcem\serial.cpp">
+      <Filter>x86</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\pcem\386_dynarec.cpp">
+      <Filter>x86</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\pcem\mouse_ps2.cpp">
+      <Filter>x86</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <None Include="..\resources\35floppy.ico">
diff --git a/pcem/pcemglue.cpp b/pcem/pcemglue.cpp
new file mode 100644 (file)
index 0000000..944c474
--- /dev/null
@@ -0,0 +1,280 @@
+
+#include "uae.h"
+#include "ibm.h"
+#include "pit.h"
+#include "pic.h"
+#include "cpu.h"
+#include "model.h"
+#include "x86.h"
+#include "x86_ops.h"
+#include "codegen.h"
+#include "timer.h"
+#include "sound.h"
+#include "sound_mpu401_uart.h"
+
+#ifdef _WIN32
+#include <windows.h>
+#include "midi.h"
+#endif
+
+#include "pcemglue.h"
+
+#include "sysconfig.h"
+#include "sysdeps.h"
+
+PIT pit, pit2;
+PIC pic, pic2;
+dma_t dma[8];
+int AT;
+
+int ppispeakon;
+float CGACONST;
+float MDACONST;
+float VGACONST1, VGACONST2;
+float RTCCONST;
+int gated, speakval, speakon;
+
+PPI ppi;
+
+cpu_state_s cpu_state;
+
+
+int codegen_flags_changed;
+uint32_t codegen_endpc;
+int codegen_in_recompile;
+int codegen_flat_ds, codegen_flat_ss;
+uint32_t recomp_page;
+codeblock_t **codeblock_hash;
+
+void codegen_reset(void)
+{
+}
+void codegen_block_init(unsigned int)
+{
+}
+void codegen_block_remove()
+{
+}
+void codegen_block_start_recompile(struct codeblock_t *)
+{
+}
+void codegen_block_end_recompile(struct codeblock_t *)
+{
+}
+void codegen_block_end()
+{
+}
+void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_pc, uint32_t old_pc)
+{
+}
+void codegen_check_flush(struct page_t *page, uint64_t mask, uint32_t phys_addr)
+{
+}
+void codegen_flush(void)
+{
+}
+void codegen_init(void)
+{
+}
+
+void pclog(char const *format, ...)
+{
+       va_list parms;
+       va_start(parms, format);
+       char buf[256];
+       vsprintf(buf, format, parms);
+       write_log("PCEMLOG: %s", buf);
+       va_end(parms);
+}
+
+extern void activate_debugger(void);
+void fatal(char const *format, ...)
+{
+       va_list parms;
+       va_start(parms, format);
+       char buf[256];
+       vsprintf(buf, format, parms);
+       write_log("PCEMFATAL: %s", buf);
+       va_end(parms);
+       activate_debugger();
+}
+
+void video_updatetiming(void)
+{
+       write_log(_T("video_updatetiming\n"));
+}
+
+void device_speed_changed(void)
+{
+       write_log(_T("device_speed_changed\n"));
+}
+
+union CR0_s CR0;
+
+int model;
+int cpuspeed;
+int CPUID;
+int insc;
+int hasfpu;
+int romset;
+int nmi_mask;
+int use32;
+int stack32;
+uint32_t cr2, cr3, cr4;
+uint32_t rammask;
+uintptr_t *readlookup2;
+uintptr_t *writelookup2;
+uint16_t flags, eflags;
+x86seg gdt, ldt, idt, tr;
+x86seg _cs, _ds, _es, _ss, _fs, _gs;
+x86seg _oldds;
+int writelookup[256], writelookupp[256];
+int readlookup[256], readlookupp[256];
+int readlnext;
+int writelnext;
+int pccache;
+unsigned char *pccache2;
+int cpl_override;
+uint32_t oldds, oldss, olddslimit, oldsslimit, olddslimitw, oldsslimitw;
+int pci_burst_time, pci_nonburst_time;
+int optype;
+uint32_t oxpc;
+char *logs_path;
+uint32_t ealimit, ealimitw;
+
+uint32_t x87_pc_off, x87_op_off;
+uint16_t x87_pc_seg, x87_op_seg;
+
+uint32_t dr[8];
+
+int xi8088_bios_128kb(void)
+{
+       return 0;
+}
+
+uint8_t portin(uint16_t portnum);
+uint8_t inb(uint16_t port)
+{
+       return portin(port);
+}
+
+void portout(uint16_t, uint8_t);
+void outb(uint16_t port, uint8_t v)
+{
+       portout(port, v);
+}
+uint16_t portin16(uint16_t portnum);
+uint16_t inw(uint16_t port)
+{
+       return portin16(port);
+}
+void portout16(uint16_t portnum, uint16_t value);
+void outw(uint16_t port, uint16_t val)
+{
+       portout16(port, val);
+}
+uint32_t portin32(uint16_t portnum);
+uint32_t inl(uint16_t port)
+{
+       return portin32(port);
+}
+void portout32(uint16_t portnum, uint32_t value);
+void outl(uint16_t port, uint32_t val)
+{
+       portout32(port, val);
+}
+
+
+static void model_init(void)
+{
+
+}
+
+int AMSTRAD;
+int TANDY;
+int keybsenddelay;
+int mouse_buttons;
+int mouse_type;
+int pcem_key[272];
+
+int mouse_get_type(int mouse_type)
+{
+       return 0;
+}
+
+void t3100e_notify_set(unsigned char v)
+{
+
+}
+void t3100e_display_set(unsigned char v)
+{
+
+}
+void t3100e_turbo_set(unsigned char v)
+{
+
+}
+void t3100e_mono_set(unsigned char v)
+{
+
+}
+uint8_t t3100e_display_get()
+{
+       return 0;
+}
+uint8_t t3100e_config_get()
+{
+       return 0;
+}
+uint8_t t3100e_mono_get()
+{
+       return 0;
+}
+void xi8088_turbo_set(unsigned char v)
+{
+
+}
+uint8_t xi8088_turbo_get()
+{
+       return 0;
+}
+
+void ps2_cache_clean(void)
+{
+
+}
+
+int video_is_mda()
+{
+       return 0;
+}
+
+MODEL models[] =
+{
+       { "[8088] Generic XT clone", ROM_GENXT, "genxt", { { "", cpus_8088 }, { "", NULL }, { "", NULL } }, MODEL_GFX_NONE, 32, 704, 16, model_init, NULL },
+       { "[286] AMI 286 clone", ROM_AMI286, "ami286", { { "", cpus_286 }, { "", NULL }, { "", NULL } }, MODEL_GFX_NONE | MODEL_AT | MODEL_HAS_IDE, 512, 16384, 128, model_init, NULL },
+       { "[386SX] AMI 386SX clone", ROM_AMI386SX, "ami386", { { "386SX", cpus_i386SX }, { "386DX", cpus_i386DX }, { "486", cpus_i486 } }, MODEL_GFX_NONE | MODEL_AT | MODEL_HAS_IDE, 512, 16384, 128, model_init, NULL },
+};
+
+int rom_present(char *s)
+{
+       return 0;
+}
+static int midi_open;
+
+void midi_write(uint8_t v)
+{
+       if (!midi_open) {
+               midi_open = Midi_Open();
+       }
+       Midi_Parse(midi_output, &v);
+}
+
+void pcem_close(void)
+{
+       if (midi_open)
+               Midi_Close();
+       midi_open = 0;
+}
+
+// void (*code)() = (void(*)(void))&block->data[BLOCK_START];
diff --git a/pcem/pcemglue.h b/pcem/pcemglue.h
new file mode 100644 (file)
index 0000000..41cea2c
--- /dev/null
@@ -0,0 +1,13 @@
+
+extern void pcem_close(void);
+
+uint8_t keyboard_at_read(uint16_t port, void *priv);
+uint8_t mem_read_romext(uint32_t addr, void *priv);
+uint16_t mem_read_romextw(uint32_t addr, void *priv);
+uint32_t mem_read_romextl(uint32_t addr, void *priv);
+
+void sound_speed_changed(void);
+extern int SOUNDBUFLEN;
+extern int32_t *x86_sndbuffer[2];
+extern bool x86_sndbuffer_filled[2];
+
index fa12e85643ab979f614fc05aa53c55b95fde2a4f..de66a825106c7f34306f9f901dfe76c9fefef4f7 100644 (file)
@@ -1219,7 +1219,7 @@ static void cirrus_valid_memory_config(CirrusVGAState *s)
                // Amiga CyberGraphX uses this to detect memory size
                // by writing long and then reading it back, if SRF[7]
                // set and test value reads correct: memory size = 2M.
-               if (s->vga.vram_size_mb == 2 && !(s->vga.sr[0xf] & 0x80))
+               if (!s->x86vga && s->vga.vram_size_mb == 2 && !(s->vga.sr[0xf] & 0x80))
                        s->valid_memory_config = 0;
        } else if (s->device_id >= CIRRUS_ID_CLGD5434) {
                // SRF[7] must be set for 4M VRAM size
@@ -1360,7 +1360,8 @@ static void cirrus_vga_write_sr(CirrusVGAState * s, uint32_t val)
        cirrus_valid_memory_config(s);
        break;          
        case 0x07:                      // Extended Sequencer Mode
-    cirrus_update_memory_access(s);
+       s->vga.sr[s->vga.sr_index] = val;
+       cirrus_update_memory_access(s);
     case 0x08:                 // EEPROM Control
     case 0x09:                 // Scratch Register 0
     case 0x0a:                 // Scratch Register 1
@@ -2533,11 +2534,15 @@ static void unmap_linear_vram(CirrusVGAState *s)
 }
 
 /* Compute the memory access functions */
+extern void x86_map_lfb(int);
 static void cirrus_update_memory_access(CirrusVGAState *s)
 {
     unsigned mode;
 
-    memory_region_transaction_begin();
+       if (s->x86vga)
+               x86_map_lfb(s->vga.sr[7] >> 4);
+
+       memory_region_transaction_begin();
     if ((s->vga.sr[0x17] & 0x44) == 0x44) {
         goto generic_io;
     } else if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
@@ -2942,7 +2947,7 @@ static const MemoryRegionOps cirrus_vga_io_ops = {
 
 void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci,
                                MemoryRegion *system_memory,
-                               MemoryRegion *system_io, int vramlimit)
+                               MemoryRegion *system_io, int vramlimit, bool x86vga)
 {
     int i;
     static int inited;
@@ -3031,6 +3036,8 @@ void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci,
     s->cirrus_addr_mask = s->real_vram_size - 1;
     s->linear_mmio_mask = s->real_vram_size - 256;
 
+       s->x86vga = x86vga;
+
     s->vga.get_bpp = cirrus_get_bpp;
     s->vga.get_offsets = cirrus_get_offsets;
     s->vga.get_resolution = cirrus_get_resolution;
index ba3448fecad0cfe9bcfc002ee750231207b17478..6e61256092d3e91ab44fac2f239ee5a17d3d47f5 100644 (file)
@@ -234,6 +234,7 @@ void qemu_register_reset(QEMUResetHandler *func, void *opaque);
 #define CIRRUS_ID_CLGD5426  (0x24<<2)
 #define CIRRUS_ID_CLGD5424  (0x25<<2)
 #define CIRRUS_ID_CLGD5428  (0x26<<2)
+#define CIRRUS_ID_CLGD5429  (0x27<<2)
 #define CIRRUS_ID_CLGD5430  (0x28<<2)
 #define CIRRUS_ID_CLGD5434  (0x2A<<2)
 #define CIRRUS_ID_CLGD5436  (0x2B<<2)
@@ -301,11 +302,12 @@ struct CirrusVGAState {
     int device_id;
     int bustype;
        int valid_memory_config;
+       bool x86vga;
 };
 
 void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci,
                                MemoryRegion *system_memory,
-                               MemoryRegion *system_io, int vramlimit);
+                               MemoryRegion *system_io, int vramlimit, bool x86vga);
 
 struct DeviceState
 {
diff --git a/x86.cpp b/x86.cpp
index 56879b3aa04f2cc9b28712233853363b083976a1..3fc22bbaacca41d94cdc274bf6eb52da3271c97b 100644 (file)
--- a/x86.cpp
+++ b/x86.cpp
@@ -8,6 +8,8 @@
 * 8088 x86 and PC support chip emulation from Fake86.
 * 80286+ CPU and AT support chip emulation from DOSBox.
 *
+* 2018: Replaced Fake86 and DOSBox with PCem.
+*
 */
 
 #define X86_DEBUG_BRIDGE 1
@@ -16,6 +18,7 @@
 #define X86_DEBUG_BRIDGE_IRQ 0
 #define X86_IO_PORT_DEBUG 0
 #define X86_DEBUG_SPECIAL_IO 0
+#define FLOPPY_DEBUG 0
 
 #define DEBUG_DMA 0
 #define DEBUG_PIT 0
 #include "gfxboard.h"
 #include "pci_hw.h"
 #include "devices.h"
-
-#include "dosbox/dosbox.h"
-#include "dosbox/mem.h"
-#include "dosbox/paging.h"
-#include "dosbox/setup.h"
-#include "dosbox/cpu.h"
-#include "dosbox/pic.h"
-#include "dosbox/timer.h"
-typedef Bits(CPU_Decoder)(void);
-extern CPU_Decoder *cpudecoder;
-extern Bit32s CPU_Cycles;
+#include "audio.h"
+
+#include "pcem/ibm.h"
+#include "pcem/pic.h"
+#include "pcem/pit.h"
+#include "pcem/timer.h"
+#include "pcem/pcemglue.h"
+#include "pcem/model.h"
+#include "pcem/mem.h"
+#include "pcem/codegen.h"
+#include "pcem/x86.h"
+#include "pcem/nvr.h"
+#include "pcem/keyboard_at.h"
+#include "pcem/keyboard.h"
+#include "pcem/dma.h"
+#include "pcem/sound_speaker.h"
+#include "pcem/sound.h"
+#include "pcem/sound_cms.h"
+#include "pcem/mouse.h"
+#include "pcem/mouse_serial.h"
+extern int cpu;
+extern int nvrmask;
+void keyboard_at_write(uint16_t port, uint8_t val, void *priv);
+
+
+#define MAX_IO_PORT 0x400
+
+static uint8_t(*port_inb[MAX_IO_PORT])(uint16_t addr, void *priv);
+static uint16_t(*port_inw[MAX_IO_PORT])(uint16_t addr, void *priv);
+static uint32_t(*port_inl[MAX_IO_PORT])(uint16_t addr, void *priv);
+static void(*port_outb[MAX_IO_PORT])(uint16_t addr, uint8_t  val, void *priv);
+static void(*port_outw[MAX_IO_PORT])(uint16_t addr, uint16_t val, void *priv);
+static void(*port_outl[MAX_IO_PORT])(uint16_t addr, uint32_t val, void *priv);
+static void *port_priv[MAX_IO_PORT];
+
+static double x86_base_event_clock;
+static int x86_sndbuffer_playpos;
+static int x86_sndbuffer_playindex;
+static int sound_handlers_num;
+int sound_poll_time = 0, sound_poll_latch;
+void sound_poll(void *priv);
 
 #define TYPE_SIDECAR 0
 #define TYPE_2088 1
@@ -58,62 +91,37 @@ extern Bit32s CPU_Cycles;
 #define TYPE_2286 3
 #define TYPE_2386 4
 
-void exec86(uint32_t execloops);
-void reset86(int v20);
-void intcall86(uint8_t intnum);
-
 void x86_doirq(uint8_t irqnum);
 
-static frame_time_t last_cycles;
-#define DEFAULT_X86_INSTRUCTION_COUNT 120
-static int x86_instruction_count;
-static bool x86_turbo_allowed;
-static bool x86_turbo_enabled;
-bool x86_turbo_on;
 bool x86_cpu_active;
 
-void CPU_Init(Section*, int, int);
-void CPU_ShutDown(Section*);
-void CPU_JMP(bool use32, Bitu selector, Bitu offset, Bitu oldeip);
-void PAGING_Init(Section * sec);
-void MEM_Init(Section * sec);
-void MEM_ShutDown(Section * sec);
-void CMOS_Init(Section* sec, int);
-void CMOS_Destroy(Section* sec);
-void PIC_Init(Section* sec);
-void PIC_Destroy(Section* sec);
-void TIMER_Destroy(Section*);
-void TIMER_Init(Section* sec);
-void TIMER_SetGate2(bool);
-bool TIMER_GetGate2(void);
-static Section_prop *dosbox_sec;
-Bitu x86_in_keyboard(Bitu port);
-void x86_out_keyboard(Bitu port, Bitu val);
-void cmos_selreg(Bitu port, Bitu val, Bitu iolen);
-void cmos_writereg(Bitu port, Bitu val, Bitu iolen);
-Bitu cmos_readreg(Bitu port, Bitu iolen);
-void x86_pic_write(Bitu port, Bitu val);
-Bitu x86_pic_read(Bitu port);
-void x86_timer_write(Bitu port, Bitu val);
-Bitu x86_timer_read(Bitu port);
-void PIC_ActivateIRQ(Bitu irq);
-void PIC_DeActivateIRQ(Bitu irq);
-void PIC_runIRQs(void);
-void KEYBOARD_AddBuffer(Bit8u data);
-void FPU_Init(Section*);
-Bit8u *x86_cmos_regs(Bit8u *regs);
-void MEM_SetVGAHandler(void);
-Bit32s ticksDone;
-Bit32u ticksScheduled;
-HostPt mono_start, mono_end, color_start, color_end;
-int x86_memsize;
-int x86_biosstart;
-int x86_fpu_enabled;
+static int x86_vga_mode;
+static int x86_vga_board;
 int x86_cmos_bank;
-int x86_xrom_start[2];
-int x86_xrom_end[2];
-int x86_vga_mode;
-int x86_vga_board;
+
+static uae_u8 *xtiderom;
+
+int GAMEBLASTER = 1;
+int sound_pos_global;
+int SOUNDBUFLEN = 8192;
+static int32_t outbuffer1[MAXSOUNDBUFLEN * 2];
+static int32_t outbuffer2[MAXSOUNDBUFLEN * 2];
+static int x86_sndbuffer_index;
+static int32_t *x86_sndbuffer[2];
+static bool x86_sndbuffer_filled[2];
+bool ps2_mouse_supported;
+
+struct membase
+{
+       uae_u8 *base;
+       uae_u32 mask;
+};
+
+struct scamp_shadow
+{
+       mem_mapping_t r_map;
+       mem_mapping_t w_map;
+};
 
 struct x86_bridge
 {
@@ -122,11 +130,15 @@ struct x86_bridge
        int configured;
        int type;
        uaecptr baseaddress;
-       int pc_maxram;
        uae_u8 *pc_ram;
        uae_u8 *pc_rom;
        uae_u8 *io_ports;
        uae_u8 *amiga_io;
+       uae_u8 *amiga_parameter;
+       uae_u8 *amiga_buffer;
+       uae_u8 *amiga_mono;
+       uae_u8 *amiga_color;
+       int mode_register;
        bool x86_reset;
        bool amiga_irq;
        bool amiga_forced_interrupts;
@@ -136,24 +148,48 @@ struct x86_bridge
        int pc_maxbaseram;
        int bios_size;
        int settings;
-       int dosbox_cpu;
-       int dosbox_cpu_arch;
-       bool x86_reset_requested;
        struct zfile *cmosfile;
        uae_u8 cmosregs[3 * 0x40];
-       uae_u8 vlsi_regs[0x100];
        int a2386_default_video;
+       bool pc_speaker;
        int cmossize;
-       int scamp_idx1, scamp_idx2;
-       uae_u8 rombank[1024 * 1024 / 4096];
-       float dosbox_vpos_tick;
-       float dosbox_tick_vpos_cnt;
        struct romconfig *rc;
        int vgaboard;
+       int vgaboard_vram;
        const struct pci_board *ne2000_isa;
        struct pci_board_state *ne2000_isa_board_state;
        int ne2000_io;
        int ne2000_irq;
+       mem_mapping_t sharedio_parameter;
+       struct membase sharedio_parameter_mb;
+       mem_mapping_t sharedio_mono;
+       struct membase sharedio_mono_mb;
+       mem_mapping_t sharedio_color;
+       struct membase sharedio_color_mb;
+       mem_mapping_t sharedio_buffer[3];
+       uae_u32 shared_io_addr;
+       struct membase sharedio_buffer_mb;
+       mem_mapping_t vgamem;
+       mem_mapping_t vgalfbmem;
+       int audstream;
+       int audeventtime;
+       bool sound_emu;
+       bool sound_initialized;
+       void *sb_base;
+       void *cms_base;
+       void *mouse_base;
+       int mouse_type;
+       int mouse_port;
+
+       struct scamp_shadow shadows[16];
+       mem_mapping_t ems[0x24];
+       int shadowvals[4];
+       int emsvals[0x24];
+       int sltptr;
+       int scamp_idx1, scamp_idx2;
+       uae_u8 vlsi_regs[0x100];
+       uae_u16 vlsi_regs_ems[64];
+       bool vlsi_config;
 };
 static int x86_found;
 
@@ -186,30 +222,22 @@ static struct x86_bridge *x86_bridge_alloc(void)
        return xb;
 };
 
-void x86_init_reset(void)
+static void reset_cpu(void)
 {
        struct x86_bridge *xb = bridges[0];
-       xb->x86_reset_requested = true;
-       write_log(_T("8042 CPU reset requested\n"));
-}
 
-static void reset_dosbox_cpu(void)
-{
-       struct x86_bridge *xb = bridges[0];
+       resetx86();
 
-       CPU_ShutDown(dosbox_sec);
-       CPU_Init(dosbox_sec, xb->dosbox_cpu, xb->dosbox_cpu_arch);
-       CPU_JMP(false, 0xffff, 0, 0);
+//     CPU_ShutDown(dosbox_sec);
+//     CPU_Init(dosbox_sec, xb->dosbox_cpu, xb->dosbox_cpu_arch);
+//     CPU_JMP(false, 0xffff, 0, 0);
 }
 
 static void reset_x86_cpu(struct x86_bridge *xb)
 {
        write_log(_T("x86 CPU reset\n"));
-       if (!xb->dosbox_cpu) {
-               reset86(xb->type == ROMTYPE_A2088T);
-       } else {
-               reset_dosbox_cpu();
-       }
+
+       reset_cpu();
        // reset x86 hd controllers
        x86_ide_hd_put(-1, 0, 0);
        x86_xt_hd_bput(-1, 0);
@@ -244,10 +272,62 @@ uint8_t x86_get_jumpers(void)
        return v;
 }
 
+
+static int get_shared_io(struct x86_bridge *xb)
+{
+       int opt = (xb->amiga_io[IO_MODE_REGISTER] >> 5) & 3;
+       // disk buffer
+       if (xb->type >= TYPE_2286) {
+               switch (opt)
+               {
+               case 1:
+                       return 0xa0000;
+               case 2:
+               default:
+                       return 0xd0000;
+               }
+       }
+       else {
+               switch (opt)
+               {
+               case 1:
+               default:
+                       return 0xa0000;
+               case 2:
+                       return 0xd0000;
+               case 3:
+                       return 0xe0000;
+               }
+       }
+}
+
+static void set_configurable_shared_io(struct x86_bridge *xb)
+{
+       if (get_shared_io(xb) == xb->shared_io_addr)
+               return;
+       xb->shared_io_addr = get_shared_io(xb);
+       mem_mapping_disable(&xb->sharedio_buffer[0]);
+       mem_mapping_disable(&xb->sharedio_buffer[1]);
+       mem_mapping_disable(&xb->sharedio_buffer[2]);
+       switch (xb->shared_io_addr)
+       {
+       case 0xa0000:
+               mem_mapping_enable(&xb->sharedio_buffer[0]);
+               break;
+       case 0xd0000:
+               mem_mapping_enable(&xb->sharedio_buffer[1]);
+               break;
+       case 0xe0000:
+               mem_mapping_enable(&xb->sharedio_buffer[2]);
+               break;
+       }
+       write_log(_T("Buffer IO = %08x\n"), xb->shared_io_addr);
+}
+
 static uae_u8 get_mode_register(struct x86_bridge *xb, uae_u8 v)
 {
        if (xb->type == TYPE_SIDECAR) {
-               // PC/XT + keyboard
+               // PC/XT + keyboard. Read-only.
                v = 0x84;
                if (!(xb->settings & (1 << 12)))
                        v |= 0x02;
@@ -260,12 +340,13 @@ static uae_u8 get_mode_register(struct x86_bridge *xb, uae_u8 v)
                if ((xb->settings & (1 << 11)))
                        v |= 0x40;
        } else if (xb->type < TYPE_2286) {
-               // PC/XT
+               // PC/XT (read-write)
                v |= 0x80;
        } else {
-               // AT
+               // AT (read-write)
                v &= ~0x80;
        }
+       set_configurable_shared_io(xb);
        return v;
 }
 
@@ -331,7 +412,7 @@ static uae_u8 x86_bridge_put_io(struct x86_bridge *xb, uaecptr addr, uae_u8 v)
 #endif
                        xb->io_ports[0x60] = v;
                        if (xb->type >= TYPE_2286) {
-                               KEYBOARD_AddBuffer(v);
+                               keyboard_send(v);
                        }
                }
                break;
@@ -352,6 +433,8 @@ static uae_u8 x86_bridge_put_io(struct x86_bridge *xb, uaecptr addr, uae_u8 v)
                        xb->a2386_default_video = v & 1;
                        write_log(_T("A2386 Default mode = %s\n"), xb->a2386_default_video ? _T("MDA") : _T("CGA"));
                }
+               if (v == 6 || v == 7)
+                       xb->pc_speaker = (v & 1) != 0;
                break;
 
                default:
@@ -427,145 +510,9 @@ static void set_interrupt(struct x86_bridge *xb, int bit)
        devices_rethink_all(x86_bridge_rethink);
 }
 
+#if 0
 /* 8237 and 8253 from fake86 with small modifications */
 
-#define PIT_MODE_LATCHCOUNT    0
-#define PIT_MODE_LOBYTE        1
-#define PIT_MODE_HIBYTE        2
-#define PIT_MODE_TOGGLE        3
-
-struct i8253_s {
-       uint16_t chandata[3];
-       uint8_t accessmode[3];
-       uint8_t bytetoggle[3];
-       uint32_t effectivedata[3];
-       float chanfreq[3];
-       uint8_t active[3];
-       uint16_t counter[3];
-};
-static struct i8253_s i8253;
-static uint16_t latched_val, latched;
-
-static uint64_t hostfreq = 313 * 50 * 227;
-static uint64_t tickgap, curtick, lasttick, lasti8253tick, i8253tickgap;
-
-static void inittiming()
-{
-       curtick = 0;
-       lasti8253tick = lasttick = curtick;
-       i8253tickgap = hostfreq / 119318;
-}
-
-static void timing(int count)
-{
-       struct x86_bridge *xb = bridges[0];
-
-       curtick += count;
-
-       if (i8253.active[0]) { //timer interrupt channel on i8253
-               if (curtick >= (lasttick + tickgap)) {
-                       lasttick = curtick;
-                       x86_doirq(0);
-               }
-       }
-
-       if (curtick >= (lasti8253tick + i8253tickgap)) {
-               for (int i8253chan = 0; i8253chan<3; i8253chan++) {
-                       bool cantrun = (i8253chan == 2 && !(xb->io_ports[0x61] & 1));
-                       if (i8253.active[i8253chan] && !cantrun) {
-                               if (i8253.counter[i8253chan] < 10)
-                                       i8253.counter[i8253chan] = i8253.chandata[i8253chan];
-                               i8253.counter[i8253chan] -= 10;
-                       }
-               }
-               lasti8253tick = curtick;
-       }
-}
-
-static void out8253(uint16_t portnum, uint8_t value)
-{
-       uint8_t curbyte;
-#if DEBUG_PIT
-       write_log("out8253(0x%X = %02x);\n", portnum, value);
-#endif
-       portnum &= 3;
-       switch (portnum)
-       {
-               case 0:
-               case 1:
-               case 2: //channel data
-               if ((i8253.accessmode[portnum] == PIT_MODE_LOBYTE) || ((i8253.accessmode[portnum] == PIT_MODE_TOGGLE) && (i8253.bytetoggle[portnum] == 0)))
-                       curbyte = 0;
-               else if ((i8253.accessmode[portnum] == PIT_MODE_HIBYTE) || ((i8253.accessmode[portnum] == PIT_MODE_TOGGLE) && (i8253.bytetoggle[portnum] == 1)))
-                       curbyte = 1;
-               if (curbyte == 0) { //low byte
-                       i8253.chandata[portnum] = (i8253.chandata[portnum] & 0xFF00) | value;
-               } else {   //high byte
-                       i8253.chandata[portnum] = (i8253.chandata[portnum] & 0x00FF) | ((uint16_t)value << 8);
-               }
-               if (i8253.chandata[portnum] == 0)
-                       i8253.effectivedata[portnum] = 65536;
-               else
-                       i8253.effectivedata[portnum] = i8253.chandata[portnum];
-               i8253.counter[portnum] = i8253.chandata[portnum];
-               i8253.active[portnum] = 1;
-               tickgap = (uint64_t)((float)hostfreq / (float)((float)1193182 / (float)i8253.effectivedata[0]));
-               if (i8253.accessmode[portnum] == PIT_MODE_TOGGLE)
-                       i8253.bytetoggle[portnum] = (~i8253.bytetoggle[portnum]) & 1;
-               i8253.chanfreq[portnum] = (float)((uint32_t)(((float) 1193182.0 / (float)i8253.effectivedata[portnum]) * (float) 1000.0)) / (float) 1000.0;
-               //printf("[DEBUG] PIT channel %u counter changed to %u (%f Hz)\n", portnum, i8253.chandata[portnum], i8253.chanfreq[portnum]);
-               break;
-               case 3: //mode/command
-               i8253.accessmode[value >> 6] = (value >> 4) & 3;
-               if (i8253.accessmode[value >> 6] == PIT_MODE_LATCHCOUNT) {
-                       latched_val = i8253.counter[value >> 6];
-                       latched = 2;
-               } else if (i8253.accessmode[value >> 6] == PIT_MODE_TOGGLE)
-                       i8253.bytetoggle[value >> 6] = 0;
-               break;
-       }
-}
-
-static uint8_t in8253(uint16_t portnum)
-{
-       uint8_t curbyte;
-       uint8_t out = 0;
-#if DEBUG_PIT
-       uint16_t portnum2 = portnum;
-#endif
-       portnum &= 3;
-       switch (portnum)
-       {
-               case 0:
-               case 1:
-               case 2: //channel data
-               if (latched == 2) {
-                       latched = 1;
-                       out = latched_val & 0xff;
-               } else if (latched == 1) {
-                       latched = 0;
-                       out = latched_val >> 8;
-               } else {
-                       if ((i8253.accessmode[portnum] == 0) || (i8253.accessmode[portnum] == PIT_MODE_LOBYTE) || ((i8253.accessmode[portnum] == PIT_MODE_TOGGLE) && (i8253.bytetoggle[portnum] == 0)))
-                               curbyte = 0;
-                       else if ((i8253.accessmode[portnum] == PIT_MODE_HIBYTE) || ((i8253.accessmode[portnum] == PIT_MODE_TOGGLE) && (i8253.bytetoggle[portnum] == 1)))
-                               curbyte = 1;
-                       if ((i8253.accessmode[portnum] == 0) || (i8253.accessmode[portnum] == PIT_MODE_TOGGLE))
-                               i8253.bytetoggle[portnum] = (~i8253.bytetoggle[portnum]) & 1;
-                       if (curbyte == 0) { //low byte
-                               out = ((uint8_t)i8253.counter[portnum]);
-                       } else {   //high byte
-                               out = ((uint8_t)(i8253.counter[portnum] >> 8));
-                       }
-               }
-               break;
-       }
-#if DEBUG_PIT
-       write_log("in8253(0x%X = %02x);\n", portnum2, out);
-#endif
-       return out;
-}
-
 struct dmachan_s {
        uint32_t page;
        uint32_t addr;
@@ -786,164 +733,25 @@ static uint8_t in8237(uint16_t addr)
 #endif
        return out;
 }
-
-static int keyboardwaitack;
-
-void x86_ack_keyboard(void)
-{
-       if (keyboardwaitack)
-               set_interrupt(bridges[0], 4);
-       keyboardwaitack = 0;
-}
-
-
-struct structpic {
-       uint8_t imr; //mask register
-       uint8_t irr; //request register
-       uint8_t isr; //service register
-       uint8_t icwstep; //used during initialization to keep track of which ICW we're at
-       uint8_t icw[5];
-       uint8_t intoffset; //interrupt vector offset
-       uint8_t priority; //which IRQ has highest priority
-       uint8_t autoeoi; //automatic EOI mode
-       uint8_t readmode; //remember what to return on read register from OCW3
-       uint8_t enabled;
-};
-
-static struct structpic i8259[2];
-
-static uint8_t in8259(uint16_t portnum)
-{
-       struct x86_bridge *xb = bridges[0];
-       uint8_t out = 0;
-
-       int chipnum = (portnum & 0x80) ? 1 : 0;
-       if (chipnum && xb->type < TYPE_2286)
-               return 0;
-       switch (portnum & 1) {
-               case 0:
-               if (i8259[chipnum].readmode == 0)
-                       out = (i8259[chipnum].irr);
-               else
-                       out = (i8259[chipnum].isr);
-               break;
-               case 1: //read mask register
-               out = (i8259[chipnum].imr);
-               break;
-       }
-#if DEBUG_INT
-       write_log("in8259(0x%X = %02x);\n", portnum, out);
-#endif
-       return out;
-}
-
-extern uint32_t makeupticks;
-
-void out8259(uint16_t portnum, uint8_t value)
-{
-       struct x86_bridge *xb = bridges[0];
-       uint8_t i;
-       int chipnum = (portnum & 0x80) ? 1 : 0;
-
-#if DEBUG_INT
-       write_log("out8259(0x%X = %02x);\n", portnum, value);
-#endif
-
-       if (chipnum && xb->type < TYPE_2286)
-               return;
-       switch (portnum & 1) {
-               case 0:
-               if (value & 0x10) { //begin initialization sequence
-                       i8259[chipnum].icwstep = 1;
-                       i8259[chipnum].imr = 0; //clear interrupt mask register
-                       i8259[chipnum].icw[i8259[chipnum].icwstep++] = value;
-                       return;
-               }
-               if ((value & 0x98) == 8) { //it's an OCW3
-                       if (value & 2)
-                               i8259[chipnum].readmode = value & 2;
-               }
-               if (value & 0x20) { //EOI command
-                       if (!chipnum) {
-                               x86_ack_keyboard();
-                               keyboardwaitack = 0;
-                       }
-                       for (i = 0; i < 8; i++)
-                               if ((i8259[chipnum].isr >> i) & 1) {
-                                       i8259[chipnum].isr ^= (1 << i);
-#if 0
-                                       if ((i == 0) && (makeupticks>0)) {
-                                               makeupticks = 0;
-                                               i8259.irr |= 1;
-                                       }
 #endif
-                                       return;
-                               }
-               }
-               break;
-               case 1:
-               if ((i8259[chipnum].icwstep == 3) && (i8259[chipnum].icw[1] & 2))
-                       i8259[chipnum].icwstep = 4; //single mode, so don't read ICW3
-               if (i8259[chipnum].icwstep<5) {
-                       i8259[chipnum].icw[i8259[chipnum].icwstep++] = value;
-                       return;
-               }
-               //if we get to this point, this is just a new IMR value
-               i8259[chipnum].imr = value;
-               break;
-       }
-}
 
-static uint8_t nextintr(void)
+void x86_ack_keyboard(void)
 {
-       uint8_t i, tmpirr;
-       tmpirr = i8259[0].irr & (~i8259[0].imr); //XOR request register with inverted mask register
-       for (i = 0; i<8; i++) {
-               if ((tmpirr >> i) & 1) {
-                       i8259[0].irr ^= (1 << i);
-                       i8259[0].isr |= (1 << i);
-                       return(i8259[0].icw[2] + i);
-               }
-       }
-       return(0); //this won't be reached, but without it the compiler gives a warning
+       set_interrupt(bridges[0], 4);
 }
 
 void x86_clearirq(uint8_t irqnum)
 {
        struct x86_bridge *xb = bridges[0];
-       if (xb->dosbox_cpu) {
-               PIC_DeActivateIRQ(irqnum);
-       }
+
+       picintc(1 << irqnum);
 }
 
 void x86_doirq(uint8_t irqnum)
 {
        struct x86_bridge *xb = bridges[0];
-       if (xb->dosbox_cpu) {
-               PIC_ActivateIRQ(irqnum);
-       } else {
-               i8259[0].irr |= (1 << irqnum);
-       }
-       if (irqnum == 1)
-               keyboardwaitack = 1;
-}
-
-void x86_doirq_keyboard(void)
-{
-       x86_doirq(1);
-}
 
-void check_x86_irq(void)
-{
-       struct x86_bridge *xb = bridges[0];
-       if (xb->dosbox_cpu) {
-               PIC_runIRQs();
-       } else {
-               if (i8259[0].irr & (~i8259[0].imr)) {
-                       uint8_t irq = nextintr();
-                       intcall86(irq); /* get next interrupt from the i8259, if any */
-               }
-       }
+       picint(1 << irqnum);
 }
 
 struct pc_floppy
@@ -977,7 +785,9 @@ static void floppy_reset(void)
 {
        struct x86_bridge *xb = bridges[0];
 
+#if FLOPPY_DEBUG
        write_log(_T("Floppy reset\n"));
+#endif
        floppy_idx = 0;
        floppy_dir = 0;
        floppy_did_reset = true;
@@ -999,7 +809,9 @@ static void floppy_hardreset(void)
 
 static void do_floppy_irq2(void)
 {
+#if FLOPPY_DEBUG
        write_log(_T("floppy%d irq (enable=%d)\n"), floppy_num, (floppy_dpc & 8) != 0);
+#endif
        if (floppy_dpc & 8) {
                floppy_irq = true;
                x86_doirq(6);
@@ -1032,13 +844,16 @@ static void do_floppy_seek(int num, int error)
                        if (valid_floppy)
                                driveclick_click(fr.num, pcf->phys_cyl);
 #endif
+#if FLOPPY_DEBUG
                        write_log(_T("Floppy%d seeking.. %d\n"), floppy_num, pcf->phys_cyl);
-
+#endif
                        if (pcf->phys_cyl - pcf->seek_offset <= 0) {
                                pcf->phys_cyl = 0;
                                if (pcf->seek_offset) {
                                        floppy_seekcyl[num] = 0;
+#if FLOPPY_DEBUG
                                        write_log(_T("Floppy%d early track zero\n"), floppy_num);
+#endif
                                        pcf->seek_offset = 0;
                                }
                        }
@@ -1069,8 +884,9 @@ static void do_floppy_seek(int num, int error)
        }
 
 done:
+#if FLOPPY_DEBUG
        write_log(_T("Floppy%d seek done err=%d. pcyl=%d cyl=%d h=%d\n"), floppy_num, error, pcf->phys_cyl,pcf->cyl, pcf->head);
-
+#endif
        floppy_status[0] = 0;
        floppy_status[0] |= 0x20; // seek end
        if (error) {
@@ -1122,6 +938,7 @@ static void floppy_do_cmd(struct x86_bridge *xb)
 
        valid_floppy = disk_reserved_getinfo(floppy_num, &fr);
 
+#if FLOPPY_DEBUG
        if (floppy_cmd_len) {
                write_log(_T("Command: "));
                for (int i = 0; i < floppy_cmd_len; i++) {
@@ -1129,13 +946,18 @@ static void floppy_do_cmd(struct x86_bridge *xb)
                }
                write_log(_T("\n"));
        }
+#endif
 
        if (cmd == 8) {
+#if FLOPPY_DEBUG
                write_log(_T("Floppy%d Sense Interrupt Status\n"), floppy_num);
+#endif
                floppy_cmd_len = 2;
+#if FLOPPY_DEBUG
                if (floppy_irq) {
                        write_log(_T("Floppy interrupt reset\n"));
                }
+#endif
                if (!floppy_irq) {
                        floppy_status[0] = 0x80;
                        floppy_cmd_len = 1;
@@ -1171,12 +993,16 @@ static void floppy_do_cmd(struct x86_bridge *xb)
        switch (cmd & 31)
        {
                case 3:
+#if FLOPPY_DEBUG
                write_log(_T("Floppy%d Specify SRT=%d HUT=%d HLT=%d ND=%d\n"), floppy_num, floppy_cmd[1] >> 4, floppy_cmd[1] & 0x0f, floppy_cmd[2] >> 1, floppy_cmd[2] & 1);
+#endif
                floppy_delay_hsync = -5;
                break;
 
                case 4:
+#if FLOPPY_DEBUG
                write_log(_T("Floppy%d Sense Drive Status\n"), floppy_num);
+#endif
                floppy_delay_hsync = 5;
                floppy_result[0] = floppy_status[3];
                floppy_cmd_len = 1;
@@ -1184,11 +1010,13 @@ static void floppy_do_cmd(struct x86_bridge *xb)
 
                case 5:
                {
+#if FLOPPY_DEBUG
                        write_log(_T("Floppy%d write MT=%d MF=%d C=%d:H=%d:R=%d:N=%d:EOT=%d:GPL=%d:DTL=%d\n"),
                                          (floppy_cmd[0] & 0x80) ? 1 : 0, (floppy_cmd[0] & 0x40) ? 1 : 0,
                                          floppy_cmd[2], floppy_cmd[3], floppy_cmd[4], floppy_cmd[5],
                                          floppy_cmd[6], floppy_cmd[7], floppy_cmd[8]);
-                       write_log(_T("DMA addr %08x len %04x\n"), dmachan[2].page | dmachan[2].addr, dmachan[2].reload);
+                       write_log(_T("DMA addr %08x len %04x\n"), dma[2].page | dma[2].ac, dma[2].ab);
+#endif
                        floppy_delay_hsync = 50;
                        int eot = floppy_cmd[6];
                        bool mt = (floppy_cmd[0] & 0x80) != 0;
@@ -1205,8 +1033,11 @@ static void floppy_do_cmd(struct x86_bridge *xb)
                                                int len = 128 << floppy_cmd[5];
                                                uae_u8 buf[512] = { 0 };
                                                for (int i = 0; i < 512 && i < len; i++) {
-                                                       buf[i] = read8237(xb, 2, &end);
-                                                       if (end)
+                                                       int v = dma_channel_read(2);
+                                                       if (v < 0)
+                                                               break;
+                                                       buf[i] = v;
+                                                       if (v >= 0x10000)
                                                                break;
                                                }
                                                zfile_fseek(fr.img, (pcf->cyl * fr.secs * fr.heads + pcf->head * fr.secs + pcf->sector) * 512, SEEK_SET);
@@ -1252,11 +1083,13 @@ static void floppy_do_cmd(struct x86_bridge *xb)
 
                case 6:
                {
+#if FLOPPY_DEBUG
                        write_log(_T("Floppy%d read MT=%d MF=%d SK=%d C=%d:H=%d:R=%d:N=%d:EOT=%d:GPL=%d:DTL=%d\n"),
                                floppy_num, (floppy_cmd[0] & 0x80) ? 1 : 0, (floppy_cmd[0] & 0x40) ? 1 : 0, (floppy_cmd[0] & 0x20) ? 1 : 0,
                                floppy_cmd[2], floppy_cmd[3], floppy_cmd[4], floppy_cmd[5],
                                floppy_cmd[6], floppy_cmd[7], floppy_cmd[8]);
-                       write_log(_T("DMA addr %08x len %04x\n"), dmachan[2].page | dmachan[2].addr, dmachan[2].reload);
+                       write_log(_T("DMA addr %08x len %04x\n"), dma[2].page | dma[2].ac, dma[2].cb);
+#endif
                        floppy_delay_hsync = 50;
                        int eot = floppy_cmd[6];
                        bool mt = (floppy_cmd[0] & 0x80) != 0;
@@ -1280,7 +1113,8 @@ static void floppy_do_cmd(struct x86_bridge *xb)
                                                zfile_fseek(fr.img, (pcf->cyl * fr.secs * fr.heads + pcf->head * fr.secs + pcf->sector) * 512, SEEK_SET);
                                                zfile_fread(buf, 1, 512, fr.img);
                                                for (int i = 0; i < 512 && i < len; i++) {
-                                                       if (write8237(xb, 2, buf[i]) <= 0)
+                                                       int v = dma_channel_write(2, buf[i]);
+                                                       if (v < 0 || v > 65535)
                                                                end = true;
                                                }
                                                pcf->sector++;
@@ -1322,7 +1156,9 @@ static void floppy_do_cmd(struct x86_bridge *xb)
                break;
 
                case 7:
+#if FLOPPY_DEBUG
                write_log(_T("Floppy%d recalibrate\n"), floppy_num);
+#endif
                if (valid_floppy) {
                        floppy_seekcyl[floppy_num] = 0;
                        floppy_seeking[floppy_num] = PC_SEEK_DELAY;
@@ -1332,7 +1168,9 @@ static void floppy_do_cmd(struct x86_bridge *xb)
                break;
 
                case 10:
+#if FLOPPY_DEBUG
                write_log(_T("Floppy read ID\n"));
+#endif
                if (!valid_floppy || !fr.img || !floppy_valid_rate(&fr) || (pcf->head && fr.heads == 1)) {
                        floppy_status[0] |= 0x40; // abnormal termination
                        floppy_status[1] |= 0x04; // no data
@@ -1357,10 +1195,12 @@ static void floppy_do_cmd(struct x86_bridge *xb)
 
                case 13:
                {
+#if FLOPPY_DEBUG
                        write_log(_T("Floppy%d format MF=%d N=%d:SC=%d:GPL=%d:D=%d\n"),
                                          floppy_num, (floppy_cmd[0] & 0x40) ? 1 : 0,
                                          floppy_cmd[2], floppy_cmd[3], floppy_cmd[4], floppy_cmd[5]);
-                       write_log(_T("DMA addr %08x len %04x\n"), dmachan[2].page | dmachan[2].addr, dmachan[2].reload);
+                       write_log(_T("DMA addr %08x len %04x\n"), dma[2].page | dma[2].ac, dma[2].cb);
+#endif
                        int secs = floppy_cmd[3];
                        if (valid_floppy && fr.img) {
                                // TODO: CHRN values totally ignored
@@ -1368,13 +1208,14 @@ static void floppy_do_cmd(struct x86_bridge *xb)
                                uae_u8 buf[512];
                                memset(buf, floppy_cmd[5], sizeof buf);
                                for (int i = 0; i < secs && i < fr.secs; i++) {
-                                       bool dmaend;
-                                       uae_u8 cx = read8237(xb, 2, &dmaend);
-                                       uae_u8 hx = read8237(xb, 2, &dmaend);
-                                       uae_u8 rx = read8237(xb, 2, &dmaend);
-                                       uae_u8 nx = read8237(xb, 2, &dmaend);
+                                       uae_u8 cx = dma_channel_read(2);
+                                       uae_u8 hx = dma_channel_read(2);
+                                       uae_u8 rx = dma_channel_read(2);
+                                       uae_u8 nx = dma_channel_read(2);
                                        pcf->sector = rx - 1;
+#if FLOPPY_DEBUG
                                        write_log(_T("Floppy%d %d/%d: C=%d H=%d R=%d N=%d\n"), floppy_num, i, fr.secs, cx, hx, rx, nx);
+#endif
                                        zfile_fseek(fr.img, (pcf->cyl * fr.secs * fr.heads + pcf->head * fr.secs + pcf->sector) * 512, SEEK_SET);
                                        zfile_fwrite(buf, 1, 512, fr.img);
                                }
@@ -1402,7 +1243,9 @@ static void floppy_do_cmd(struct x86_bridge *xb)
                case 15:
                {
                        int newcyl = floppy_cmd[2];
+#if FLOPPY_DEBUG
                        write_log(_T("Floppy%d seek %d->%d (max %d)\n"), floppy_num, pcf->phys_cyl, newcyl, fr.cyls);
+#endif
                        floppy_seekcyl[floppy_num] = newcyl;
                        floppy_seeking[floppy_num] = valid_floppy ? PC_SEEK_DELAY : -PC_SEEK_DELAY;
                        pcf->head = (floppy_cmd[1] & 4) ? 1 : 0;
@@ -1419,11 +1262,13 @@ end:
        if (floppy_cmd_len) {
                floppy_idx = -1;
                floppy_dir = 1;
+#if FLOPPY_DEBUG
                write_log(_T("Status return: "));
                for (int i = 0; i < floppy_cmd_len; i++) {
                        write_log(_T("%02x "), floppy_result[i]);
                }
                write_log(_T("\n"));
+#endif
        } else {
                floppy_idx = 0;
                floppy_dir = 0;
@@ -1432,10 +1277,6 @@ end:
 
 static void outfloppy(struct x86_bridge *xb, int portnum, uae_u8 v)
 {
-       if (!x86_turbo_allowed) {
-               x86_turbo_allowed = true;
-       }
-
        switch (portnum)
        {
                case 0x3f2: // dpc
@@ -1508,7 +1349,9 @@ static void outfloppy(struct x86_bridge *xb, int portnum, uae_u8 v)
                break;
                case 0x3f7: // configuration control
                if (xb->type >= TYPE_2286) {
+#if FLOPPY_DEBUG
                        write_log(_T("FDC Control Register %02x\n"), v);
+#endif
                        floppy_rate = v & 3;
                } else {
                        floppy_rate = -1;
@@ -1575,34 +1418,18 @@ static uae_u8 infloppy(struct x86_bridge *xb, int portnum)
        return v;
 }
 
-void bridge_mono_hit(void)
-{
-       struct x86_bridge *xb = bridges[0];
-       if (xb->amiga_io[IO_MODE_REGISTER] & 8)
-               set_interrupt(xb, 0);
-}
-void bridge_color_hit(void)
-{
-       struct x86_bridge *xb = bridges[0];
-       if (xb->amiga_io[IO_MODE_REGISTER] & 16)
-               set_interrupt(xb, 1);
-}
-
-
 static void set_pc_address_access(struct x86_bridge *xb, uaecptr addr)
 {
        if (addr >= 0xb0000 && addr < 0xb2000) {
                // mono
                if (xb->amiga_io[IO_MODE_REGISTER] & 8) {
                        xb->delayed_interrupt |= 1 << 0;
-                       //set_interrupt(xb, 0);
                }
        }
        if (addr >= 0xb8000 && addr < 0xc0000) {
                // color
                if (xb->amiga_io[IO_MODE_REGISTER] & 16) {
                        xb->delayed_interrupt |= 1 << 1;
-                       //set_interrupt(xb, 1);
                }
        }
 }
@@ -1610,17 +1437,30 @@ static void set_pc_address_access(struct x86_bridge *xb, uaecptr addr)
 static void set_pc_io_access(struct x86_bridge *xb, uaecptr portnum, bool write)
 {
        uae_u8 mode_register = xb->amiga_io[IO_MODE_REGISTER];
+
+       if (xb->mode_register < 0 || ((mode_register & (8 | 16)) != (xb->mode_register & (8 | 16)))) {
+               xb->mode_register = mode_register;
+               if (!(mode_register & 8)) {
+                       mem_mapping_disable(&xb->sharedio_mono);
+               } else {
+                       mem_mapping_enable(&xb->sharedio_mono);
+               }
+               if (!(mode_register & 16)) {
+                       mem_mapping_disable(&xb->sharedio_color);
+               } else {
+                       mem_mapping_enable(&xb->sharedio_color);
+               }
+       }
+
        if (write && (portnum == 0x3b1 || portnum == 0x3b3 || portnum == 0x3b5 || portnum == 0x3b7 || portnum == 0x3b8)) {
                // mono crt data register
                if (mode_register & 8) {
                        xb->delayed_interrupt |= 1 << 2;
-                       //set_interrupt(xb, 2);
                }
        } else if (write && (portnum == 0x3d1 || portnum == 0x3d3 || portnum == 0x3d5 || portnum == 0x3d7 || portnum == 0x3d8 || portnum == 0x3d9 || portnum == 0x3dd)) {
                        // color crt data register
                if (mode_register & 16) {
                        xb->delayed_interrupt |= 1 << 3;
-                       //set_interrupt(xb, 3);
                }
        } else if (portnum >= 0x37a && portnum < 0x37b) {
                // LPT1
@@ -1666,63 +1506,298 @@ static uae_u8 get0x3da(struct x86_bridge *xb)
        return v;
 }
 
-static uae_u8 vlsi_in(struct x86_bridge *xb, int portnum)
+
+static uint8_t mem_read_emsb(uint32_t addr, void *priv)
 {
-       uae_u8 v = 0;
-       switch(portnum)
-       {
-               case 0xed:
-               v = xb->vlsi_regs[xb->scamp_idx2];
-               break;
-       }
-       //write_log(_T("VLSI_IN %02x = %02x\n"), portnum, v);
-       return v;
+       return ram[addr];
+}
+static uint16_t mem_read_emsw(uint32_t addr, void *priv)
+{
+       return ((uint16_t*)&ram[addr])[0];
+}
+static uint32_t mem_read_emsl(uint32_t addr, void *priv)
+{
+       return ((uint32_t*)&ram[addr])[0];
+}
+static void mem_write_emsb(uint32_t addr, uint8_t val, void *priv)
+{
+       ram[addr] = val;
+}
+static void mem_write_emsw(uint32_t addr, uint16_t val, void *priv)
+{
+       ((uint16_t*)&ram[addr])[0] = val;
+}
+static void mem_write_emsl(uint32_t addr, uint32_t val, void *priv)
+{
+       ((uint32_t*)&ram[addr])[0] = val;
 }
 
-static void vlsi_reg_out(struct x86_bridge *xb, int reg, uae_u8 v)
+static uint8_t mem_read_shadowb(uint32_t addr, void *priv)
+{
+       struct scamp_shadow *m = (struct scamp_shadow*)priv;
+       return ram[addr];
+}
+static uint16_t mem_read_shadoww(uint32_t addr, void *priv)
+{
+       struct scamp_shadow *m = (struct scamp_shadow*)priv;
+       return ((uint16_t*)&ram[addr])[0];
+}
+static uint32_t mem_read_shadowl(uint32_t addr, void *priv)
+{
+       struct scamp_shadow *m = (struct scamp_shadow*)priv;
+       return ((uint32_t*)&ram[addr])[0];
+}
+static void mem_write_shadowb(uint32_t addr, uint8_t val, void *priv)
 {
-       uae_u32 shadow_start = 0;
-       uae_u32 shadow_size = 0;
+       struct scamp_shadow *m = (struct scamp_shadow*)priv;
+       ram[addr] = val;
+}
+static void mem_write_shadoww(uint32_t addr, uint16_t val, void *priv)
+{
+       struct scamp_shadow *m = (struct scamp_shadow*)priv;
+       ((uint16_t*)&ram[addr])[0] = val;
+}
+static void mem_write_shadowl(uint32_t addr, uint32_t val, void *priv)
+{
+       struct scamp_shadow *m = (struct scamp_shadow*)priv;
+       ((uint32_t*)&ram[addr])[0] = val;
+}
 
-       switch(reg)
-       {
-               case 0x1d:
-               x86_cmos_bank = (v & 0x20) ? 1 : 0;
-               break;
-               case 0x0e: // ABAX
-               shadow_size = 0x8000;
-               shadow_start = 0xa0000;
-               break;
-               case 0x0f: // CAXS
-               shadow_size = 0x4000;
-               shadow_start = 0xc0000;
-               break;
-               case 0x10: // DAXS
-               shadow_size = 0x4000;
-               shadow_start = 0xd0000;
-               break;
-               case 0x11: // FEAXS
-               shadow_size = 0x4000;
-               shadow_start = 0xe0000;
-               break;
-       }
-       if (shadow_size) {
-               for (int i = 0; i < 4; i++) {
-                       int state = (v >> (i * 2)) & 3;
-                       write_log(_T("%06x - %06x : shadow status=%d\n"), shadow_start, shadow_start + shadow_size - 1, state);
-                       shadow_start += shadow_size;
+static const uae_u32 shadow_bases[] = { 0xa0000, 0xc0000, 0xd0000, 0xe0000 };
+static const uae_u32 shadow_sizes[] = { 0x8000, 0x4000, 0x4000, 0x8000 };
+
+static void vlsi_set_mapping(struct x86_bridge *xb)
+{
+       int sltptr = xb->vlsi_regs[2];
+       if (sltptr != xb->sltptr) {
+               xb->sltptr = sltptr;
+               if (sltptr < 0x0a)
+                       xb->vlsi_regs[0x0b] &= ~0x40; // disable ems backfill
+               if (sltptr >= 0x0a && sltptr <= 0x0f)
+                       sltptr = 0x10;
+               uae_u32 addr = sltptr << 16;
+               mem_set_mem_state(addr, 640 * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
+               mem_set_mem_state(0x100000, (mem_size - 1024) * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
+               if (sltptr < 0x10) {
+                       mem_set_mem_state(addr, 640 * 1024 - addr, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
+               } else if (sltptr < 0xfe) {
+                       mem_set_mem_state(addr, (16384 - 128) * 1024 - addr, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
                }
+       }
+}
 
+static void vlsi_set_ems(struct x86_bridge *xb, bool all)
+{
+       int emsenablebits = (xb->vlsi_regs[0x0b] << 8) | (xb->vlsi_regs[0x0c]);
+       bool emsenable = ((xb->vlsi_regs[0x0b] >> 7) & 1) != 0;
+       bool emsbackfillenable = ((xb->vlsi_regs[0x0b] >> 6) & 1) != 0;
+       for (int i = 0; i < 0x24; i++) {
+               mem_mapping_t *m = &xb->ems[i];
+               int v = xb->vlsi_regs_ems[i];
+               if (!all && v == xb->emsvals[i])
+                       return;
+               xb->emsvals[i] = v;
+               uae_u32 baseaddr;
+               uae_u32 emsaddr;
+               if (i >= 0x0c) {
+                       baseaddr = 0x40000 + (i - 0x0c) * 0x4000;
+               } else {
+                       bool emsmap = ((xb->vlsi_regs[0x0b] >> 4) & 1) != 0;
+                       if (emsmap) {
+                               if (i < 0x04)
+                                       baseaddr = 0xa0000 + (i - 0) * 0x4000;
+                               else if (i < 0x08)
+                                       baseaddr = 0xd0000 + (i - 4) * 0x4000;
+                               else
+                                       baseaddr = 0xb0000 + (i - 8) * 0x4000;
+                       } else {
+                               baseaddr = 0xc0000 + i * 0x4000;
+                       }
+               }
+               emsaddr = xb->vlsi_regs_ems[i] << 14;
+               if (((i < 0x0c && (emsenablebits & (1 << i))) || (i >= 0x0c && emsbackfillenable)) && emsenable) {
+                       mem_mapping_set_addr(m, baseaddr, 0x4000);
+                       mem_mapping_set_exec(m, ram + emsaddr);
+               }       else {
+                       mem_mapping_disable(m);
+               }
        }
 }
 
-static void vlsi_out(struct x86_bridge *xb, int portnum, uae_u8 v)
+
+static void vlsi_set_shadow(struct x86_bridge *xb, int base, uae_u8 v)
 {
+       uae_u32 shadow_start = shadow_bases[base];
+       uae_u32 shadow_size = shadow_sizes[base];
+       if (xb->shadowvals[base] == v)
+               return;
+       xb->shadowvals[base] = v;
+       for (int i = 0; i < 4; i++) {
+               int state = (v >> (i * 2)) & 3;
+               struct scamp_shadow *m = &xb->shadows[base * 4 + i];
+               switch (state)
+               {
+               case 0: // read = rom, write = rom
+                       mem_mapping_disable(&m->r_map);
+                       mem_mapping_disable(&m->w_map);
+                       break;
+               case 1: // read = rom, write = ram
+                       mem_mapping_disable(&m->r_map);
+                       mem_mapping_enable(&m->w_map);
+                       break;
+               case 2: // read = ram, write = rom
+                       mem_mapping_enable(&m->r_map);
+                       mem_mapping_disable(&m->w_map);
+                       break;
+               case 3: // read = ram, write = ram
+                       mem_mapping_enable(&m->r_map);
+                       mem_mapping_enable(&m->w_map);
+                       break;
+               }
+               write_log(_T("%06x - %06x : shadow status=%d\n"), shadow_start, shadow_start + shadow_size - 1, state);
+               shadow_start += shadow_size;
+       }
+}
+
+static void vlsi_init_mapping(struct x86_bridge *xb)
+{
+       // Shadow
+       for (int i = 0; i < 4; i++) {
+               uae_u32 b = shadow_bases[i];
+               uae_u32 s = shadow_sizes[i];
+               for (int j = 0; j < 4; j++) {
+                       struct scamp_shadow *m = &xb->shadows[i * 4 + j];
+                       mem_mapping_add(&m->r_map, b, s,
+                               mem_read_shadowb, mem_read_shadoww, mem_read_shadowl,
+                               NULL, NULL, NULL,
+                               ram + b, MEM_READ_INTERNAL, m);
+                       mem_mapping_add(&m->w_map, b, s,
+                               NULL, NULL, NULL,
+                               mem_write_shadowb, mem_write_shadoww, mem_write_shadowl,
+                               ram + b, MEM_WRITE_INTERNAL, m);
+                       mem_mapping_disable(&m->r_map);
+                       mem_mapping_disable(&m->w_map);
+                       b += s;
+               }
+               xb->shadowvals[i] = -1;
+       }
+       // EMS
+       for (int i = 0x0; i < 0xc; i++) {
+               uae_u32 addr = 0xa0000 + i * 0x4000;
+               mem_mapping_add(&xb->ems[i], addr, 0x4000,
+                       mem_read_emsb, mem_read_emsw, mem_read_emsl,
+                       mem_write_emsb, mem_write_emsw, mem_write_emsl,
+                       ram + addr, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL, NULL);
+               mem_mapping_disable(&xb->ems[i]);
+       }
+       // EMS backfill
+       for (int i = 0x0c; i < 0x24; i++) {
+               uae_u32 addr = 0x40000 + i * 0x4000;
+               mem_mapping_add(&xb->ems[i], addr, 0x4000,
+                       mem_read_emsb, mem_read_emsw, mem_read_emsl,
+                       mem_write_emsb, mem_write_emsw, mem_write_emsl,
+                       ram + addr, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL, NULL);
+               mem_mapping_disable(&xb->ems[i]);
+       }
+       xb->vlsi_regs[2] = 0xff;
+       xb->sltptr = 0xff;
+}
+
+static void vlsi_reg_out(struct x86_bridge *xb, int reg, uae_u8 v)
+{
+       int shadowbase = -1;
+
+       switch(reg)
+       {
+               case 0x02: // SLTPTR
+               write_log(_T("SLTPTR = %02x\n"), v);
+               vlsi_set_ems(xb, true);
+               vlsi_set_mapping(xb);
+               break;
+
+               case 0x03: // RAMMAP
+               write_log(_T("RAMMAP = %02x\n"), v);
+               if ((v & (0x40 | 0x20 | 0x10)) != 0x20)
+                       write_log(_T("RAMMAP unsupported configuration!\n"));
+               if (mem_size > 4 * 1024 * 1024)
+                       v &= ~0x10; // REMAP384 not support if >4M RAM
+               vlsi_set_ems(xb, true);
+               vlsi_set_mapping(xb);
+               break;
+
+               case 0x0b: // ENSEN1
+               case 0x0c: // ENSEN2
+               write_log(_T("ENSEN%d = %02x\n"), reg == 0x0b ? 1 : 2, v);
+               vlsi_set_ems(xb, true);
+               vlsi_set_mapping(xb);
+               break;
+
+               case 0x0e: // ABAX
+                       shadowbase = 0;
+               break;
+               case 0x0f: // CAXS
+                       shadowbase = 1;
+               break;
+               case 0x10: // DAXS
+                       shadowbase = 2;
+               break;
+               case 0x11: // FEAXS
+                       shadowbase = 3;
+               break;
+
+               case 0x1d:
+                       x86_cmos_bank = (v & 0x20) ? 1 : 0;
+               break;
+       }
+       if (shadowbase >= 0) {
+               vlsi_set_shadow(xb, shadowbase, v);
+               vlsi_set_mapping(xb);
+       }
+}
+
+static void vlsi_autoinc(struct x86_bridge *xb)
+{
+       if (!(xb->scamp_idx1 & 0x40))
+               return;
+       int reg = xb->scamp_idx1 & 0x3f;
+       reg++;
+       xb->scamp_idx1 = (xb->scamp_idx1 & (0x80 | 0x40)) | (reg & 0x3f);
+}
+
+static void vlsi_out(struct x86_bridge *xb, int portnum, uae_u8 v)
+{
+#if 0
+       switch (portnum)
+       {
+               case 0xf9: // config disable
+               xb->vlsi_config = false;
+               break;
+               case 0xfb: // config enable
+               xb->vlsi_config = true;
+               break;
+       }
+
+       if (!xb->vlsi_config)
+               return;
+#endif
+
        switch (portnum)
        {
                case 0xe8:
                xb->scamp_idx1 = v;
                break;
+               case 0xea:
+               xb->vlsi_regs_ems[xb->scamp_idx1 & 0x3f] &= 0xff00;
+               xb->vlsi_regs_ems[xb->scamp_idx1 & 0x3f] |= v << 0;
+               break;
+               case 0xeb:
+               xb->vlsi_regs_ems[xb->scamp_idx1 & 0x3f] &= 0x00ff;
+               xb->vlsi_regs_ems[xb->scamp_idx1 & 0x3f] |= v << 8;
+               write_log(_T("EMS %d = %04x\n"), xb->vlsi_regs_ems[xb->scamp_idx1 & 0x3f]);
+               vlsi_set_ems(xb, false);
+               vlsi_set_mapping(xb);
+               vlsi_autoinc(xb);
+               break;
                case 0xec:
                xb->scamp_idx2 = v;
                break;
@@ -1730,11 +1805,54 @@ static void vlsi_out(struct x86_bridge *xb, int portnum, uae_u8 v)
                xb->vlsi_regs[xb->scamp_idx2] = v;
                vlsi_reg_out(xb, xb->scamp_idx2, v);
                break;
+               case 0xee: // fast a20 (write=disable)
+               mem_a20_alt = 0;
+               mem_a20_recalc();
+               break;
+               case 0xef: // fast reset
+               break;
        }
-       //write_log(_T("VLSI_OUT %02x = %02x\n"), portnum, v);
+       write_log(_T("VLSI_OUT %02x = %02x\n"), portnum, v);
 }
 
 
+static uae_u8 vlsi_in(struct x86_bridge *xb, int portnum)
+{
+       uae_u8 v = 0;
+       switch (portnum)
+       {
+               case 0xe8:
+               v = xb->scamp_idx1 | 0x80;
+               break;
+               case 0xea:
+               v = xb->vlsi_regs_ems[xb->scamp_idx1 & 0x3f];
+               break;
+               case 0xeb:
+               v = xb->vlsi_regs_ems[xb->scamp_idx1 & 0x3f] >> 8;
+               v |= ~0x03;
+               vlsi_autoinc(xb);
+               break;
+               case 0xec:
+               v = xb->scamp_idx2;
+               break;
+               case 0xed:
+               v = xb->vlsi_regs[xb->scamp_idx2];
+               if (xb->scamp_idx2 == 0)
+                       v = 0xd6; // version
+               break;
+               case 0xee: // fast a20 (read=enable)
+               mem_a20_alt = 1;
+               mem_a20_recalc();
+               break;
+               case 0xef: // fast reset
+               softresetx86();
+               cpu_set_edx();
+               break;
+       }
+       write_log(_T("VLSI_IN %02x = %02x\n"), portnum, v);
+       return v;
+}
+
 void portout(uint16_t portnum, uint8_t v)
 {
        struct x86_bridge *xb = bridges[0];
@@ -1744,7 +1862,7 @@ void portout(uint16_t portnum, uint8_t v)
        bool mda_emu = (enables & 8) != 0;
        bool cga_emu = (enables & 16) != 0;
 
-       if (portnum >= 0x400)
+       if (portnum >= MAX_IO_PORT)
                return;
 
        if (!is_port_enabled(xb, portnum))
@@ -1759,96 +1877,9 @@ void portout(uint16_t portnum, uint8_t v)
 
        switch(portnum)
        {
-               case 0x20:
-               case 0x21:
-               case 0xa0:
-               case 0xa1:
-               if (xb->dosbox_cpu)
-                       x86_pic_write(portnum, v);
-               else
-                       out8259(portnum, v);
-               break;
-               case 0x40:
-               case 0x41:
-               case 0x42:
-               case 0x43:
-               if (xb->dosbox_cpu)
-                       x86_timer_write(portnum, v);
-               else
-                       out8253(portnum, v);
-               break;
-               case 0x80:
-               case 0x81:
-               case 0x82:
-               case 0x83:
-               case 0x84:
-               case 0x85:
-               case 0x86:
-               case 0x87:
-               case 0x88:
-               case 0x89:
-               case 0x8a:
-               case 0x8b:
-               case 0x8c:
-               case 0x8d:
-               case 0x8e:
-               case 0x8f:
-               case 0x00:
-               case 0x01:
-               case 0x02:
-               case 0x03:
-               case 0x04:
-               case 0x05:
-               case 0x06:
-               case 0x07:
-               case 0x08:
-               case 0x09:
-               case 0x0a:
-               case 0x0b:
-               case 0x0c:
-               case 0x0d:
-               case 0x0e:
-               case 0x0f:
-
-               case 0xc0:
-               case 0xc1:
-               case 0xc2:
-               case 0xc3:
-               case 0xc4:
-               case 0xc5:
-               case 0xc6:
-               case 0xc7:
-               case 0xc8:
-               case 0xc9:
-               case 0xca:
-               case 0xcb:
-               case 0xcc:
-               case 0xcd:
-               case 0xce:
-               case 0xcf:
-               case 0xd0:
-               case 0xd1:
-               case 0xd2:
-               case 0xd3:
-               case 0xd4:
-               case 0xd5:
-               case 0xd6:
-               case 0xd7:
-               case 0xd8:
-               case 0xd9:
-               case 0xda:
-               case 0xdb:
-               case 0xdc:
-               case 0xdd:
-               case 0xde:
-               case 0xdf:
-
-               out8237(portnum, v);
-               break;
-
                case 0x60:
                if (xb->type >= TYPE_2286) {
-                       x86_out_keyboard(0x60, v);
+                       keyboard_at_write(portnum, v, NULL);
                } else {
                        aio = 0x41f;
                }
@@ -1856,11 +1887,16 @@ void portout(uint16_t portnum, uint8_t v)
                case 0x61:
                //write_log(_T("OUT Port B %02x\n"), v);
                if (xb->type >= TYPE_2286) {
-                       x86_out_keyboard(0x61, v);
+                       keyboard_at_write(portnum, v, NULL);
                } else {
-                       if (xb->dosbox_cpu) {
-                               TIMER_SetGate2(v & 1);
-                       }
+                       timer_process();
+                       timer_update_outstanding();
+                       speaker_update();
+                       speaker_gated = v & 1;
+                       speaker_enable = v & 2;
+                       if (speaker_enable)
+                               was_speaker_enable = 1;
+                       pit_set_gate(&pit, 2, v & 1);
                        aio = 0x5f;
                }
                break;
@@ -1888,30 +1924,30 @@ void portout(uint16_t portnum, uint8_t v)
                        }
                        if (xb->type == TYPE_2088T) {
                                int speed = v >> 6;
-                               if (speed == 0)
+                               switch (speed)
+                               {
+                               case 0:
                                        write_log(_T("A2088T: 4.77MHz\n"));
-                               if (speed == 1)
+                                       cpu_set_turbo(0);
+                                       break;
+                               case 1:
                                        write_log(_T("A2088T: 7.15MHz\n"));
-                               if (speed == 2)
+                                       cpu_set_turbo(1);
+                                       break;
+                               case 2:
                                        write_log(_T("A2088T: 9.54MHz\n"));
+                                       cpu_set_turbo(1);
+                                       break;
+                               }
                        }
                }
                break;
                case 0x64:
                if (xb->type >= TYPE_2286) {
-                       x86_out_keyboard(0x64, v);
+                       keyboard_at_write(portnum, v, NULL);
                }
                break;
 
-               case 0x70:
-               if (xb->type >= TYPE_2286)
-                       cmos_selreg(portnum, v, 1);
-               break;
-               case 0x71:
-               if (xb->type >= TYPE_2286)
-                       cmos_writereg(portnum, v, 1);
-               break;
-
                case 0x2f8:
                if (xb->amiga_io[0x13f] & 0x80)
                        aio = 0x7f;
@@ -2082,25 +2118,18 @@ void portout(uint16_t portnum, uint8_t v)
 
                // A2386SX only
                case 0xe8:
-               case 0xe9:
                case 0xea:
-               case 0xeb:
                case 0xec:
                case 0xed:
                case 0xee:
-               case 0xef:
                case 0xf0:
                case 0xf1:
                case 0xf4:
                case 0xf5:
-               case 0xf8:
                case 0xf9:
-               case 0xfa:
                case 0xfb:
-               case 0xfc:
-               case 0xfe:
-               if (xb->type >= TYPE_2386)
-                       vlsi_out(xb, portnum, v);
+                       if (xb->type >= TYPE_2386)
+                               vlsi_out(xb, portnum, v);
                break;
 
                // floppy
@@ -2167,17 +2196,13 @@ void portout(uint16_t portnum, uint8_t v)
                x86_ide_hd_put(portnum, v, 0);
                break;
 
-               case 0x101:
-               case 0x102:
-               // A2286 BIOS timer test fails if CPU is too fast
-               // so we'll run normal speed until tests are done
-               if (!x86_turbo_allowed) {
-                       x86_turbo_allowed = true;
-               }
-               break;
-
                default:
-               write_log(_T("X86_OUT unknown %02x %02x\n"), portnum, v);
+               if (port_outb[portnum]) {
+                       port_outb[portnum](portnum, v, port_priv[portnum]);
+               } else {
+                       write_log(_T("X86_OUT unknown %02x %02x\n"), portnum, v);
+                       return;
+               }
                break;
        }
 
@@ -2193,6 +2218,9 @@ void portout16(uint16_t portnum, uint16_t value)
 {
        struct x86_bridge *xb = bridges[0];
 
+       if (portnum >= MAX_IO_PORT)
+               return;
+
        if (xb->ne2000_isa && portnum >= xb->ne2000_io && portnum < xb->ne2000_io + 32) {
                xb->ne2000_isa->bars[0].wput(xb->ne2000_isa_board_state, portnum - xb->ne2000_io, value);
                return;
@@ -2206,13 +2234,21 @@ void portout16(uint16_t portnum, uint16_t value)
                x86_ide_hd_put(portnum, value, 1);
                break;
                default:
-               portout(portnum, value);
-               portout(portnum + 1, value >> 8);
+               if (port_outw[portnum]) {
+                       port_outw[portnum](portnum, value, port_priv[portnum]);
+               } else {
+                       portout(portnum, value);
+                       portout(portnum + 1, value >> 8);
+               }
                break;
        }
 }
-static void portout32(uint16_t portnum, uint32_t value)
+
+void portout32(uint16_t portnum, uint32_t value)
 {
+       if (portnum >= MAX_IO_PORT)
+               return;
+
        switch (portnum)
        {
                case 0x170:
@@ -2238,7 +2274,7 @@ uint8_t portin(uint16_t portnum)
        if (!is_port_enabled(xb, portnum))
                return 0;
 
-       if (portnum >= 0x400)
+       if (portnum >= MAX_IO_PORT)
                return 0;
 
        set_pc_io_access(xb, portnum, false);
@@ -2252,100 +2288,6 @@ uint8_t portin(uint16_t portnum)
 
        switch (portnum)
        {
-               case 0x20:
-               case 0x21:
-               case 0xa0:
-               case 0xa1:
-               if (xb->dosbox_cpu)
-                       v = x86_pic_read(portnum);
-               else
-                       v = in8259(portnum);
-               break;
-
-               case 0x40:
-               case 0x41:
-               case 0x42:
-               case 0x43:
-               if (xb->dosbox_cpu)
-                       v = x86_timer_read(portnum);
-               else
-                       v = in8253(portnum);
-               break;
-
-               case 0x80:
-               case 0x81:
-               case 0x82:
-               case 0x83:
-               case 0x84:
-               case 0x85:
-               case 0x86:
-               case 0x87:
-               case 0x88:
-               case 0x89:
-               case 0x8a:
-               case 0x8b:
-               case 0x8c:
-               case 0x8d:
-               case 0x8e:
-               case 0x8f:
-               case 0x00:
-               case 0x01:
-               case 0x02:
-               case 0x03:
-               case 0x04:
-               case 0x05:
-               case 0x06:
-               case 0x07:
-               case 0x08:
-               case 0x09:
-               case 0x0a:
-               case 0x0b:
-               case 0x0c:
-               case 0x0d:
-               case 0x0e:
-               case 0x0f:
-
-               case 0xc0:
-               case 0xc1:
-               case 0xc2:
-               case 0xc3:
-               case 0xc4:
-               case 0xc5:
-               case 0xc6:
-               case 0xc7:
-               case 0xc8:
-               case 0xc9:
-               case 0xca:
-               case 0xcb:
-               case 0xcc:
-               case 0xcd:
-               case 0xce:
-               case 0xcf:
-               case 0xd0:
-               case 0xd1:
-               case 0xd2:
-               case 0xd3:
-               case 0xd4:
-               case 0xd5:
-               case 0xd6:
-               case 0xd7:
-               case 0xd8:
-               case 0xd9:
-               case 0xda:
-               case 0xdb:
-               case 0xdc:
-               case 0xdd:
-               case 0xde:
-               case 0xdf:
-
-               v = in8237(portnum);
-               break;
-
-               case 0x71:
-               if (xb->type >= TYPE_2286)
-                       v = cmos_readreg(portnum, 1);
-               break;
-
                case 0x2f8:
                if (xb->amiga_io[0x11f] & 0x80)
                        aio = 0x7f;
@@ -2514,23 +2456,11 @@ uint8_t portin(uint16_t portnum)
 
                // A2386SX only
                case 0xe8:
-               case 0xe9:
                case 0xea:
-               case 0xeb:
                case 0xec:
                case 0xed:
                case 0xee:
                case 0xef:
-               case 0xf0:
-               case 0xf1:
-               case 0xf4:
-               case 0xf5:
-               case 0xf8:
-               case 0xf9:
-               case 0xfa:
-               case 0xfb:
-               case 0xfc:
-               case 0xfe:
                if (xb->type >= TYPE_2386)
                        v = vlsi_in(xb, portnum);
                break;
@@ -2548,14 +2478,14 @@ uint8_t portin(uint16_t portnum)
 
                case 0x60:
                if (xb->type >= TYPE_2286) {
-                       v = x86_in_keyboard(0x60);
+                       v = keyboard_at_read(portnum, NULL);
                        //write_log(_T("PC read keycode %02x\n"), v);
                }
                break;
                case 0x61:
                if (xb->type >= TYPE_2286) {
                        // bios test hack
-                       v = x86_in_keyboard(0x61);
+                       v = keyboard_at_read(portnum, NULL);
                } else {
                        v = xb->amiga_io[0x5f];
                }
@@ -2590,13 +2520,8 @@ uint8_t portin(uint16_t portnum)
                        }
                        v &= ~0x20;
                        if (!(xb->amiga_io[0x5f] & 1)) {
-                               bool timer2 = false;
-                               if (xb->dosbox_cpu) {
-                                       timer2 = TIMER_GetGate2();
-                               } else {
-                                       timer2 = i8253.active[2] != 0;
-                               }
-                               if (timer2)
+                               bool timer2gate = pit.gate[2] == 0;
+                               if (timer2gate)
                                        v |= 0x20;
                        }
                        //write_log(_T("IN Port C %02x\n"), v);
@@ -2607,7 +2532,7 @@ uint8_t portin(uint16_t portnum)
                break;
                case 0x64:
                if (xb->type >= TYPE_2286) {
-                       v = x86_in_keyboard(0x64);
+                       v = keyboard_at_read(portnum, NULL);
                }
                break;
 
@@ -2664,9 +2589,25 @@ uint8_t portin(uint16_t portnum)
                v = x86_ide_hd_get(portnum, 0);
                break;
 
+               // led debug (a2286 bios uses this)
+               case 0x108:
+               case 0x109:
+               case 0x10a:
+               case 0x10b:
+               case 0x10c:
+               case 0x10d:
+               case 0x10e:
+               case 0x10f:
+                       break;
+
                default:
-               write_log(_T("X86_IN unknown %02x\n"), portnum);
-               return 0;
+               if (port_inb[portnum]) {
+                       v = port_inb[portnum](portnum, port_priv[portnum]);
+               } else {
+                       write_log(_T("X86_IN unknown %02x\n"), portnum);
+                       return 0;
+               }
+               break;
        }
 
 end:
@@ -2683,6 +2624,10 @@ uint16_t portin16(uint16_t portnum)
 {
        struct x86_bridge *xb = bridges[0];
        uae_u16 v = 0;
+
+       if (portnum >= MAX_IO_PORT)
+               return v;
+
        if (xb->ne2000_isa && portnum >= xb->ne2000_io && portnum < xb->ne2000_io + 32) {
                v = xb->ne2000_isa->bars[0].wget(xb->ne2000_isa_board_state, portnum - xb->ne2000_io);
                return v;
@@ -2695,14 +2640,23 @@ uint16_t portin16(uint16_t portnum)
                v = x86_ide_hd_get(portnum, 1);
                break;
                default:
-               write_log(_T("portin16 %08x\n"), portnum);
+               if (port_inw[portnum]) {
+                       v = port_inw[portnum](portnum, port_priv[portnum]);
+               } else {
+                       v = (portin(portnum) << 0) | (portin(portnum + 1) << 8);
+               }
                break;
        }
        return v;
 }
-static uint32_t portin32(uint16_t portnum)
+
+uint32_t portin32(uint16_t portnum)
 {
        uint32_t v = 0;
+
+       if (portnum >= MAX_IO_PORT)
+               return v;
+
        switch (portnum)
        {
                case 0x170:
@@ -2718,51 +2672,7 @@ static uint32_t portin32(uint16_t portnum)
        return v;
 }
 
-void write86(uint32_t addr32, uint8_t value)
-{
-       struct x86_bridge *xb = bridges[0];
-       addr32 &= 0xFFFFF;
-       if (addr32 >= xb->pc_maxbaseram && addr32 < 0xa0000)
-               return;
-       if (addr32 >= x86_xrom_start[0] && addr32 < x86_xrom_end[0])
-               return;
-       if (addr32 >= x86_xrom_start[1] && addr32 < x86_xrom_end[1])
-               return;
-       set_pc_address_access(xb, addr32);
-       xb->pc_ram[addr32] = value;
-}
-void writew86(uint32_t addr32, uint16_t value)
-{
-       struct x86_bridge *xb = bridges[0];
-       addr32 &= 0xFFFFF;
-       if (addr32 >= xb->pc_maxbaseram && addr32 < 0xa0000)
-               return;
-       if (addr32 >= x86_xrom_start[0] && addr32 < x86_xrom_end[0])
-               return;
-       if (addr32 >= x86_xrom_start[1] && addr32 < x86_xrom_end[1])
-               return;
-       set_pc_address_access(xb, addr32);
-       xb->pc_ram[addr32] = value & 0xff;
-       xb->pc_ram[addr32 + 1] = value >> 8;
-}
-uint8_t read86(uint32_t addr32)
-{
-       struct x86_bridge *xb = bridges[0];
-       addr32 &= 0xFFFFF;
-       return xb->pc_ram[addr32];
-}
-uint16_t readw86(uint32_t addr32)
-{
-       uint16_t v;
-       struct x86_bridge *xb = bridges[0];
-       addr32 &= 0xFFFFF;
-
-       v = xb->pc_ram[addr32];
-       v |= xb->pc_ram[addr32 + 1] << 8;
-       return v;
-}
-
-static uaecptr get_x86_address(struct x86_bridge *xb, uaecptr addr, int *mode)
+static uaecptr get_x86_address(struct x86_bridge *xb, uaecptr addr, int *mode, uae_u8 **base)
 {
        addr -= xb->baseaddress;
        if (!xb->baseaddress || addr >= 0x80000) {
@@ -2772,35 +2682,34 @@ static uaecptr get_x86_address(struct x86_bridge *xb, uaecptr addr, int *mode)
        *mode = addr >> 17;
        addr &= 0x1ffff;
        if (addr < 0x10000) {
-               int opt = (xb->amiga_io[IO_MODE_REGISTER] >> 5) & 3;
-               // disk buffer
-               switch(opt)
-               {
-                       case 1:
-                       default:
-                       return 0xa0000 + addr;
-                       case 2:
-                       return 0xd0000 + addr;
-                       case 3:
-                       return 0xe0000 + addr;
-               }
+               *base = xb->amiga_buffer + addr;
+               return get_shared_io(xb) + addr;
        }
        if (addr < 0x18000) {
                // color video
                addr -= 0x10000;
+               *base = xb->amiga_color + addr;
                return 0xb8000 + addr;
        }
        if (addr < 0x1c000) {
-               addr -= 0x18000;
                // parameter
-               if (xb->type >= TYPE_2286)
+               addr -= 0x18000;
+               if (xb->type >= TYPE_2286) {
+                       if (get_shared_io(xb) == 0xd0000) {
+                               *base = xb->amiga_buffer + addr;
+                               return 0xd0000 + addr;
+                       }
+                       *base = xb->amiga_parameter + addr;
                        return 0xd0000 + addr;
-               else
+               } else {
+                       *base = xb->amiga_parameter + addr;
                        return 0xf0000 + addr;
+               }
        }
        if (addr < 0x1e000) {
-               addr -= 0x1c000;
                // mono video
+               addr -= 0x1c000;
+               *base = xb->amiga_mono + addr;
                return 0xb0000 + addr;
        }
        // IO
@@ -2816,23 +2725,24 @@ static struct x86_bridge *get_x86_bridge(uaecptr addr)
 static uae_u32 REGPARAM2 x86_bridge_wget(uaecptr addr)
 {
        uae_u16 v = 0;
+       uae_u8 *base;
        struct x86_bridge *xb = get_x86_bridge(addr);
        if (!xb)
                return v;
        int mode;
-       uaecptr a = get_x86_address(xb, addr, &mode);
+       uaecptr a = get_x86_address(xb, addr, &mode, &base);
        if (mode == ACCESS_MODE_WORD) {
-               v = (xb->pc_ram[a + 1] << 8) | (xb->pc_ram[a + 0] << 0);
+               v = (base[1] << 8) | (base[0] << 0);
        } else if (mode == ACCESS_MODE_GFX) {
                write_log(_T("ACCESS_MODE_GFX\n"));
        } else if (mode == ACCESS_MODE_IO) {
                v = x86_bridge_get_io(xb, a);
                v |= x86_bridge_get_io(xb, a + 1) << 8;
        } else if (mode >= 0) {
-               v = (xb->pc_ram[a + 1] << 0) | (xb->pc_ram[a + 0] << 8);
+               v = (base[1] << 0) | (base[0] << 8);
        }
 #if X86_DEBUG_BRIDGE > 1
-       write_log(_T("x86_bridge_wget %08x (%08x,%d) PC=%08x\n"), addr - xb->baseaddress, a, mode, M68K_GETPC);
+       write_log(_T("x86_bridge_wget %08x (%08x,%d)=%04x PC=%08x\n"), addr - xb->baseaddress, a, mode, v, M68K_GETPC);
 #endif
        return v;
 }
@@ -2846,6 +2756,7 @@ static uae_u32 REGPARAM2 x86_bridge_lget(uaecptr addr)
 static uae_u32 REGPARAM2 x86_bridge_bget(uaecptr addr)
 {
        uae_u8 v = 0;
+       uae_u8 *base;
        struct x86_bridge *xb = get_x86_bridge(addr);
        if (!xb)
                return v;
@@ -2856,16 +2767,16 @@ static uae_u32 REGPARAM2 x86_bridge_bget(uaecptr addr)
                return xb->acmemory[offset];
        }
        int mode;
-       uaecptr a = get_x86_address(xb, addr, &mode);
+       uaecptr a = get_x86_address(xb, addr, &mode, &base);
        if (mode == ACCESS_MODE_WORD) {
-               v = xb->pc_ram[a ^ 1];
+               v = base[(a ^ 1) & 1];
        } else if (mode == ACCESS_MODE_IO) {
                v = x86_bridge_get_io(xb, a);
        } else if (mode >= 0) {
-               v = xb->pc_ram[a];
+               v = base[0];
        }
 #if X86_DEBUG_BRIDGE > 1
-       write_log(_T("x86_bridge_bget %08x (%08x,%d) %02x PC=%08x\n"), addr - xb->baseaddress, a, mode, v, M68K_GETPC);
+       write_log(_T("x86_bridge_bget %08x (%08x,%d)=%02x PC=%08x\n"), addr - xb->baseaddress, a, mode, v, M68K_GETPC);
 #endif
        return v;
 }
@@ -2876,7 +2787,8 @@ static void REGPARAM2 x86_bridge_wput(uaecptr addr, uae_u32 b)
        if (!xb)
                return;
        int mode;
-       uaecptr a = get_x86_address(xb, addr, &mode);
+       uae_u8 *base;
+       uaecptr a = get_x86_address(xb, addr, &mode, &base);
 
 #if X86_DEBUG_BRIDGE > 1
        write_log(_T("pci_bridge_wput %08x (%08x,%d) %04x PC=%08x\n"), addr - xb->baseaddress, a, mode, b & 0xffff, M68K_GETPC);
@@ -2884,21 +2796,19 @@ static void REGPARAM2 x86_bridge_wput(uaecptr addr, uae_u32 b)
 
        if (a >= 0x100000 || mode < 0)
                return;
-       if (xb->rombank[a / 4096])
-               return;
 
        if (mode == ACCESS_MODE_IO) {
                uae_u16 v = b;
                x86_bridge_put_io(xb, a, v & 0xff);
                x86_bridge_put_io(xb, a + 1, v >> 8);
        } else if (mode == ACCESS_MODE_WORD) {
-               xb->pc_ram[a + 0] = b;
-               xb->pc_ram[a + 1] = b >> 8;
+               base[0] = b;
+               base[1] = b >> 8;
        } else if (mode == ACCESS_MODE_GFX) {
                write_log(_T("ACCESS_MODE_GFX\n"));
        } else {
-               xb->pc_ram[a + 1] = b;
-               xb->pc_ram[a + 0] = b >> 8;
+               base[1] = b;
+               base[0] = b >> 8;
        }
 }
 static void REGPARAM2 x86_bridge_lput(uaecptr addr, uae_u32 b)
@@ -2929,12 +2839,11 @@ static void REGPARAM2 x86_bridge_bput(uaecptr addr, uae_u32 b)
        }
 
        int mode;
-       uaecptr a = get_x86_address(xb, addr, &mode);
+       uae_u8 *base;
+       uaecptr a = get_x86_address(xb, addr, &mode, &base);
 
        if (a >= 0x100000 || mode < 0)
                return;
-       if (xb->rombank[a / 4096])
-               return;
 
 #if X86_DEBUG_BRIDGE > 1
        write_log(_T("x86_bridge_bput %08x (%08x,%d) %02x PC=%08x\n"), addr - xb->baseaddress, a, mode, b & 0xff, M68K_GETPC);
@@ -2943,9 +2852,9 @@ static void REGPARAM2 x86_bridge_bput(uaecptr addr, uae_u32 b)
        if (mode == ACCESS_MODE_IO) {
                x86_bridge_put_io(xb, a, b);
        } else if (mode == ACCESS_MODE_WORD) {
-               xb->pc_ram[a ^ 1] = b;
+               base[(a ^ 1) & 1] = b;
        } else {
-               xb->pc_ram[a] = b;
+               base[0] = b;
        }
 }
 
@@ -2957,6 +2866,112 @@ addrbank x86_bridge_bank = {
        ABFLAG_IO | ABFLAG_SAFE, S_READ, S_WRITE
 };
 
+static uint8_t mem_read_sharedb(uint32_t addr, void *priv)
+{
+       struct membase *mb = (struct membase*)priv;
+       return mb->base[addr & mb->mask];
+}
+static uint16_t mem_read_sharedw(uint32_t addr, void *priv)
+{
+       struct membase *mb = (struct membase*)priv;
+       return ((uae_u16*)(mb->base + (addr & mb->mask)))[0];
+}
+static uint32_t mem_read_sharedl(uint32_t addr, void *priv)
+{
+       struct membase *mb = (struct membase*)priv;
+       uae_u8 *base = (uae_u8*)priv;
+       return ((uae_u32*)(mb->base + (addr & mb->mask)))[0];
+}
+static void mem_write_sharedb(uint32_t addr, uint8_t val, void *priv)
+{
+       struct membase *mb = (struct membase*)priv;
+       set_pc_address_access(bridges[0], addr);
+       mb->base[addr & mb->mask] = val;
+}
+static void mem_write_sharedw(uint32_t addr, uint16_t val, void *priv)
+{
+       struct membase *mb = (struct membase*)priv;
+       set_pc_address_access(bridges[0], addr);
+       ((uae_u16*)(mb->base + (addr & mb->mask)))[0] = val;
+}
+static void mem_write_sharedl(uint32_t addr, uint32_t val, void *priv)
+{
+       struct membase *mb = (struct membase*)priv;
+       set_pc_address_access(bridges[0], addr);
+       ((uae_u32*)(mb->base + (addr & mb->mask)))[0] = val;
+}
+
+static uint8_t vga_readb(uint32_t addr, void *priv)
+{
+       return vga_ram_get(x86_vga_board, addr);
+}
+static uint16_t vga_readw(uint32_t addr, void *priv)
+{
+       return (vga_ram_get(x86_vga_board, addr) << 0) | (vga_ram_get(x86_vga_board, addr + 1) << 8);
+}
+static uint32_t vga_readl(uint32_t addr, void *priv)
+{
+       return (vga_readw(addr, priv) << 0) | (vga_readw(addr + 2, priv) << 16);
+}
+static void vga_writeb(uint32_t addr, uint8_t val, void *priv)
+{
+       vga_ram_put(x86_vga_board, addr, val);
+}
+static void vga_writew(uint32_t addr, uint16_t val, void *priv)
+{
+       vga_ram_put(x86_vga_board, addr, val);
+       vga_ram_put(x86_vga_board, addr + 1, val >> 8);
+}
+static void vga_writel(uint32_t addr, uint32_t val, void *priv)
+{
+       vga_ram_put(x86_vga_board, addr, val);
+       vga_ram_put(x86_vga_board, addr + 1, val >> 8);
+       vga_ram_put(x86_vga_board, addr + 2, val >> 16);
+       vga_ram_put(x86_vga_board, addr + 3, val >> 24);
+}
+
+static uint8_t vgalfb_readb(uint32_t addr, void *priv)
+{
+       return vgalfb_ram_get(x86_vga_board, addr);
+}
+static uint16_t vgalfb_readw(uint32_t addr, void *priv)
+{
+       return (vgalfb_ram_get(x86_vga_board, addr) << 0) | (vgalfb_ram_get(x86_vga_board, addr + 1) << 8);
+}
+static uint32_t vgalfb_readl(uint32_t addr, void *priv)
+{
+       return (vgalfb_readw(addr, priv) << 0) | (vgalfb_readw(addr + 2, priv) << 16);
+}
+static void vgalfb_writeb(uint32_t addr, uint8_t val, void *priv)
+{
+       vgalfb_ram_put(x86_vga_board, addr, val);
+}
+static void vgalfb_writew(uint32_t addr, uint16_t val, void *priv)
+{
+       vgalfb_ram_put(x86_vga_board, addr, val);
+       vgalfb_ram_put(x86_vga_board, addr + 1, val >> 8);
+}
+static void vgalfb_writel(uint32_t addr, uint32_t val, void *priv)
+{
+       vgalfb_ram_put(x86_vga_board, addr, val);
+       vgalfb_ram_put(x86_vga_board, addr + 1, val >> 8);
+       vgalfb_ram_put(x86_vga_board, addr + 2, val >> 16);
+       vgalfb_ram_put(x86_vga_board, addr + 3, val >> 24);
+}
+
+static uint8_t mem_read_romext2(uint32_t addr, void *priv)
+{
+       return xtiderom[addr & 0x3fff];
+}
+static uint16_t mem_read_romextw2(uint32_t addr, void *priv)
+{
+       return *(uint16_t *)&xtiderom[addr & 0x3fff];
+}
+static uint32_t mem_read_romextl2(uint32_t addr, void *priv)
+{
+       return *(uint32_t *)&xtiderom[addr & 0x3fff];
+}
+
 void x86_bridge_rethink(void)
 {
        struct x86_bridge *xb = bridges[0];
@@ -2981,8 +2996,6 @@ void x86_bridge_free(void)
 
 void x86_bridge_reset(void)
 {
-       x86_xrom_start[0] = x86_xrom_end[0] = 0;
-       x86_xrom_start[1] = x86_xrom_end[1] = 0;
        for (int i = 0; i < X86_BRIDGE_MAX; i++) {
                struct x86_bridge *xb = bridges[i];
                if (!xb)
@@ -2993,25 +3006,31 @@ void x86_bridge_reset(void)
                        xfree(xb->ne2000_isa_board_state);
                        xb->ne2000_isa_board_state = NULL;
                }
-               if (xb->dosbox_cpu) {
-                       if (xb->cmosfile) {
-                               uae_u8 *regs = x86_cmos_regs(NULL);
-                               zfile_fseek(xb->cmosfile, 0, SEEK_SET);
-                               zfile_fwrite(regs, 1, xb->cmossize, xb->cmosfile);
-                       }
-                       CPU_ShutDown(dosbox_sec);
-                       CMOS_Destroy(dosbox_sec);
-                       TIMER_Destroy(dosbox_sec);
-                       PIC_Destroy(dosbox_sec);
-                       MEM_ShutDown(dosbox_sec);
-                       delete dosbox_sec;
+               if (xb->cmosfile) {
+                       zfile_fseek(xb->cmosfile, 0, SEEK_SET);
+                       zfile_fwrite(nvrram, 1, xb->cmossize, xb->cmosfile);
+               }
+               if (xb->audstream) {
+                       audio_enable_stream(false, xb->audstream, 0, NULL);
                }
+               zfile_fclose(xb->cmosfile);
                xfree(xb->amiga_io);
                xfree(xb->io_ports);
-               xfree(xb->pc_ram);
                xfree(xb->pc_rom);
-               zfile_fclose(xb->cmosfile);
+               rom = NULL;
+               xfree(xtiderom);
+               xtiderom = NULL;
+               xfree(xb->mouse_base);
+               xfree(xb->cms_base);
+               xfree(xb->sb_base);
+               mem_free();
                bridges[i] = NULL;
+               memset(port_inb, 0, sizeof(port_inb));
+               memset(port_inw, 0, sizeof(port_inw));
+               memset(port_inl, 0, sizeof(port_inl));
+               memset(port_outb, 0, sizeof(port_outb));
+               memset(port_outw, 0, sizeof(port_outw));
+               memset(port_outl, 0, sizeof(port_outl));
        }
 }
 
@@ -3038,49 +3057,56 @@ static void check_floppy_delay(void)
        }
 }
 
-static void x86_cpu_execute(int cnt)
+static void x86_cpu_execute(int cycs)
 {
        struct x86_bridge *xb = bridges[0];
        if (!xb->x86_reset) {
-               if (xb->dosbox_cpu) {
-                       if (xb->x86_reset_requested) {
-                               xb->x86_reset_requested = false;
-                               reset_x86_cpu(xb);
-                       }
-                       Bit32s old_cpu_cycles = CPU_Cycles;
-                       if (CPU_Cycles > cnt)
-                               CPU_Cycles = cnt;
-                       if (PIC_RunQueue()) {
-                               (*cpudecoder)();
-                       }
-                       CPU_Cycles = old_cpu_cycles -= cnt;
-                       if (CPU_Cycles < 0)
-                               CPU_Cycles = 0;
-                       check_x86_irq();
-               } else {
-                       exec86(cnt);
-               }
+
+               // no free buffers to fill
+               if (x86_sndbuffer_filled[x86_sndbuffer_index])
+                       return;
+
+               if (AT)
+                       exec386(cycs);
+               else
+                       execx86(cycs);
        }
 
        // BIOS has CPU loop delays in floppy driver...
        check_floppy_delay();
 }
 
-void x86_bridge_execute_until(int until)
+static bool audio_state_sndboard_x86(int streamid)
 {
+       static int smp[2] = { 0, 0 };
        struct x86_bridge *xb = bridges[0];
-       if (!xb)
-               return;
-       if (!x86_turbo_allowed)
-               return;
-       for (;;) {
-               x86_cpu_execute(until ? 10 : 1);
-               if (until == 0)
-                       break;
-               frame_time_t rpt = read_processor_time();
-               if ((int)until - (int)rpt <= 0)
-                       break;
-       }
+
+       if (streamid != xb->audstream)
+               return false;
+
+       if (x86_sndbuffer_filled[x86_sndbuffer_playindex]) {
+               int32_t *p = x86_sndbuffer[x86_sndbuffer_playindex];
+               int32_t l = p[x86_sndbuffer_playpos * 2 + 0];
+               int32_t r = p[x86_sndbuffer_playpos * 2 + 1];
+               if (l < -32768)
+                       l = -32768;
+               if (l > 32767)
+                       l = 32767;
+               if (r < -32768)
+                       r = -32768;
+               if (r > 32767)
+                       r = 32767;
+               x86_sndbuffer_playpos++;
+               if (x86_sndbuffer_playpos == SOUNDBUFLEN) {
+                       x86_sndbuffer_filled[x86_sndbuffer_playindex] = false;
+                       x86_sndbuffer_playindex ^= 1;
+                       x86_sndbuffer_playpos = 0;
+               }
+               smp[0] = l;
+               smp[1] = r;
+       }
+       audio_state_stream_state(xb->audstream, smp, 2, xb->audeventtime);
+       return true;
 }
 
 void x86_bridge_sync_change(void)
@@ -3088,10 +3114,6 @@ void x86_bridge_sync_change(void)
        struct x86_bridge *xb = bridges[0];
        if (!xb)
                return;
-
-       xb->dosbox_vpos_tick = maxvpos * vblank_hz / 1000;
-       if (xb->dosbox_vpos_tick >= xb->dosbox_vpos_tick)
-               xb->dosbox_tick_vpos_cnt -= xb->dosbox_vpos_tick;
 }
 
 void x86_bridge_vsync(void)
@@ -3103,50 +3125,47 @@ void x86_bridge_vsync(void)
        if (xb->delayed_interrupt) {
                devices_rethink_all(x86_bridge_rethink);
        }
+       struct romconfig *rc = get_device_romconfig(&changed_prefs, ROMTYPE_X86MOUSE, 0);
+       if (rc) {
+               xb->mouse_port = (rc->device_settings & 3) + 1;
+       }
+       xb->audeventtime = x86_base_event_clock * CYCLE_UNIT / currprefs.sound_freq + 1;
 }
 
 void x86_bridge_hsync(void)
 {
+       static float totalcycles;
        struct x86_bridge *xb = bridges[0];
        if (!xb)
                return;
 
+       if (!xb->sound_initialized) {
+               // x86_base_event_clock is not initialized until syncs start
+               xb->sound_initialized = true;
+               if (xb->sound_emu) {
+                       write_log(_T("x86 sound init\n"));
+                       xb->audeventtime = x86_base_event_clock * CYCLE_UNIT / currprefs.sound_freq + 1;
+                       timer_add(sound_poll, &sound_poll_time, TIMER_ALWAYS_ENABLED, NULL);
+                       xb->audstream = audio_enable_stream(true, -1, 2, audio_state_sndboard_x86);
+               }
+       }
+
        check_floppy_delay();
 
        if (xb->ne2000_isa)
                xb->ne2000_isa->hsync(xb->ne2000_isa_board_state);
 
        if (!xb->x86_reset) {
-               if (xb->dosbox_cpu) {
-                       xb->dosbox_tick_vpos_cnt++;
-                       if (xb->dosbox_tick_vpos_cnt >= xb->dosbox_vpos_tick) {
-                               TIMER_AddTick();
-                               xb->dosbox_tick_vpos_cnt -= xb->dosbox_vpos_tick;
-                       }
-                       x86_cpu_execute(x86_instruction_count);
-               } else {
-                       for (int i = 0; i < 3; i++) {
-                               x86_cpu_execute(x86_instruction_count / 3);
-                               timing(maxhpos / 3);
-                       }
-               }
+               float cycles_to_run = (float)cpu_get_speed() / (vblank_hz * maxvpos);
+               totalcycles += cycles_to_run;
+               int cycs = (int)totalcycles;
+               x86_cpu_execute(cycs);
+               totalcycles -= (int)totalcycles;
        }
 
        if (currprefs.x86_speed_throttle != changed_prefs.x86_speed_throttle) {
                currprefs.x86_speed_throttle = changed_prefs.x86_speed_throttle;
-               x86_instruction_count = DEFAULT_X86_INSTRUCTION_COUNT;
-               if (currprefs.x86_speed_throttle < 0) {
-                       x86_turbo_enabled = true;
-               } else {
-                       x86_turbo_enabled = false;
-                       x86_instruction_count = DEFAULT_X86_INSTRUCTION_COUNT + DEFAULT_X86_INSTRUCTION_COUNT * currprefs.x86_speed_throttle / 1000;
-               }
-       }
-
-       if (x86_turbo_allowed && x86_turbo_enabled && !x86_turbo_on) {
-               x86_turbo_on = true;
-       } else if ((!x86_turbo_allowed || !x86_turbo_enabled) && x86_turbo_on) {
-               x86_turbo_on = false;
+               cpu_set((int)currprefs.x86_speed_throttle);
        }
 }
 
@@ -3161,15 +3180,6 @@ static void ew(uae_u8 *acmemory, int addr, uae_u8 value)
        }
 }
 
-static void setrombank(struct x86_bridge *xb, int start, int len)
-{
-       while (len > 0) {
-               xb->rombank[start / 4096] = 1;
-               start += 4096;
-               len -= 4096;
-       }
-}
-
 static void bridge_reset(struct x86_bridge *xb)
 {
        xb->x86_reset = true;
@@ -3177,22 +3187,11 @@ static void bridge_reset(struct x86_bridge *xb)
        xb->amiga_forced_interrupts = false;
        xb->amiga_irq = false;
        xb->pc_irq3a = xb->pc_irq3b = xb->pc_irq7 = false;
-       x86_turbo_allowed = false;
+       xb->mode_register = -1;
        x86_cpu_active = false;
-       x86_instruction_count = DEFAULT_X86_INSTRUCTION_COUNT;
-       memset(xb->amiga_io, 0, 0x10000);
+       memset(xb->amiga_io, 0, 0x50000);
        memset(xb->io_ports, 0, 0x10000);
-       memset(xb->pc_ram, 0, 0x100000 - xb->bios_size);
-       memset(xb->rombank, 0, sizeof xb->rombank);
-
-       for (int i = 0; i < 2; i++) {
-               if (x86_xrom_end[i] - x86_xrom_start[i] > 0) {
-                       memcpy(xb->pc_ram + x86_xrom_start[i], xb->pc_rom + x86_xrom_start[i], x86_xrom_end[i] - x86_xrom_start[i]);
-                       setrombank(xb, x86_xrom_start[i], x86_xrom_end[i] - x86_xrom_start[i]);
-               }
-       }
-       memcpy(xb->pc_ram + 0x100000 - xb->bios_size, xb->pc_rom + 0x100000 - xb->bios_size, xb->bios_size);
-       setrombank(xb, 0x100000 - xb->bios_size, xb->bios_size);
+       memset(xb->pc_ram, 0, xb->pc_maxbaseram);
 
        if (xb->ne2000_isa)
                xb->ne2000_isa->reset(xb->ne2000_isa_board_state);
@@ -3202,26 +3201,16 @@ static void bridge_reset(struct x86_bridge *xb)
        xb->amiga_io[IO_INTERRUPT_MASK] = 0xff;
        xb->amiga_io[IO_MODE_REGISTER] = 0x00;
        xb->amiga_io[IO_PC_INTERRUPT_STATUS] = 0xfe;
-       x86_cmos_bank = 0;
        memset(xb->vlsi_regs, 0, sizeof xb->vlsi_regs);
 
-       if (xb->type >= TYPE_2286) {
-               int sel1 = (xb->settings >> 10) & 1;
-               int sel2 = (xb->settings >> 11) & 1;
-               // only A0000 or D0000 is valid for AT
-               if ((!sel1 && !sel2) || (sel1 && sel2)) {
-                       sel1 = 0;
-                       sel2 = 1;
-               }
-               xb->amiga_io[IO_MODE_REGISTER] |= sel1 << 5;
-               xb->amiga_io[IO_MODE_REGISTER] |= sel2 << 6;
-       }
-       if (xb->type == TYPE_2386)
-               x86_turbo_allowed = true;
+       int sel1 = (xb->settings >> 10) & 1;
+       int sel2 = (xb->settings >> 11) & 1;
+       xb->amiga_io[IO_MODE_REGISTER] |= sel1 << 5;
+       xb->amiga_io[IO_MODE_REGISTER] |= sel2 << 6;
 
        x86_bridge_sync_change();
-       inittiming();
        floppy_hardreset();
+       pcem_close();
 }
 
 int is_x86_cpu(struct uae_prefs *p)
@@ -3253,7 +3242,194 @@ int is_x86_cpu(struct uae_prefs *p)
 static void ne2000_isa_irq_callback(struct pci_board_state *pcibs, bool irq)
 {
        struct x86_bridge *xb = bridges[0];
-       x86_doirq(xb->ne2000_irq);
+       if (irq)
+               x86_doirq(xb->ne2000_irq);
+       else
+               x86_clearirq(xb->ne2000_irq);
+}
+
+void x86_xt_ide_bios(struct zfile *z, struct romconfig *rc)
+{
+       struct x86_bridge *xb = bridges[0];
+       uae_u32 addr = 0;
+       if (!xb || !z)
+               return;
+       switch (rc->device_settings)
+       {
+               case 0:
+               addr = 0xcc000;
+               break;
+               case 1:
+               addr = 0xdc000;
+               break;
+               case 2:
+               default:
+               addr = 0xec000;
+               break;
+       }
+       xtiderom = xcalloc(uae_u8, 0x4000);
+       zfile_fread(xtiderom, 1, 0x4000, z);
+       mem_mapping_add(&bios_mapping[5], addr, 0x4000, mem_read_romext2, mem_read_romextw2, mem_read_romextl2, mem_write_null, mem_write_nullw, mem_write_nulll, xtiderom, MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM, 0);
+}
+
+void *sb_1_init();
+void *sb_15_init();
+void *sb_2_init();
+void *sb_pro_v1_init();
+void *sb_pro_v2_init();
+void *sb_16_init();
+void *cms_init();
+
+static int x86_global_settings;
+
+int device_get_config_int(char *s)
+{
+       if (x86_global_settings < 0)
+               return 0;
+       if (!strcmp(s, "addr")) {
+               int io = 0x210 + ((x86_global_settings >> 3) & 7) * 0x10;
+               return io;
+       } else if (!strcmp(s, "irq")) {
+               int irq = (x86_global_settings >> 6) & 7;
+               if (irq == 0)
+                       return 2;
+               if (irq == 1)
+                       return 3;
+               if (irq == 2)
+                       return 5;
+               if (irq == 3)
+                       return 7;
+               if (irq == 4)
+                       return 10;
+               return 5;
+       } else if (!strcmp(s, "dma")) {
+               int irq = (x86_global_settings >> 9) & 1;
+               return irq ? 3 : 1;
+       } else if (!strcmp(s, "opl_emu")) {
+               int opl = (x86_global_settings >> 10) & 1;
+               return opl ? 1 : 0;
+       }
+       return 0;
+}
+
+static void set_sb_emu(struct x86_bridge *xb)
+{
+       if (!is_board_enabled(&currprefs, ROMTYPE_SBISA, 0))
+               return;
+       void *p = NULL, *c = NULL;
+       struct romconfig *rc = get_device_romconfig(&currprefs, ROMTYPE_SBISA, 0);
+       x86_global_settings = rc->device_settings;
+       int model = (x86_global_settings >> 0) & 7;
+       switch (model)
+       {
+       case 0:
+               c = cms_init();
+               p = sb_1_init();
+               break;
+       case 1:
+               c = cms_init();
+               p = sb_15_init();
+               break;
+       case 2:
+               c = cms_init();
+               p = sb_2_init();
+               break;
+       case 3:
+               p = sb_pro_v1_init();
+               break;
+       case 4:
+               p = sb_pro_v2_init();
+               break;
+       case 5:
+               p = sb_16_init();
+               break;
+       }
+       x86_global_settings = -1;
+       xb->sb_base = p;
+       xb->cms_base = c;
+       xb->sound_emu = true;
+}
+
+static void x86_ne2000(struct x86_bridge *xb)
+{
+       if (!is_board_enabled(&currprefs, ROMTYPE_NE2KISA, 0))
+               return;
+       struct romconfig *rc = get_device_romconfig(&currprefs, ROMTYPE_NE2KISA, 0);
+       if (rc) {
+               xb->ne2000_isa = &ne2000_pci_board;
+               xb->ne2000_isa_board_state = xcalloc(pci_board_state, 1);
+               xb->ne2000_isa_board_state->irq_callback = ne2000_isa_irq_callback;
+               switch (rc->device_settings & 7)
+               {
+               case 0:
+                       xb->ne2000_io = 0x240;
+                       break;
+               case 1:
+                       xb->ne2000_io = 0x260;
+                       break;
+               case 2:
+                       xb->ne2000_io = 0x280;
+                       break;
+               case 3:
+                       xb->ne2000_io = 0x2a0;
+                       break;
+               case 4:
+               default:
+                       xb->ne2000_io = 0x300;
+                       break;
+               case 5:
+                       xb->ne2000_io = 0x320;
+                       break;
+               case 6:
+                       xb->ne2000_io = 0x340;
+                       break;
+               case 7:
+                       xb->ne2000_io = 0x360;
+                       break;
+               }
+               switch ((rc->device_settings >> 3) & 15)
+               {
+               case 0:
+                       xb->ne2000_irq = 3;
+                       break;
+               case 1:
+                       xb->ne2000_irq = 4;
+                       break;
+               case 2:
+                       xb->ne2000_irq = 5;
+                       break;
+               case 3:
+               default:
+                       xb->ne2000_irq = 7;
+                       break;
+               case 4:
+                       xb->ne2000_irq = 9;
+                       break;
+               case 5:
+                       xb->ne2000_irq = 10;
+                       break;
+               case 6:
+                       xb->ne2000_irq = 11;
+                       break;
+               case 7:
+                       xb->ne2000_irq = 12;
+                       break;
+               case 8:
+                       xb->ne2000_irq = 15;
+                       break;
+               }
+               struct romconfig *rc = get_device_romconfig(&currprefs, ROMTYPE_NE2KISA, 0);
+               struct autoconfig_info aci = { 0 };
+               aci.rc = rc;
+               if (xb->ne2000_isa->init(xb->ne2000_isa_board_state, &aci)) {
+                       write_log(_T("NE2000 ISA configured, IO=%3X, IRQ=%d\n"), xb->ne2000_io, xb->ne2000_irq);
+               }
+               else {
+                       xb->ne2000_isa = NULL;
+                       xfree(xb->ne2000_isa_board_state);
+                       xb->ne2000_isa_board_state = NULL;
+               }
+       }
 }
 
 static void load_vga_bios(void)
@@ -3262,54 +3438,82 @@ static void load_vga_bios(void)
        if (!xb || !ISVGA())
                return;
        struct zfile *zf = read_device_rom(&currprefs, ROMTYPE_x86_VGA, 0, NULL);
-       x86_xrom_start[1] = 0xc0000;
-       x86_xrom_end[1] = x86_xrom_start[1];
        if (zf) {
-               int size = zfile_fread(xb->pc_rom + x86_xrom_start[1], 1, 65536, zf);
-               write_log(_T("X86 VGA BIOS '%s' loaded, %08x %d bytes\n"), zfile_getname(zf), x86_xrom_start[1], size);
+               int size = zfile_fread(romext, 1, 32768, zf);
+               write_log(_T("X86 VGA BIOS '%s' loaded, %08x %d bytes\n"), zfile_getname(zf), 0xc0000, size);
                zfile_fclose(zf);
-               x86_xrom_end[1] += size;
-               x86_xrom_end[1] += 4095;
-               x86_xrom_end[1] &= ~4095;
-               memcpy(xb->pc_ram + x86_xrom_start[1], xb->pc_rom + x86_xrom_start[1], x86_xrom_end[1] - x86_xrom_start[1]);
-               setrombank(xb, x86_xrom_start[1], x86_xrom_end[1] - x86_xrom_start[1]);
+               mem_mapping_add(&bios_mapping[4], 0xc0000, 0x8000, mem_read_romext, mem_read_romextw, mem_read_romextl, mem_write_null, mem_write_nullw, mem_write_nulll, romext, MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM, 0);
        }
-       if (xb->dosbox_cpu) {
-               MEM_ShutDown(dosbox_sec);
-               MEM_Init(dosbox_sec);
-               MEM_SetVGAHandler();
+}
+
+static void set_vga(struct x86_bridge *xb)
+{
+       // load vga bios
+       xb->vgaboard = -1;
+       for (int i = 0; i < MAX_RTG_BOARDS; i++) {
+               if (currprefs.rtgboards[i].rtgmem_type == GFXBOARD_VGA) {
+                       xb->vgaboard = i;
+                       x86_vga_board = i;
+                       xb->vgaboard_vram = currprefs.rtgboards[i].rtgmem_size;
+                       load_vga_bios();
+                       mem_mapping_add(&xb->vgamem, 0xa0000, 0x20000, vga_readb, vga_readw, vga_readl, vga_writeb, vga_writew, vga_writel, NULL, MEM_MAPPING_EXTERNAL, NULL);
+                       mem_mapping_add(&xb->vgalfbmem, 0x100000, 0x00200000, vgalfb_readb, vgalfb_readw, vgalfb_readl, vgalfb_writeb, vgalfb_writew, vgalfb_writel, NULL, MEM_MAPPING_EXTERNAL, NULL);
+                       mem_mapping_disable(&xb->vgalfbmem);
+                       break;
+               }
        }
 }
 
-void x86_xt_ide_bios(struct zfile *z, struct romconfig *rc)
+void mouse_serial_poll(int x, int y, int z, int b, void *p);
+void mouse_ps2_poll(int x, int y, int z, int b, void *p);
+
+void x86_mouse(int port, int x, int y, int z, int b)
 {
        struct x86_bridge *xb = bridges[0];
-       uae_u32 addr = 0;
-       if (!xb || !z)
+       if (!xb || !xb->mouse_port || !xb->mouse_base || xb->mouse_port != port + 1)
                return;
-       switch (rc->device_settings)
+       switch (xb->mouse_type)
        {
                case 0:
-               addr = 0xcc000;
+               default:
+               mouse_serial_poll(x, y, z, b, xb->mouse_base);
                break;
                case 1:
-               addr = 0xdc000;
-               break;
                case 2:
-               default:
-               addr = 0xec000;
+               mouse_ps2_poll(x, y, z, b, xb->mouse_base);
                break;
        }
-       x86_xrom_start[0] = addr;
-       x86_xrom_end[0] = x86_xrom_start[0] + 0x4000;
-       zfile_fread(xb->pc_rom + x86_xrom_start[0], 1, 32768, z);
-       memcpy(xb->pc_ram + x86_xrom_start[0], xb->pc_rom + x86_xrom_start[0], x86_xrom_end[0] - x86_xrom_start[0]);
-       setrombank(xb, x86_xrom_start[0], x86_xrom_end[0] - x86_xrom_start[0]);
-       if (xb->dosbox_cpu) {
-               MEM_ShutDown(dosbox_sec);
-               MEM_Init(dosbox_sec);
-               if (ISVGA()) {
-                       MEM_SetVGAHandler();
+}
+
+void *mouse_serial_init();
+void *mouse_ps2_init();
+void *mouse_intellimouse_init();
+void serial1_init(uint16_t addr, int irq);
+
+static void set_mouse(struct x86_bridge *xb)
+{
+       if (!is_board_enabled(&currprefs, ROMTYPE_X86MOUSE, 0))
+               return;
+       struct romconfig *rc = get_device_romconfig(&currprefs, ROMTYPE_X86MOUSE, 0);
+       if (rc) {
+               xb->mouse_port = (rc->device_settings & 3) + 1;
+               xb->mouse_type = (rc->device_settings >> 2) & 3;
+               switch (xb->mouse_type)
+               {
+                       case 0:
+                       default:
+                       ps2_mouse_supported = false;
+                       serial1_init(0x3f8, 4);
+                       xb->mouse_base = mouse_serial_init();
+                       break;
+                       case 1:
+                       ps2_mouse_supported = true;
+                       xb->mouse_base = mouse_ps2_init();
+                       break;
+                       case 2:
+                       ps2_mouse_supported = true;
+                       xb->mouse_base = mouse_intellimouse_init();
+                       break;
                }
        }
 }
@@ -3324,10 +3528,11 @@ bool x86_bridge_init(struct autoconfig_info *aci, uae_u32 romtype, int type)
 
        if (type >= TYPE_2286) {
                ac = type >= TYPE_2386 ? a2386_autoconfig : a1060_autoconfig;
-       } else {
+       }
+       else {
                ac = a1060_autoconfig;
-       }       
-               
+       }
+
        for (int i = 0; i < 16; i++) {
                ew(aci->autoconfig_raw, i * 4, ac[i]);
        }
@@ -3342,156 +3547,33 @@ bool x86_bridge_init(struct autoconfig_info *aci, uae_u32 romtype, int type)
        memcpy(xb->acmemory, aci->autoconfig_raw, sizeof aci->autoconfig_raw);
        bridges[0] = xb;
        xb->rc = rc;
+       x86_global_settings = -1;
 
        xb->type = type;
 
        xb->io_ports = xcalloc(uae_u8, 0x10000);
-       xb->amiga_io = xcalloc(uae_u8, 0x10000);
+       xb->amiga_io = xcalloc(uae_u8, 0x50000);
+       xb->amiga_buffer = xb->amiga_io + 0x10000;
+       xb->amiga_parameter = xb->amiga_io + 0x20000;
+       xb->amiga_mono = xb->amiga_io + 0x30000;
+       xb->amiga_color = xb->amiga_io + 0x40000;
 
-       x86_xrom_start[0] = x86_xrom_end[0] = 0;
-       x86_xrom_start[1] = x86_xrom_end[1] = 0;
        xb->settings = rc->device_settings;
        if (xb->type >= TYPE_2286) {
-               xb->dosbox_cpu = ((xb->settings >> 19) & 3) + 1;
-               xb->dosbox_cpu_arch = (xb->settings >> 23) & 7;
                xb->settings |= 0xff;
-               xb->pc_maxram = (1024 * 1024) << ((xb->settings >> 16) & 7);
                xb->bios_size = 65536;
        } else {
-               xb->dosbox_cpu = (xb->settings >> 19) & 7;
-               xb->dosbox_cpu_arch = (xb->settings >> 23) & 7;
-               xb->pc_maxram = 1 * 1024 * 1024;
                xb->bios_size = 32768;
        }
 
-       xb->pc_ram = xcalloc(uae_u8, xb->pc_maxram + 1 * 1024 * 1024);
-       xb->pc_rom = xcalloc(uae_u8, 0x100000);
-       x86_memsize = xb->pc_maxram;
-       mono_start =  xb->pc_ram + 0xb0000;
-       mono_end =    xb->pc_ram + 0xb2000;
-       color_start = xb->pc_ram + 0xb8000;
-       color_end =   xb->pc_ram + 0xc0000;
-       x86_biosstart = 0x100000 - xb->bios_size;
-       MemBase = xb->pc_ram;
-
-       if (xb->dosbox_cpu) {
-               ticksDone = 0;
-               ticksScheduled = 0;
-               x86_fpu_enabled = (xb->settings >> 22) & 1;
-               dosbox_sec = new Section_prop("dummy");
-               MEM_Init(dosbox_sec);
-               PAGING_Init(dosbox_sec);
-               CMOS_Init(dosbox_sec, xb->type == TYPE_2386 ? 0x7f : 0x3f);
-               PIC_Init(dosbox_sec);
-               TIMER_Init(dosbox_sec);
-               FPU_Init(dosbox_sec);
-               if (xb->type >= TYPE_2286) {
-                       TCHAR path[MAX_DPATH];
-                       cfgfile_resolve_path_out_load(currprefs.flashfile, path, MAX_DPATH, PATH_ROM);
-                       xb->cmossize = xb->type == TYPE_2386 ? 192 : 64;
-                       xb->cmosfile = zfile_fopen(path, _T("rb+"), ZFD_NORMAL);
-                       if (!xb->cmosfile) {
-                               xb->cmosfile = zfile_fopen(path, _T("wb"));
-                       }
-                       memset(xb->cmosregs, 0, sizeof xb->cmosregs);
-                       if (xb->cmosfile) {
-                               if (zfile_fread(xb->cmosregs, 1, xb->cmossize, xb->cmosfile) == xb->cmossize) {
-                                       x86_cmos_regs(xb->cmosregs);
-                               }
-                       }
-               }
-       }
+       // PC Spekaer?
+       xb->pc_speaker = true;
+       xb->sound_emu = (xb->settings >> 13) & 1;
 
-       if (is_board_enabled(&currprefs, ROMTYPE_NE2KISA, 0)) {
-               struct romconfig *rc = get_device_romconfig(&currprefs, ROMTYPE_NE2KISA, 0);
-               if (rc) {
-                       xb->ne2000_isa = &ne2000_pci_board;
-                       xb->ne2000_isa_board_state = xcalloc(pci_board_state, 1);
-                       xb->ne2000_isa_board_state->irq_callback = ne2000_isa_irq_callback;
-                       switch (rc->device_settings & 7)
-                       {
-                               case 0:
-                               xb->ne2000_io = 0x240;
-                               break;
-                               case 1:
-                               xb->ne2000_io = 0x260;
-                               break;
-                               case 2:
-                               xb->ne2000_io = 0x280;
-                               break;
-                               case 3:
-                               xb->ne2000_io = 0x2a0;
-                               break;
-                               case 4:
-                               default:
-                               xb->ne2000_io = 0x300;
-                               break;
-                               case 5:
-                               xb->ne2000_io = 0x320;
-                               break;
-                               case 6:
-                               xb->ne2000_io = 0x340;
-                               break;
-                               case 7:
-                               xb->ne2000_io = 0x360;
-                               break;
-                       }
-                       switch ((rc->device_settings >> 3) & 15)
-                       {
-                               case 0:
-                               xb->ne2000_irq = 3;
-                               break;
-                               case 1:
-                               xb->ne2000_irq = 4;
-                               break;
-                               case 2:
-                               xb->ne2000_irq = 5;
-                               break;
-                               case 3:
-                               default:
-                               xb->ne2000_irq = 7;
-                               break;
-                               case 4:
-                               xb->ne2000_irq = 9;
-                               break;
-                               case 5:
-                               xb->ne2000_irq = 10;
-                               break;
-                               case 6:
-                               xb->ne2000_irq = 11;
-                               break;
-                               case 7:
-                               xb->ne2000_irq = 12;
-                               break;
-                               case 8:
-                               xb->ne2000_irq = 15;
-                               break;
-                       }
-                       struct romconfig *rc = get_device_romconfig(&currprefs, ROMTYPE_NE2KISA, 0);
-                       struct autoconfig_info aci = { 0 };
-                       aci.rc = rc;
-                       if (xb->ne2000_isa->init(xb->ne2000_isa_board_state, &aci)) {
-                               write_log(_T("NE2000 ISA configured, IO=%3X, IRQ=%d\n"), xb->ne2000_io, xb->ne2000_irq);
-                       } else {
-                               xb->ne2000_isa = NULL;
-                               xfree(xb->ne2000_isa_board_state);
-                               xb->ne2000_isa_board_state = NULL;
-                       }
-               }
-       }
+       xb->pc_rom = xcalloc(uae_u8, 0x20000);
+       memset(xb->pc_rom, 0xff, 0x20000);
 
-       xb->vgaboard = -1;
-       for (int i = 0; i < MAX_RTG_BOARDS; i++) {
-               if (currprefs.rtgboards[i].rtgmem_type == GFXBOARD_VGA) {
-                       xb->vgaboard = i;
-                       x86_vga_board = i;
-                       if (xb->dosbox_cpu) {
-                               MEM_SetVGAHandler();
-                       }
-                       load_vga_bios();
-                       break;
-               }
-       }
+       x86_ne2000(xb);
 
        xb->pc_jumpers = (xb->settings & 0xff) ^ ((0x80 | 0x40) | (0x20 | 0x10 | 0x01 | 0x02));
 
@@ -3511,17 +3593,189 @@ bool x86_bridge_init(struct autoconfig_info *aci, uae_u32 romtype, int type)
                break;
        }
 
+       romset = ROM_GENXT;
+       shadowbios = 0;
+       enable_sync = 1;
+
+       switch (xb->type)
+       {
+       case TYPE_SIDECAR:
+               model = 0;
+               cpu_manufacturer = 0;
+               cpu = 0; // 4.77MHz
+               break;
+       case TYPE_2088:
+               model = 0;
+               cpu_manufacturer = 0;
+               cpu = 0; // 4.77MHz
+               break;
+       case TYPE_2088T:
+               model = 0;
+               cpu_manufacturer = 0;
+               cpu = 0; // 4.77MHz
+               break;
+       case TYPE_2286:
+               model = 1;
+               cpu_manufacturer = 0;
+               cpu = 1; // 8MHz
+               break;
+       case TYPE_2386:
+               model = 2;
+               cpu_manufacturer = 0;
+               cpu = 2; // 25MHz
+               break;
+       }
+       if (rc->configtext[0]) {
+               MODEL *m = &models[model];
+               int mannum = 0;
+               while (m->cpu[mannum].cpus) {
+                       CPU *cpup = m->cpu[mannum].cpus;
+                       int cpunum = 0;
+                       while(cpup[cpunum].cpu_type >= 0) {
+                               TCHAR *cpuname = au(cpup[cpunum].name);
+                               if (!_tcsicmp(rc->configtext, cpuname)) {
+                                       cpu_manufacturer = mannum;
+                                       cpu = cpunum;
+                                       write_log(_T("CPU override = %s\n"), cpuname);
+                               }
+                               xfree(cpuname);
+                               cpunum++;
+                       }
+                       mannum++;
+               }
+       }
+
+       cpu_set((int)currprefs.x86_speed_throttle);
+       if (xb->type >= TYPE_2286) {
+               mem_size = (1024 * 1024) << ((xb->settings >> 16) & 7);
+       } else {
+               mem_size = xb->pc_maxbaseram;
+       }
+       mem_size /= 1024;
+       mem_init();
+       xb->pc_ram = ram;
+       if (xb->type < TYPE_2286) {
+               mem_set_704kb();
+       }
+
        bridge_reset(xb);
 
+       timer_reset();
+       dma_init();
+       pit_init();
+       pic_init();
+       if (xb->type >= TYPE_2286) {
+               AT = 1;
+               nvr_init();
+               TCHAR path[MAX_DPATH];
+               cfgfile_resolve_path_out_load(currprefs.flashfile, path, MAX_DPATH, PATH_ROM);
+               xb->cmossize = xb->type == TYPE_2386 ? 192 : 64;
+               xb->cmosfile = zfile_fopen(path, _T("rb+"), ZFD_NORMAL);
+               if (!xb->cmosfile) {
+                       xb->cmosfile = zfile_fopen(path, _T("wb"));
+               }
+               memset(nvrram, 0, sizeof nvrram);
+               if (xb->cmosfile) {
+                       zfile_fread(nvrram, 1, xb->cmossize, xb->cmosfile);
+               }
+               loadnvr();
+               nvrmask = 127;
+               pit_set_out_func(&pit, 1, pit_refresh_timer_at);
+               keyboard_at_init();
+               keyboard_at_init_ps2();
+               dma16_init();
+               pic2_init();
+       } else {
+               AT = 0;
+               pit_set_out_func(&pit, 1, pit_refresh_timer_xt);
+       }
+       pic_reset();
+       dma_reset();
+       cpu_set_turbo(0);
+       cpu_set_turbo(1);
+       codegen_init();
+
        // load bios
-       if (!load_rom_rc(rc, romtype, xb->bios_size, 0, xb->pc_rom + 0x100000 - xb->bios_size, xb->bios_size, LOADROM_FILL)) {
+       if (!load_rom_rc(rc, romtype, xb->bios_size, 0, xb->pc_rom, xb->bios_size, LOADROM_FILL)) {
                error_log(_T("Bridgeboard BIOS failed to load"));
                x86_bridge_free();
                aci->addrbank = &expamem_null;
                return false;
        }
-       memcpy(xb->pc_ram + 0x100000 - xb->bios_size, xb->pc_rom + 0x100000 - xb->bios_size, xb->bios_size);
-       setrombank(xb, 0x100000 - xb->bios_size, xb->bios_size);
+       rom = xb->pc_rom;
+       biosmask = xb->bios_size - 1;
+       if (xb->type < TYPE_2286) {
+               mem_mapping_add(&bios_mapping[0], 0xf8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x8000 & biosmask), MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM, 0);
+               mem_mapping_add(&bios_mapping[1], 0xfc000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0xc000 & biosmask), MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM, 0);
+       } else {
+               mem_mapping_add(&bios_mapping[0], 0xe0000, 0x08000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom, MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM, 0);
+               mem_mapping_add(&bios_mapping[1], 0xe8000, 0x08000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x8000 & biosmask), MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM, 0);
+               mem_mapping_add(&bios_mapping[2], 0xf0000, 0x08000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x10000 & biosmask), MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM, 0);
+               mem_mapping_add(&bios_mapping[3], 0xf8000, 0x08000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x18000 & biosmask), MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM, 0);
+               
+               mem_mapping_add(&bios_high_mapping[0], (AT && cpu_16bitbus) ? 0xfe0000 : 0xfffe0000, 0x08000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom, MEM_MAPPING_ROM, 0);
+               mem_mapping_add(&bios_high_mapping[1], (AT && cpu_16bitbus) ? 0xfe8000 : 0xfffe8000, 0x08000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x8000 & biosmask), MEM_MAPPING_ROM, 0);
+               mem_mapping_add(&bios_high_mapping[2], (AT && cpu_16bitbus) ? 0xff0000 : 0xffff0000, 0x08000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x10000 & biosmask), MEM_MAPPING_ROM, 0);
+               mem_mapping_add(&bios_high_mapping[3], (AT && cpu_16bitbus) ? 0xff8000 : 0xffff8000, 0x08000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x18000 & biosmask), MEM_MAPPING_ROM, 0);
+       }
+
+       set_vga(xb);
+
+       // buffer ram
+       xb->sharedio_buffer_mb.base = xb->amiga_buffer;
+       xb->sharedio_buffer_mb.mask = 0xffff;
+       mem_mapping_add(&xb->sharedio_buffer[0], 0xa0000, 0x10000,
+               mem_read_sharedb, mem_read_sharedw, mem_read_sharedl,
+               mem_write_sharedb, mem_write_sharedw, mem_write_sharedl,
+               xb->amiga_buffer, 0, &xb->sharedio_buffer_mb);
+       mem_mapping_add(&xb->sharedio_buffer[1], 0xd0000, 0x10000,
+               mem_read_sharedb, mem_read_sharedw, mem_read_sharedl,
+               mem_write_sharedb, mem_write_sharedw, mem_write_sharedl,
+               xb->amiga_buffer, 0, &xb->sharedio_buffer_mb);
+       mem_mapping_add(&xb->sharedio_buffer[2], 0xe0000, 0x10000,
+               mem_read_sharedb, mem_read_sharedw, mem_read_sharedl,
+               mem_write_sharedb, mem_write_sharedw, mem_write_sharedl,
+               xb->amiga_buffer, 0, &xb->sharedio_buffer_mb);
+
+       // mono ram
+       xb->sharedio_mono_mb.base = xb->amiga_mono;
+       xb->sharedio_mono_mb.mask = 0x1fff;
+       mem_mapping_add(&xb->sharedio_mono, 0xb0000, 0x2000,
+               mem_read_sharedb, mem_read_sharedw, mem_read_sharedl,
+               mem_write_sharedb, mem_write_sharedw, mem_write_sharedl,
+               xb->amiga_mono, 0, &xb->sharedio_mono_mb);
+
+       // color ram
+       xb->sharedio_color_mb.base = xb->amiga_color;
+       xb->sharedio_color_mb.mask = 0x7fff;
+       mem_mapping_add(&xb->sharedio_color, 0xb8000, 0x8000,
+               mem_read_sharedb, mem_read_sharedw, mem_read_sharedl,
+               mem_write_sharedb, mem_write_sharedw, mem_write_sharedl,
+               xb->amiga_color, 0, &xb->sharedio_color_mb);
+
+       // parameter ram
+       if (xb->type < TYPE_2286) {
+               xb->sharedio_parameter_mb.base = xb->amiga_parameter;
+               xb->sharedio_parameter_mb.mask = 0x3fff;
+               mem_mapping_add(&xb->sharedio_parameter, 0xf0000, 0x4000,
+                       mem_read_sharedb, mem_read_sharedw, mem_read_sharedl,
+                       mem_write_sharedb, mem_write_sharedw, mem_write_sharedl,
+                       xb->amiga_parameter, 0, &xb->sharedio_parameter_mb);
+       }
+
+       set_configurable_shared_io(xb);
+
+       if (xb->type == TYPE_2386) {
+               vlsi_init_mapping(xb);
+       }
+
+       sound_reset();
+       sound_speed_changed();
+       speaker_init();
+       set_sb_emu(xb);
+       sound_pos_global = xb->sound_emu ? 0 : -1;
+
+       set_mouse(xb);
 
        xb->bank = &x86_bridge_bank;
 
@@ -3529,134 +3783,159 @@ bool x86_bridge_init(struct autoconfig_info *aci, uae_u32 romtype, int type)
        return true;
 }
 
-bool a1060_init(struct autoconfig_info *aci)
-{
-       return x86_bridge_init(aci, ROMTYPE_A1060, TYPE_SIDECAR);
-}
-bool a2088xt_init(struct autoconfig_info *aci)
-{
-       return x86_bridge_init(aci, ROMTYPE_A2088, TYPE_2088);
-}
-bool a2088t_init(struct autoconfig_info *aci)
-{
-       return x86_bridge_init(aci, ROMTYPE_A2088T, TYPE_2088T);
-}
-bool a2286_init(struct autoconfig_info *aci)
-{
-       return x86_bridge_init(aci, ROMTYPE_A2286, TYPE_2286);
-}
-bool a2386_init(struct autoconfig_info *aci)
+void x86_map_lfb(int v)
 {
-       return x86_bridge_init(aci, ROMTYPE_A2386, TYPE_2386);
-}
+       struct x86_bridge *xb = bridges[0];
+       if (!xb)
+               return;
+       uae_u32 addr = v << 20;
 
-bool isa_expansion_init(struct autoconfig_info *aci)
-{
-       static const int parent[] = { ROMTYPE_A1060, ROMTYPE_A2088, ROMTYPE_A2088T, ROMTYPE_A2286, ROMTYPE_A2386, 0 };
-       aci->parent_romtype = parent;
-       aci->zorro = 0;
-       return true;
+       if (addr) {
+               mem_mapping_set_addr(&xb->vgalfbmem, addr, xb->vgaboard_vram);
+       } else {
+               mem_mapping_disable(&xb->vgalfbmem);
+       }
 }
 
-/* dosbox cpu core support stuff */
-
-void IO_WriteB(Bitu port, Bitu val)
-{
-       portout(port, val);
-}
-void IO_WriteW(Bitu port, Bitu val)
-{
-       portout16(port, val);
-}
-void IO_WriteD(Bitu port, Bitu val)
+void io_sethandler(uint16_t base, int size,
+       uint8_t(*inb)(uint16_t addr, void *priv),
+       uint16_t(*inw)(uint16_t addr, void *priv),
+       uint32_t(*inl)(uint16_t addr, void *priv),
+       void(*outb)(uint16_t addr, uint8_t  val, void *priv),
+       void(*outw)(uint16_t addr, uint16_t val, void *priv),
+       void(*outl)(uint16_t addr, uint32_t val, void *priv),
+       void *priv)
 {
-       portout32(port, val);
-}
-Bitu IO_ReadB(Bitu port)
-{
-       return portin(port);
-}
-Bitu IO_ReadW(Bitu port)
-{
-       return portin16(port);
-}
-Bitu IO_ReadD(Bitu port)
-{
-       return portin32(port);
-}
+       if (base + size > MAX_IO_PORT)
+               return;
 
-Bits CPU_Core_Prefetch_Run(void)
-{
-       return 0;
+       for (int i = 0; i < size; i++) {
+               int io = base + i;
+               port_inb[io] = inb;
+               port_inw[io] = inw;
+               port_inl[io] = inl;
+               port_outb[io] = outb;
+               port_outw[io] = outw;
+               port_outl[io] = outl;
+               port_priv[io] = priv;
+       }
 }
 
-bool CommandLine::FindCommand(unsigned int which, std::string & value)
-{
-       return false;
-}
-unsigned int CommandLine::GetCount(void)
+void io_removehandler(uint16_t base, int size,
+       uint8_t(*inb)(uint16_t addr, void *priv),
+       uint16_t(*inw)(uint16_t addr, void *priv),
+       uint32_t(*inl)(uint16_t addr, void *priv),
+       void(*outb)(uint16_t addr, uint8_t  val, void *priv),
+       void(*outw)(uint16_t addr, uint16_t val, void *priv),
+       void(*outl)(uint16_t addr, uint32_t val, void *priv),
+       void *priv)
 {
-       return 0;
+       if (base + size > MAX_IO_PORT)
+               return;
+
+       for (int i = 0; i < size; i++) {
+               int io = base + i;
+               port_inb[io] = NULL;
+               port_inw[io] = NULL;
+               port_inl[io] = NULL;
+               port_outb[io] = NULL;
+               port_outw[io] = NULL;
+               port_outl[io] = NULL;
+       }
 }
-CommandLine::CommandLine(int argc, char const * const argv[])
+
+static struct
 {
-}
-CommandLine::CommandLine(char const * const name, char const * const cmdline)
+       void(*get_buffer)(int32_t *buffer, int len, void *p);
+       void *priv;
+} sound_handlers[8];
+
+void sound_add_handler(void(*get_buffer)(int32_t *buffer, int len, void *p), void *p)
 {
+       sound_handlers[sound_handlers_num].get_buffer = get_buffer;
+       sound_handlers[sound_handlers_num].priv = p;
+       sound_handlers_num++;
 }
-void Section::AddDestroyFunction(SectionFunction func, bool canchange)
+
+void sound_speed_changed()
 {
+       sound_poll_latch = (int)((double)TIMER_USEC * (1000000.0 / currprefs.sound_freq));
 }
-int Section_prop::Get_int(string const&_propname) const
+
+void sound_poll(void *priv)
 {
-       return 0;
+       struct x86_bridge *xb = bridges[0];
+
+       sound_poll_time += sound_poll_latch;
+
+       if (x86_sndbuffer_filled[x86_sndbuffer_index]) {
+               return;
+       }
+
+       sound_pos_global++;
+       if (sound_pos_global == SOUNDBUFLEN) {
+               int32_t *p = x86_sndbuffer[x86_sndbuffer_index];
+               memset(p, 0, SOUNDBUFLEN * sizeof(int32_t) * 2);
+               for (int c = 0; c < sound_handlers_num; c++) {
+                       if (c > 0 || (c == 0 && xb->pc_speaker)) {
+                               sound_handlers[c].get_buffer(p, SOUNDBUFLEN, sound_handlers[c].priv);
+                       }
+               }
+               x86_sndbuffer_filled[x86_sndbuffer_index] = true;
+               x86_sndbuffer_index ^= 1;
+               sound_pos_global = 0;
+       }
 }
-const char* Section_prop::Get_string(string const& _propname) const
+
+void sound_reset()
 {
-       return NULL;
+       sound_handlers_num = 0;
+       sound_pos_global = 0;
+       x86_sndbuffer[0] = outbuffer1;
+       x86_sndbuffer[1] = outbuffer2;
+       x86_sndbuffer_filled[0] = x86_sndbuffer_filled[1] = false;
 }
-Prop_multival* Section_prop::Get_multival(string const& _propname) const
+
+void sound_set_cd_volume(unsigned int l, unsigned int r)
 {
-       return NULL;
+
 }
-void Section_prop::HandleInputline(string const& gegevens)
+
+void x86_update_sound(double clk)
 {
+       struct x86_bridge *xb = bridges[0];
+       x86_base_event_clock = clk;
+       if (xb) {
+               xb->audeventtime = x86_base_event_clock * CYCLE_UNIT / currprefs.sound_freq + 1;
+               sound_speed_changed();
+       }
 }
-void Section_prop::PrintData(FILE* outfile) const
+
+bool a1060_init(struct autoconfig_info *aci)
 {
+       return x86_bridge_init(aci, ROMTYPE_A1060, TYPE_SIDECAR);
 }
-Section_prop::~Section_prop()
+bool a2088xt_init(struct autoconfig_info *aci)
 {
+       return x86_bridge_init(aci, ROMTYPE_A2088, TYPE_2088);
 }
-string Section_prop::GetPropValue(string const& _property) const
+bool a2088t_init(struct autoconfig_info *aci)
 {
-       return NO_SUCH_PROPERTY;
+       return x86_bridge_init(aci, ROMTYPE_A2088T, TYPE_2088T);
 }
-
-void DOSBOX_RunMachine(void)
+bool a2286_init(struct autoconfig_info *aci)
 {
+       return x86_bridge_init(aci, ROMTYPE_A2286, TYPE_2286);
 }
-
-void GFX_SetTitle(Bit32s cycles, Bits frameskip, bool paused)
+bool a2386_init(struct autoconfig_info *aci)
 {
+       return x86_bridge_init(aci, ROMTYPE_A2386, TYPE_2386);
 }
 
-void E_Exit(char *format, ...)
-{
-       va_list parms;
-       va_start(parms, format);
-       char buffer[1000];
-       vsnprintf(buffer, sizeof(buffer), format, parms);
-       write_log("DOSBOX E_Exit: %s\n", buffer);
-       va_end(parms);
-}
-void GFX_ShowMsg(const char *format, ...)
+bool isa_expansion_init(struct autoconfig_info *aci)
 {
-       va_list parms;
-       va_start(parms, format);
-       char buffer[1000];
-       vsnprintf(buffer, sizeof(buffer), format, parms);
-       write_log("DOSBOX GFX_ShowMsg: %s\n", buffer);
-       va_end(parms);
+       static const int parent[] = { ROMTYPE_A1060, ROMTYPE_A2088, ROMTYPE_A2088T, ROMTYPE_A2286, ROMTYPE_A2386, 0 };
+       aci->parent_romtype = parent;
+       aci->zorro = 0;
+       return true;
 }
-