]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
3100b12
authorToni Wilen <twilen@winuae.net>
Sat, 14 Mar 2015 14:07:41 +0000 (16:07 +0200)
committerToni Wilen <twilen@winuae.net>
Sat, 14 Mar 2015 14:07:41 +0000 (16:07 +0200)
60 files changed:
a2091.cpp
amax.cpp
cdtv.cpp
cfgfile.cpp
cia.cpp
cpuboard.cpp
cpummu.cpp
cpummu30.cpp
custom.cpp
debug.cpp
devices.cpp
disk.cpp
drawing.cpp
expansion.cpp
filesys.cpp
gayle.cpp
hardfile.cpp
ide.cpp
idecontrollers.cpp
include/a2091.h
include/autoconf.h
include/cdtv.h
include/cpuboard.h
include/disk.h
include/filesys.h
include/gfxboard.h
include/ide.h
include/idecontrollers.h
include/memory.h
include/ncr9x_scsi.h
include/ncr_scsi.h
include/options.h
include/rommgr.h
include/scsi.h
include/sndboard.h
include/xwin.h
include/zarchive.h
include/zfile.h
inputdevice.cpp
main.cpp
memory.cpp
ncr9x_scsi.cpp
ncr_scsi.cpp
newcpu.cpp
od-win32/mman.cpp
od-win32/parser.cpp
od-win32/resources/resource.h
od-win32/resources/winuae.rc
od-win32/serial_win32.cpp
od-win32/win32.h
od-win32/win32gfx.cpp
od-win32/win32gui.cpp
od-win32/winuaechangelog.txt
ppc/ppc.cpp
rommgr.cpp
savestate.cpp
scsi.cpp
uaeexe.cpp
uaelib.cpp
zfile.cpp

index 1b10677ba6bdbbd58024d2e25cdc7a1a81231ac8..fd14965a6bd119521e621c6b552f178e2134b617 100644 (file)
--- a/a2091.cpp
+++ b/a2091.cpp
 #define XT_UNIT 7
 #define XT_SECTORS 17 /* hardwired */
 
-static struct wd_state wd_a2091;
-static struct wd_state wd_a2091_2;
-static struct wd_state wd_a3000;
-static struct wd_state wd_gvp;
-static struct wd_state wd_gvp_2;
-struct wd_state wd_cdtv;
-
-static struct wd_state *wda2091[] = {
-               &wd_a2091,
-               &wd_a2091_2
-};
+#define MAX_SCSI_UNITS 10
 
-static struct wd_state *wdscsi[] = {
-               &wd_a2091,
-               &wd_a2091_2,
-               &wd_a3000,
-               &wd_cdtv,
-               NULL
-};
+static struct wd_state *wd_a2091[MAX_DUPLICATE_EXPANSION_BOARDS];
+static struct wd_state *wd_a2090[MAX_DUPLICATE_EXPANSION_BOARDS];
+static struct wd_state *wd_a3000;
+static struct wd_state *wd_gvp[MAX_DUPLICATE_EXPANSION_BOARDS];
+struct wd_state *wd_cdtv;
 
-static struct wd_state *gvpscsi[] = {
-       &wd_gvp,
-       &wd_gvp_2
-};
+static struct wd_state *scsi_units[MAX_SCSI_UNITS + 1];
+
+static void freescsi(struct wd_state **wd)
+{
+       for (int i = 0; i < MAX_SCSI_UNITS; i++) {
+               if (scsi_units[i] == *wd) {
+                       scsi_units[i] = NULL;
+               }
+       }
+       if (*wd) {
+               scsi_freenative((*wd)->scsis);
+               xfree(*wd);
+       }
+       *wd = NULL;
+}
+
+static struct wd_state *allocscsi(struct wd_state **wd, struct romconfig *rc)
+{
+       struct wd_state *scsi;
+
+       freescsi(wd);
+       scsi = xcalloc(struct wd_state, 1);
+       for (int i = 0; i < MAX_SCSI_UNITS; i++) {
+               if (scsi_units[i] == NULL) {
+                       scsi_units[i] = scsi;
+                       if (rc)
+                               rc->unitdata = scsi;
+                       scsi->rc = rc;
+                       *wd = scsi;
+                       return scsi;
+               }
+       }
+       xfree(scsi);
+       return NULL;
+}
+
+static struct wd_state *getscsi(struct romconfig *rc)
+{
+       if (rc->unitdata)
+               return (struct wd_state*)rc->unitdata;
+       return NULL;
+}
+
+static struct wd_state *getscsiboard(uaecptr addr)
+{
+       for (int i = 0; scsi_units[i]; i++) {
+               if (!scsi_units[i]->baseaddress)
+                       return scsi_units[i];
+               if ((addr & ~scsi_units[i]->board_mask) == scsi_units[i]->baseaddress)
+                       return scsi_units[i];
+       }
+       return NULL;
+}
 
 static void reset_dmac(struct wd_state *wd)
 {
@@ -381,11 +418,13 @@ static bool is_dma_enabled(struct wd_state *wds)
 
 void rethink_a2091 (void)
 {
-       if (isirq (&wd_a2091) ||isirq (&wd_a2091_2) || isirq (&wd_a3000) || isirq(&wd_gvp) || isirq(&wd_gvp_2)) {
-               INTREQ_0(0x8000 | 0x0008);
+       for (int i = 0; i < MAX_SCSI_UNITS; i++) {
+               if (scsi_units[i] && isirq(scsi_units[i])) {
+                       INTREQ_0(0x8000 | 0x0008);
 #if A2091_DEBUG > 2 || A3000_DEBUG > 2
-               write_log (_T("Interrupt_RETHINK\n"));
+                       write_log (_T("Interrupt_RETHINK\n"));
 #endif
+               }
        }
 }
 
@@ -985,6 +1024,10 @@ static void wd_cmd_sel_xfer (struct wd_chip_state *wd, struct wd_state *wds, boo
                }
                wd->wdregs[WD_COMMAND_PHASE] = 0x30 + gettc (wd);
                settc (wd, 0);
+               if (scsi->direction <= 0) {
+                       scsi_emulate_cmd (scsi);
+               }
+               scsi_start_transfer (scsi);
        }
 
        if (wd->wdregs[WD_COMMAND_PHASE] <= 0x41) {
@@ -1003,10 +1046,6 @@ static void wd_cmd_sel_xfer (struct wd_chip_state *wd, struct wd_state *wds, boo
 
        // target replied or start/continue data phase (if data available)
        if (wd->wdregs[WD_COMMAND_PHASE] == 0x44) {
-               if (scsi->direction <= 0) {
-                       scsi_emulate_cmd (scsi);
-               }
-               scsi_start_transfer (scsi);
                wd->wdregs[WD_COMMAND_PHASE] = 0x45;
        }
                
@@ -1331,7 +1370,7 @@ static void scsi_hsync2_a2091 (struct wd_state *wds)
 {
        struct wd_chip_state *wd = &wds->wc;
 
-       if (!wds->enabled)
+       if (!wds || !wds->enabled)
                return;
        scsi_hsync_check_dma(wds);
        if (wds->cdmac.dmac_dma > 0 && (wds->cdmac.xt_status & (XT_STAT_INPUT | XT_STAT_REQUEST))) {
@@ -1346,7 +1385,7 @@ static void scsi_hsync2_a2091 (struct wd_state *wds)
 
 static void scsi_hsync2_gvp (struct wd_state *wds)
 {
-       if (!wds->enabled)
+       if (!wds || !wds->enabled)
                return;
        scsi_hsync_check_dma(wds);
        wd_check_interrupt(wds, false);
@@ -1354,12 +1393,13 @@ static void scsi_hsync2_gvp (struct wd_state *wds)
 
 void scsi_hsync (void)
 {
-       scsi_hsync2_a2091(&wd_a2091);
-       scsi_hsync2_a2091(&wd_a2091_2);
-       scsi_hsync2_a2091(&wd_a3000);
-       scsi_hsync2_a2091(&wd_cdtv);
-       scsi_hsync2_gvp(&wd_gvp);
-       scsi_hsync2_gvp(&wd_gvp_2);
+       for (int i = 0; i < MAX_DUPLICATE_EXPANSION_BOARDS; i++) {
+               scsi_hsync2_a2091(wd_a2091[i]);
+               scsi_hsync2_a2091(wd_a2090[i]);
+               scsi_hsync2_gvp(wd_gvp[i]);
+       }
+       scsi_hsync2_a2091(wd_a3000);
+       scsi_hsync2_a2091(wd_cdtv);
 }
 
 
@@ -1410,7 +1450,7 @@ void wdscsi_put (struct wd_chip_state *wd, struct wd_state *wds, uae_u8 d)
        }
        if (!wd->wd_used) {
                wd->wd_used = 1;
-               write_log (_T("%s %s in use\n"), wds->name, WD33C93);
+               write_log (_T("%s %s in use\n"), wds->bank ? wds->bank->name : _T("built-in"), WD33C93);
        }
        if (wd->sasr == WD_COMMAND_PHASE) {
 #if WD33C93_DEBUG > 1
@@ -2241,7 +2281,6 @@ static void REGPARAM2 dmac_a2091_wput(struct wd_state *wd, uaecptr addr, uae_u32
 }
 
 extern addrbank dmaca2091_bank;
-extern addrbank dmaca2091_2_bank;
 
 static void REGPARAM2 dmac_a2091_bput(struct wd_state *wd, uaecptr addr, uae_u32 b)
 {
@@ -2251,16 +2290,16 @@ static void REGPARAM2 dmac_a2091_bput(struct wd_state *wd, uaecptr addr, uae_u32
        b &= 0xff;
        addr &= 65535;
        if (wd->autoconfig) {
-               addrbank *ab = wd == &wd_a2091 ? &dmaca2091_bank : &dmaca2091_2_bank;
                if (addr == 0x48 && !wd->configured) {
-                       map_banks_z2 (ab, b, 0x10000 >> 16);
+                       map_banks_z2 (wd->bank, b, 0x10000 >> 16);
+                       wd->baseaddress = b << 16;
                        wd->configured = 1;
-                       expamem_next (ab, NULL);
+                       expamem_next (wd->bank, NULL);
                        return;
                }
                if (addr == 0x4c && !wd->configured) {
                        wd->configured = 1;
-                       expamem_shutup(ab);
+                       expamem_shutup(wd->bank);
                        return;
                }
                if (!wd->configured)
@@ -2310,103 +2349,83 @@ static uae_u8 *REGPARAM2 dmac_a2091_xlate(struct wd_state *wd, uaecptr addr)
 
 static uae_u8 *REGPARAM2 dmac_a2091_xlate (uaecptr addr)
 {
-       return dmac_a2091_xlate(&wd_a2091, addr);
+       struct wd_state *wd = getscsiboard(addr);
+       if (wd)
+               return dmac_a2091_xlate(wd, addr);
+       return default_xlate(0);
 }
 static int REGPARAM2 dmac_a2091_check (uaecptr addr, uae_u32 size)
 {
-       return dmac_a2091_check(&wd_a2091, addr, size);
+       struct wd_state *wd = getscsiboard(addr);
+       if (wd)
+               return dmac_a2091_check(wd, addr, size);
+       return 0;
 }
 static uae_u32 REGPARAM2 dmac_a2091_lgeti (uaecptr addr)
 {
-       return dmac_a2091_lgeti(&wd_a2091, addr);
+       struct wd_state *wd = getscsiboard(addr);
+       if (wd)
+               return dmac_a2091_lgeti(wd, addr);
+       return 0;
 }
 static uae_u32 REGPARAM2 dmac_a2091_wgeti (uaecptr addr)
 {
-       return dmac_a2091_wgeti(&wd_a2091, addr);
+       struct wd_state *wd = getscsiboard(addr);
+       if (wd)
+               return dmac_a2091_wgeti(wd, addr);
+       return 0;
 }
 static uae_u32 REGPARAM2 dmac_a2091_bget (uaecptr addr)
 {
-       return dmac_a2091_bget(&wd_a2091, addr);
+       struct wd_state *wd = getscsiboard(addr);
+       if (wd)
+               return dmac_a2091_bget(wd, addr);
+       return 0;
 }
 static uae_u32 REGPARAM2 dmac_a2091_wget (uaecptr addr)
 {
-       return dmac_a2091_wget(&wd_a2091, addr);
+       struct wd_state *wd = getscsiboard(addr);
+       if (wd)
+               return dmac_a2091_wget(wd, addr);
+       return 0;
 }
 static uae_u32 REGPARAM2 dmac_a2091_lget (uaecptr addr)
 {
-       return dmac_a2091_lget(&wd_a2091, addr);
+       struct wd_state *wd = getscsiboard(addr);
+       if (wd)
+               return dmac_a2091_lget(wd, addr);
+       return 0;
 }
 static void REGPARAM2 dmac_a2091_bput (uaecptr addr, uae_u32 b)
 {
-       dmac_a2091_bput(&wd_a2091, addr, b);
+       struct wd_state *wd = getscsiboard(addr);
+       if (wd)
+               dmac_a2091_bput(wd, addr, b);
 }
 static void REGPARAM2 dmac_a2091_wput (uaecptr addr, uae_u32 b)
 {
-       dmac_a2091_wput(&wd_a2091, addr, b);
+       struct wd_state *wd = getscsiboard(addr);
+       if (wd)
+               dmac_a2091_wput(wd, addr, b);
 }
 static void REGPARAM2 dmac_a2091_lput (uaecptr addr, uae_u32 b)
 {
-       dmac_a2091_lput(&wd_a2091, addr, b);
-}
-
-static uae_u8 *REGPARAM2 dmac_a20912_xlate (uaecptr addr)
-{
-       return dmac_a2091_xlate(&wd_a2091_2, addr);
-}
-static int REGPARAM2 dmac_a20912_check (uaecptr addr, uae_u32 size)
-{
-       return dmac_a2091_check(&wd_a2091_2, addr, size);
-}
-static uae_u32 REGPARAM2 dmac_a20912_lgeti (uaecptr addr)
-{
-       return dmac_a2091_lgeti(&wd_a2091_2, addr);
-}
-static uae_u32 REGPARAM2 dmac_a20912_wgeti (uaecptr addr)
-{
-       return dmac_a2091_wgeti(&wd_a2091_2, addr);
-}
-static uae_u32 REGPARAM2 dmac_a20912_bget (uaecptr addr)
-{
-       return dmac_a2091_bget(&wd_a2091_2, addr);
-}
-static uae_u32 REGPARAM2 dmac_a20912_wget (uaecptr addr)
-{
-       return dmac_a2091_wget(&wd_a2091_2, addr);
-}
-static uae_u32 REGPARAM2 dmac_a20912_lget (uaecptr addr)
-{
-       return dmac_a2091_lget(&wd_a2091_2, addr);
-}
-static void REGPARAM2 dmac_a20912_bput (uaecptr addr, uae_u32 b)
-{
-       dmac_a2091_bput(&wd_a2091_2, addr, b);
-}
-static void REGPARAM2 dmac_a20912_wput (uaecptr addr, uae_u32 b)
-{
-       dmac_a2091_wput(&wd_a2091_2, addr, b);
-}
-static void REGPARAM2 dmac_a20912_lput (uaecptr addr, uae_u32 b)
-{
-       dmac_a2091_lput(&wd_a2091_2, addr, b);
+       struct wd_state *wd = getscsiboard(addr);
+       if (wd)
+               dmac_a2091_lput(wd, addr, b);
 }
 
 addrbank dmaca2091_bank = {
        dmac_a2091_lget, dmac_a2091_wget, dmac_a2091_bget,
        dmac_a2091_lput, dmac_a2091_wput, dmac_a2091_bput,
-       dmac_a2091_xlate, dmac_a2091_check, NULL, NULL, _T("A2091/A590"),
+       dmac_a2091_xlate, dmac_a2091_check, NULL, NULL, _T("A2090/A2091/A590"),
        dmac_a2091_lgeti, dmac_a2091_wgeti, ABFLAG_IO | ABFLAG_SAFE
 };
-addrbank dmaca2091_2_bank = {
-       dmac_a20912_lget, dmac_a20912_wget, dmac_a20912_bget,
-       dmac_a20912_lput, dmac_a20912_wput, dmac_a20912_bput,
-       dmac_a20912_xlate, dmac_a20912_check, NULL, NULL, _T("A2091/A590 #2"),
-       dmac_a20912_lgeti, dmac_a20912_wgeti, ABFLAG_IO | ABFLAG_SAFE
-};
+
 
 /* GVP Series I and II */
 
 extern addrbank gvp_bank;
-extern addrbank gvp_2_bank;
 
 static uae_u32 dmac_gvp_read_byte(struct wd_state *wd, uaecptr addr)
 {
@@ -2415,7 +2434,8 @@ static uae_u32 dmac_gvp_read_byte(struct wd_state *wd, uaecptr addr)
        addr &= wd->board_mask;
        if (addr < 0x3e) {
                v = wd->dmacmemory[addr];
-       } else if (addr >= GVP_ROM_OFFSET && addr < 65536) {
+       } else if ((addr & 0x8000) == GVP_ROM_OFFSET) {
+               addr &= 0xffff;
                if (wd->gdmac.series2) {
                        if (addr & 1) {
                                v = wd->gdmac.version;
@@ -2500,7 +2520,8 @@ static uae_u32 dmac_gvp_read_word(struct wd_state *wd, uaecptr addr)
        addr &= wd->board_mask;
        if (addr < 0x3e) {
                v = (wd->dmacmemory[addr] << 8) | wd->dmacmemory[addr + 1];
-       } else if (addr >= GVP_ROM_OFFSET && addr < 65536) {
+       } else if ((addr & 0x8000) == GVP_ROM_OFFSET) {
+               addr &= 0xffff;
                if (wd->gdmac.series2) {
                        if (wd->rom) {
                                if (wd->rombankswitcher && (addr & 0xffe0) == GVP_ROM_OFFSET)
@@ -2579,8 +2600,10 @@ static void dmac_gvp_write_byte(struct wd_state *wd, uaecptr addr, uae_u32 b)
 #if GVP_S1_DEBUG_IO > 1
                int off = wd->gdmac.bufoffset;
 #endif
-               wd->gdmac.buffer[wd->gdmac.bufoffset++] = b;
-               wd->gdmac.bufoffset &= wd->gdmac.s1_rammask;
+               if (!(addr & GVP_ROM_OFFSET)) {
+                       wd->gdmac.buffer[wd->gdmac.bufoffset++] = b;
+                       wd->gdmac.bufoffset &= wd->gdmac.s1_rammask;
+               }
 #if GVP_S1_DEBUG_IO > 1
                write_log(_T("gvp_s1_bput sram %d %04x\n"), off, b);
 #endif
@@ -2680,10 +2703,12 @@ static void dmac_gvp_write_word(struct wd_state *wd, uaecptr addr, uae_u32 b)
 #if GVP_S1_DEBUG_IO > 1
                int off = wd->gdmac.bufoffset;
 #endif
-               wd->gdmac.buffer[wd->gdmac.bufoffset++] = b >> 8;
-               wd->gdmac.bufoffset &= wd->gdmac.s1_rammask;
-               wd->gdmac.buffer[wd->gdmac.bufoffset++] = b;
-               wd->gdmac.bufoffset &= wd->gdmac.s1_rammask;
+               if (!(addr & GVP_ROM_OFFSET)) {
+                       wd->gdmac.buffer[wd->gdmac.bufoffset++] = b >> 8;
+                       wd->gdmac.bufoffset &= wd->gdmac.s1_rammask;
+                       wd->gdmac.buffer[wd->gdmac.bufoffset++] = b;
+                       wd->gdmac.bufoffset &= wd->gdmac.s1_rammask;
+               }
 #if GVP_S1_DEBUG_IO > 1
                write_log(_T("gvp_s1_wput sram %d %04x\n"), off, b);
 #endif
@@ -2801,16 +2826,16 @@ static void REGPARAM2 dmac_gvp_bput(struct wd_state *wd, uaecptr addr, uae_u32 b
        b &= 0xff;
        addr &= wd->board_mask;
        if (wd->autoconfig) {
-               addrbank *ab = wd == &wd_gvp ? &gvp_bank : &gvp_2_bank;
                if (addr == 0x48 && !wd->configured) {
-                       map_banks_z2(ab, b, (wd->board_mask + 1) >> 16);
+                       map_banks_z2(wd->bank, b, (wd->board_mask + 1) >> 16);
+                       wd->baseaddress = b << 16;
                        wd->configured = 1;
-                       expamem_next(ab, NULL);
+                       expamem_next(wd->bank, NULL);
                        return;
                }
                if (addr == 0x4c && !wd->configured) {
                        wd->configured = 1;
-                       expamem_shutup(ab);
+                       expamem_shutup(wd->bank);
                        return;
                }
                if (!wd->configured)
@@ -2846,58 +2871,71 @@ static uae_u32 REGPARAM2 dmac_gvp_lgeti(struct wd_state *wd, uaecptr addr)
        return v;
 }
 
-static int REGPARAM2 dmac_gvp_check(struct wd_state *wd, uaecptr addr, uae_u32 size)
-{
-       return 1;
-}
-
-static uae_u8 *REGPARAM2 dmac_gvp_xlate(struct wd_state *wd, uaecptr addr)
+static void REGPARAM2 dmac_gvp_bput (uaecptr addr, uae_u32 b)
 {
-       addr &= 0xffff;
-       return wd->rom + addr;
-}
-
-static uae_u8 *REGPARAM2 dmac_gvp_xlate(uaecptr addr)
-{
-       return dmac_gvp_xlate(&wd_gvp, addr);
+       struct wd_state *wd = getscsiboard(addr);
+       if (wd)
+               dmac_gvp_bput(wd, addr, b);
 }
-static int REGPARAM2 dmac_gvp_check(uaecptr addr, uae_u32 size)
+static void REGPARAM2 dmac_gvp_wput (uaecptr addr, uae_u32 b)
 {
-       return dmac_gvp_check(&wd_gvp, addr, size);
+       struct wd_state *wd = getscsiboard(addr);
+       if (wd)
+               dmac_gvp_wput(wd, addr, b);
 }
-static uae_u32 REGPARAM2 dmac_gvp_lgeti(uaecptr addr)
+static void REGPARAM2 dmac_gvp_lput (uaecptr addr, uae_u32 b)
 {
-       return dmac_gvp_lgeti(&wd_gvp, addr);
+       struct wd_state *wd = getscsiboard(addr);
+       if (wd)
+               dmac_gvp_lput(wd, addr, b);
 }
-static uae_u32 REGPARAM2 dmac_gvp_wgeti(uaecptr addr)
+static uae_u32 REGPARAM2 dmac_gvp_bget (uaecptr addr)
 {
-       return dmac_gvp_wgeti(&wd_gvp, addr);
+       struct wd_state *wd = getscsiboard(addr);
+       if (wd)
+               return dmac_gvp_bget(wd, addr);
+       return 0;
 }
-static uae_u32 REGPARAM2 dmac_gvp_bget(uaecptr addr)
+static uae_u32 REGPARAM2 dmac_gvp_wget (uaecptr addr)
 {
-       return dmac_gvp_bget(&wd_gvp, addr);
+       struct wd_state *wd = getscsiboard(addr);
+       if (wd)
+               return dmac_gvp_wget(wd, addr);
+       return 0;
 }
-static uae_u32 REGPARAM2 dmac_gvp_wget(uaecptr addr)
+static uae_u32 REGPARAM2 dmac_gvp_lget (uaecptr addr)
 {
-       return dmac_gvp_wget(&wd_gvp, addr);
+       struct wd_state *wd = getscsiboard(addr);
+       if (wd)
+               return dmac_gvp_lget(wd, addr);
+       return 0;
 }
-static uae_u32 REGPARAM2 dmac_gvp_lget(uaecptr addr)
+static uae_u32 REGPARAM2 dmac_gvp_wgeti (uaecptr addr)
 {
-       return dmac_gvp_lget(&wd_gvp, addr);
+       struct wd_state *wd = getscsiboard(addr);
+       if (wd)
+               return dmac_gvp_wgeti(wd, addr);
+       return 0;
 }
-static void REGPARAM2 dmac_gvp_bput(uaecptr addr, uae_u32 b)
+static uae_u32 REGPARAM2 dmac_gvp_lgeti (uaecptr addr)
 {
-       dmac_gvp_bput(&wd_gvp, addr, b);
+       struct wd_state *wd = getscsiboard(addr);
+       if (wd)
+               return dmac_gvp_lgeti(wd, addr);
+       return 0;
 }
-static void REGPARAM2 dmac_gvp_wput(uaecptr addr, uae_u32 b)
+static int REGPARAM2 dmac_gvp_check(uaecptr addr, uae_u32 size)
 {
-       dmac_gvp_wput(&wd_gvp, addr, b);
+       return 1;
 }
-static void REGPARAM2 dmac_gvp_lput(uaecptr addr, uae_u32 b)
+static uae_u8 *REGPARAM2 dmac_gvp_xlate(uaecptr addr)
 {
-       dmac_gvp_lput(&wd_gvp, addr, b);
+       struct wd_state *wd = getscsiboard(addr);
+       if (!wd)
+               return default_xlate(0);
+       addr &= 0xffff;
+       return wd->rom + addr;
 }
-
 addrbank gvp_bank = {
        dmac_gvp_lget, dmac_gvp_wget, dmac_gvp_bget,
        dmac_gvp_lput, dmac_gvp_wput, dmac_gvp_bput,
@@ -2905,54 +2943,6 @@ addrbank gvp_bank = {
        dmac_gvp_lgeti, dmac_gvp_wgeti, ABFLAG_IO | ABFLAG_SAFE
 };
 
-static uae_u8 *REGPARAM2 dmac_gvp_2_xlate(uaecptr addr)
-{
-       return dmac_gvp_xlate(&wd_gvp_2, addr);
-}
-static int REGPARAM2 dmac_gvp_2_check(uaecptr addr, uae_u32 size)
-{
-       return dmac_gvp_check(&wd_gvp_2, addr, size);
-}
-static uae_u32 REGPARAM2 dmac_gvp_2_lgeti(uaecptr addr)
-{
-       return dmac_gvp_lgeti(&wd_gvp_2, addr);
-}
-static uae_u32 REGPARAM2 dmac_gvp_2_wgeti(uaecptr addr)
-{
-       return dmac_gvp_wgeti(&wd_gvp_2, addr);
-}
-static uae_u32 REGPARAM2 dmac_gvp_2_bget(uaecptr addr)
-{
-       return dmac_gvp_bget(&wd_gvp_2, addr);
-}
-static uae_u32 REGPARAM2 dmac_gvp_2_wget(uaecptr addr)
-{
-       return dmac_gvp_wget(&wd_gvp_2, addr);
-}
-static uae_u32 REGPARAM2 dmac_gvp_2_lget(uaecptr addr)
-{
-       return dmac_gvp_lget(&wd_gvp_2, addr);
-}
-static void REGPARAM2 dmac_gvp_2_bput(uaecptr addr, uae_u32 b)
-{
-       dmac_gvp_bput(&wd_gvp_2, addr, b);
-}
-static void REGPARAM2 dmac_gvp_2_wput(uaecptr addr, uae_u32 b)
-{
-       dmac_gvp_wput(&wd_gvp_2, addr, b);
-}
-static void REGPARAM2 dmac_gvp_2_lput(uaecptr addr, uae_u32 b)
-{
-       dmac_gvp_lput(&wd_gvp_2, addr, b);
-}
-
-addrbank gvp_2_bank = {
-       dmac_gvp_2_lget, dmac_gvp_2_wget, dmac_gvp_2_bget,
-       dmac_gvp_2_lput, dmac_gvp_2_wput, dmac_gvp_2_bput,
-       dmac_gvp_2_xlate, dmac_gvp_2_check, NULL, NULL, _T("GVP #2"),
-       dmac_gvp_2_lgeti, dmac_gvp_2_wgeti, ABFLAG_IO | ABFLAG_SAFE
-};
-
 /* SUPERDMAC (A3000 mainboard built-in) */
 
 static void mbdmac_write_word (struct wd_state *wd, uae_u32 addr, uae_u32 val)
@@ -3152,8 +3142,8 @@ static uae_u32 REGPARAM2 mbdmac_lget (uaecptr addr)
 #ifdef JIT
        special_mem |= S_READ;
 #endif
-       v =  mbdmac_read_word (&wd_a3000, addr + 0) << 16;
-       v |= mbdmac_read_word (&wd_a3000, addr + 2) << 0;
+       v =  mbdmac_read_word (wd_a3000, addr + 0) << 16;
+       v |= mbdmac_read_word (wd_a3000, addr + 2) << 0;
        return v;
 }
 static uae_u32 REGPARAM2 mbdmac_wget (uaecptr addr)
@@ -3162,7 +3152,7 @@ static uae_u32 REGPARAM2 mbdmac_wget (uaecptr addr)
 #ifdef JIT
        special_mem |= S_READ;
 #endif
-       v =  mbdmac_read_word (&wd_a3000, addr);
+       v =  mbdmac_read_word (wd_a3000, addr);
        return v;
 }
 static uae_u32 REGPARAM2 mbdmac_bget (uaecptr addr)
@@ -3170,7 +3160,7 @@ static uae_u32 REGPARAM2 mbdmac_bget (uaecptr addr)
 #ifdef JIT
        special_mem |= S_READ;
 #endif
-       return mbdmac_read_byte (&wd_a3000, addr);
+       return mbdmac_read_byte (wd_a3000, addr);
 }
 static void REGPARAM2 mbdmac_lput (uaecptr addr, uae_u32 l)
 {
@@ -3179,10 +3169,10 @@ static void REGPARAM2 mbdmac_lput (uaecptr addr, uae_u32 l)
 #endif
        if ((addr & 0xffff) == 0x40) {
                // long write to 0x40 = write byte to SASR
-               mbdmac_write_byte (&wd_a3000, 0x41, l);
+               mbdmac_write_byte (wd_a3000, 0x41, l);
        } else {
-               mbdmac_write_word (&wd_a3000, addr + 0, l >> 16);
-               mbdmac_write_word (&wd_a3000, addr + 2, l >> 0);
+               mbdmac_write_word (wd_a3000, addr + 0, l >> 16);
+               mbdmac_write_word (wd_a3000, addr + 2, l >> 0);
        }
 }
 static void REGPARAM2 mbdmac_wput (uaecptr addr, uae_u32 w)
@@ -3190,14 +3180,14 @@ static void REGPARAM2 mbdmac_wput (uaecptr addr, uae_u32 w)
 #ifdef JIT
        special_mem |= S_WRITE;
 #endif
-       mbdmac_write_word (&wd_a3000, addr + 0, w);
+       mbdmac_write_word (wd_a3000, addr + 0, w);
 }
 static void REGPARAM2 mbdmac_bput (uaecptr addr, uae_u32 b)
 {
 #ifdef JIT
        special_mem |= S_WRITE;
 #endif
-       mbdmac_write_byte (&wd_a3000, addr, b);
+       mbdmac_write_byte (wd_a3000, addr, b);
 }
 
 addrbank mbdmac_a3000_bank = {
@@ -3292,9 +3282,9 @@ void init_wd_scsi (struct wd_state *wd)
        wd->enabled = true;
        wd->wc.wd_used = 0;
        wd->wc.wd33c93_ver = 1;
-       if (wd == &wd_cdtv) {
+       wd->baseaddress = 0;
+       if (wd == wd_cdtv) {
                wd->cdtv = true;
-               wd->name = _T("CDTV");
        }
        if (!wd->scsi_thread_running) {
                wd->scsi_thread_running = 1;
@@ -3303,20 +3293,19 @@ void init_wd_scsi (struct wd_state *wd)
        }
 }
 
-int a3000_add_scsi_unit (int ch, struct uaedev_config_info *ci)
+void a3000_add_scsi_unit (int ch, struct uaedev_config_info *ci, struct romconfig *rc)
 {
-       struct wd_state *wd = &wd_a3000;
-       if (ci->type == UAEDEV_CD)
-               return add_scsi_cd (wd->scsis, ch, ci->device_emu_unit);
-       else if (ci->type == UAEDEV_TAPE)
-               return add_scsi_tape (wd->scsis, ch, ci->rootdir, ci->readonly);
-       else
-               return add_scsi_hd (wd->scsis, ch, NULL, ci, 2);
+       struct wd_state *wd = allocscsi(&wd_a3000, rc);
+       if (!wd || ch < 0)
+               return;
+       add_scsi_device(&wd->scsis[ch], ch, ci, rc, 2);
 }
 
 void a3000scsi_reset (void)
 {
-       struct wd_state *wd = &wd_a3000;
+       struct wd_state *wd = wd_a3000;
+       if (!wd)
+               return;
        init_wd_scsi (wd);
        wd->enabled = true;
        wd->configured = -1;
@@ -3324,12 +3313,13 @@ void a3000scsi_reset (void)
        map_banks (&mbdmac_a3000_bank, 0xDD, 1, 0);
        wd_cmd_reset (&wd->wc, false);
        reset_dmac(wd);
-       wd->name = _T("A3000");
 }
 
 void a3000scsi_free (void)
 {
-       struct wd_state *wd = &wd_a3000;
+       struct wd_state *wd = wd_a3000;
+       if (!wd)
+               return;
        scsi_freenative(wd->scsis);
        if (wd->scsi_thread_running > 0) {
                wd->scsi_thread_running = 0;
@@ -3340,56 +3330,51 @@ void a3000scsi_free (void)
        }
 }
 
-int a2090_add_scsi_unit(int ch, struct uaedev_config_info *ci)
+void a2090_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
 {
-       struct wd_state *wd = wda2091[ci->controller_type_unit];
-
-       if (ci->type == UAEDEV_CD)
-               return add_scsi_cd(wd->scsis, ch, ci->device_emu_unit);
-       else if (ci->type == UAEDEV_TAPE)
-               return add_scsi_tape(wd->scsis, ch, ci->rootdir, ci->readonly);
-       else
-               return add_scsi_hd(wd->scsis, ch, NULL, ci, 1);
+       struct wd_state *wd = allocscsi(&wd_a2090[ci->controller_type_unit], rc);
+       if (!wd || ch < 0)
+               return;
+       add_scsi_device(&wd->scsis[ch], ch, ci, rc, 1);
 }
 
-int a2091_add_scsi_unit(int ch, struct uaedev_config_info *ci)
+void a2091_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
 {
-       struct wd_state *wd = wda2091[ci->controller_type_unit];
-
-       if (ci->type == UAEDEV_CD)
-               return add_scsi_cd(wd->scsis, ch, ci->device_emu_unit);
-       else if (ci->type == UAEDEV_TAPE)
-               return add_scsi_tape(wd->scsis, ch, ci->rootdir, ci->readonly);
-       else
-               return add_scsi_hd(wd->scsis, ch, NULL, ci, 1);
+       struct wd_state *wd = allocscsi(&wd_a2091[ci->controller_type_unit], rc);
+       if (!wd || ch < 0)
+               return;
+       add_scsi_device(&wd->scsis[ch], ch, ci, rc, 1);
 }
 
-int gvp_add_scsi_unit(int ch, struct uaedev_config_info *ci)
+void gvp_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
 {
-       struct wd_state *wd = gvpscsi[ci->controller_type_unit];
-
-       if (ci->type == UAEDEV_CD)
-               return add_scsi_cd(wd->scsis, ch, ci->device_emu_unit);
-       else if (ci->type == UAEDEV_TAPE)
-               return add_scsi_tape(wd->scsis, ch, ci->rootdir, ci->readonly);
-       else
-               return add_scsi_hd(wd->scsis, ch, NULL, ci, 2);
+       struct wd_state *wd = allocscsi(&wd_gvp[ci->controller_type_unit], rc);
+       if (!wd || ch < 0)
+               return;
+       add_scsi_device(&wd->scsis[ch], ch, ci, rc, 2);
 }
 
 void a2091_free_device (struct wd_state *wd)
 {
+       if (!wd)
+               return;
        scsi_freenative(wd->scsis);
        xfree (wd->rom);
        wd->rom = NULL;
 }
+
 void a2091_free (void)
 {
-       a2091_free_device(&wd_a2091);
-       a2091_free_device(&wd_a2091_2);
+       for (int i = 0; i < MAX_DUPLICATE_EXPANSION_BOARDS; i++) {
+               a2091_free_device(wd_a2091[i]);
+               a2091_free_device(wd_a2090[i]);
+       }
 }
 
 static void a2091_reset_device(struct wd_state *wd)
 {
+       if (!wd)
+               return;
        wd->configured = 0;
        wd->wc.wd_used = 0;
        wd->wc.wd33c93_ver = 1;
@@ -3399,15 +3384,13 @@ static void a2091_reset_device(struct wd_state *wd)
                scsi_addnative(wd->scsis);
        wd_cmd_reset (&wd->wc, false);
        reset_dmac(wd);
-       if (wd == &wd_a2091)
-               wd->name = _T("A2091/A590");
-       if (wd == &wd_a2091_2)
-               wd->name = _T("A2091/A590 #2");
        xt_reset(wd);
 }
 
 static void a2090_reset_device(struct wd_state *wd)
 {
+       if (!wd)
+               return;
        wd->configured = 0;
        wd->wc.wd_used = 0;
        wd->wc.wd33c93_ver = 1;
@@ -3415,49 +3398,32 @@ static void a2090_reset_device(struct wd_state *wd)
        wd->cdmac.old_dmac = 0;
        wd_cmd_reset (&wd->wc, false);
        reset_dmac(wd);
-       if (wd == &wd_a2091)
-               wd->name = _T("A2090");
-       if (wd == &wd_a2091_2)
-               wd->name = _T("A2090 #2");
 }
 
 void a2091_reset (void)
 {
-       struct romconfig *rc;
-       
-       rc = get_device_romconfig(&currprefs, 0, ROMTYPE_A2091);
-       if (rc) {
-               a2091_reset_device(&wd_a2091);
-               a2091_reset_device(&wd_a2091_2);
-       }
-       rc = get_device_romconfig(&currprefs, 0, ROMTYPE_A2090);
-       if (rc) {
-               a2090_reset_device(&wd_a2091);
-               a2090_reset_device(&wd_a2091_2);
+       for (int i = 0; i < MAX_DUPLICATE_EXPANSION_BOARDS; i++) {
+               a2091_reset_device(wd_a2091[i]);
+               a2090_reset_device(wd_a2090[i]);
        }
 }
 
-addrbank *a2091_init (int devnum)
+addrbank *a2091_init (struct romconfig *rc)
 {
-       struct wd_state *wd = wda2091[devnum];
+       struct wd_state *wd = getscsi(rc);
        int roms[6];
        int slotsize;
-       struct romconfig *rc = NULL;
 
-       if (devnum > 0 && !wd->enabled)
+       if (!wd)
                return &expamem_null;
 
        init_wd_scsi(wd);
 
-       rc = get_device_romconfig(&currprefs, devnum, ROMTYPE_A2091);
-       if (rc)
-               wd->cdmac.old_dmac = rc->subtype == 0;
-
+       wd->cdmac.old_dmac = rc->subtype == 0;
        wd->configured = 0;
        wd->autoconfig = true;
        wd->board_mask = 65535;
-       wd->bank = devnum ? &dmaca2091_2_bank : &dmaca2091_bank;
-       wd->bank->name = devnum ? _T("A2091 2nd") : _T("A2091");
+       wd->bank = &dmaca2091_bank;
        memset (wd->dmacmemory, 0xff, sizeof wd->dmacmemory);
        ew (wd, 0x00, 0xc0 | 0x01 | 0x10);
        /* A590/A2091 hardware id */
@@ -3488,52 +3454,43 @@ addrbank *a2091_init (int devnum)
        memset(wd->rom, 0xff, slotsize);
        wd->rom_size = 16384;
        wd->rom_mask = wd->rom_size - 1;
-       if (rc && !rc->autoboot_disabled) {
-               if (is_device_rom(&currprefs, devnum, ROMTYPE_A2091)) {
-                       struct zfile *z = read_device_rom(&currprefs, devnum, ROMTYPE_A2091, roms);
-                       if (z) {
-                               write_log (_T("A590/A2091 BOOT ROM '%s'\n"), zfile_getname (z));
-                               wd->rom_size = zfile_size (z);
-                               zfile_fread (wd->rom, wd->rom_size, 1, z);
-                               zfile_fclose (z);
-                               if (wd->rom_size == 32768) {
-                                       wd->rombankswitcher = 1;
-                                       for (int i = wd->rom_size - 1; i >= 0; i--) {
-                                               wd->rom[i * 2 + 0] = wd->rom[i];
-                                               wd->rom[i * 2 + 1] = 0xff;
-                                       }
-                               } else {
-                                       for (int i = 1; i < slotsize / wd->rom_size; i++)
-                                               memcpy (wd->rom + i * wd->rom_size, wd->rom, wd->rom_size);
+       if (!rc->autoboot_disabled) {
+               struct zfile *z = read_device_from_romconfig(rc, roms);
+               if (z) {
+                       wd->rom_size = zfile_size (z);
+                       zfile_fread (wd->rom, wd->rom_size, 1, z);
+                       zfile_fclose (z);
+                       if (wd->rom_size == 32768) {
+                               wd->rombankswitcher = 1;
+                               for (int i = wd->rom_size - 1; i >= 0; i--) {
+                                       wd->rom[i * 2 + 0] = wd->rom[i];
+                                       wd->rom[i * 2 + 1] = 0xff;
                                }
-                               wd->rom_mask = wd->rom_size - 1;
                        } else {
-                               romwarning (roms);
+                               for (int i = 1; i < slotsize / wd->rom_size; i++)
+                                       memcpy (wd->rom + i * wd->rom_size, wd->rom, wd->rom_size);
                        }
+                       wd->rom_mask = wd->rom_size - 1;
                }
        }
-       return wd == &wd_a2091 ? &dmaca2091_bank : &dmaca2091_2_bank;
+       return wd->bank;
 }
 
-addrbank *a2090_init (int devnum)
+addrbank *a2090_init (struct romconfig *rc)
 {
-       struct wd_state *wd = wda2091[devnum];
+       struct wd_state *wd = getscsi(rc);
        int roms[6];
        int slotsize;
-       struct romconfig *rc = NULL;
 
-       if (devnum > 0 && !wd->enabled)
+       if (!wd)
                return &expamem_null;
 
        init_wd_scsi(wd);
 
-       rc = get_device_romconfig(&currprefs, devnum, ROMTYPE_A2090);
-
        wd->configured = 0;
        wd->autoconfig = true;
        wd->board_mask = 65535;
-       wd->bank = devnum ? &dmaca2091_2_bank : &dmaca2091_bank;
-       wd->bank->name = devnum ? _T("A2090a 2nd") : _T("A2090a");
+       wd->bank = &dmaca2091_bank;
        memset (wd->dmacmemory, 0xff, sizeof wd->dmacmemory);
        ew (wd, 0x00, 0xc0 | 0x01 | 0x10);
        /* A590/A2091 hardware id */
@@ -3562,21 +3519,16 @@ addrbank *a2090_init (int devnum)
        memset(wd->rom, 0xff, slotsize);
        wd->rom_size = 16384;
        wd->rom_mask = wd->rom_size - 1;
-       if (rc && !rc->autoboot_disabled) {
-               if (is_device_rom(&currprefs, devnum, ROMTYPE_A2090)) {
-                       struct zfile *z = read_device_rom(&currprefs, devnum, ROMTYPE_A2090, roms);
-                       if (z) {
-                               write_log (_T("A2090a BOOT ROM '%s'\n"), zfile_getname (z));
-                               wd->rom_size = zfile_size (z);
-                               zfile_fread (wd->rom, wd->rom_size, 1, z);
-                               zfile_fclose (z);
-                               for (int i = 1; i < slotsize / wd->rom_size; i++) {
-                                       memcpy (wd->rom + i * wd->rom_size, wd->rom, wd->rom_size);
-                               }
-                               wd->rom_mask = wd->rom_size - 1;
-                       } else {
-                               romwarning (roms);
+       if (!rc->autoboot_disabled) {
+               struct zfile *z = read_device_from_romconfig(rc, roms);
+               if (z) {
+                       wd->rom_size = zfile_size (z);
+                       zfile_fread (wd->rom, wd->rom_size, 1, z);
+                       zfile_fclose (z);
+                       for (int i = 1; i < slotsize / wd->rom_size; i++) {
+                               memcpy (wd->rom + i * wd->rom_size, wd->rom, wd->rom_size);
                        }
+                       wd->rom_mask = wd->rom_size - 1;
                }
        }
        return wd->bank;
@@ -3584,18 +3536,24 @@ addrbank *a2090_init (int devnum)
 
 void gvp_free_device (struct wd_state *wd)
 {
+       if (!wd)
+               return;
        scsi_freenative(wd->scsis);
        xfree (wd->rom);
        wd->rom = NULL;
 }
+
 void gvp_free (void)
 {
-       gvp_free_device(&wd_gvp);
-       gvp_free_device(&wd_gvp_2);
+       for (int i = 0; i < MAX_DUPLICATE_EXPANSION_BOARDS; i++) {
+               gvp_free_device(wd_gvp[i]);
+       }
 }
 
 static void gvp_reset_device(struct wd_state *wd)
 {
+       if (!wd)
+               return;
        wd->configured = 0;
        wd->wc.wd_used = 0;
        wd->wc.wd33c93_ver = 1;
@@ -3604,16 +3562,13 @@ static void gvp_reset_device(struct wd_state *wd)
                scsi_addnative(wd->scsis);
        wd_cmd_reset (&wd->wc, false);
        reset_dmac(wd);
-       if (wd == &wd_gvp)
-               wd->name = _T("GVP");
-       if (wd == &wd_gvp_2)
-               wd->name = _T("GPV #2");
 }
 
 void gvp_reset (void)
 {
-       gvp_reset_device(&wd_gvp);
-       gvp_reset_device(&wd_gvp_2);
+       for (int i = 0; i < MAX_DUPLICATE_EXPANSION_BOARDS; i++) {
+               gvp_reset_device(wd_gvp[i]);
+       }
 }
 
 static const uae_u8 gvp_scsi_i_autoconfig_1[16] = { 0xd1, 0x01, 0x00, 0x00, 0x07, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00 };
@@ -3623,32 +3578,29 @@ static const uae_u8 gvp_scsi_ii_autoconfig[16] =  { 0xd1, 0x0b, 0x00, 0x00, 0x07
 
 static bool is_gvp_accelerator(void)
 {
-       return currprefs.cpuboard_type == BOARD_GVP;
+       return ISCPUBOARD(BOARD_GVP, -1);
 }
 
-static addrbank *gvp_init(int devnum, bool series2)
+static addrbank *gvp_init(struct romconfig *rc, bool series2, bool accel)
 {
-       struct wd_state *wd;
+       struct wd_state *wd = getscsi(rc);
        int roms[6];
        bool isscsi = true;
-       struct romconfig *rc = NULL;
        const uae_u8 *ac;
        int romtype;
 
-       if (devnum >= 0) {
+       if (!accel) {
                romtype = series2 ? ROMTYPE_GVPS2 : ROMTYPE_GVPS1;
        } else {
-               devnum = 0;
                romtype = ROMTYPE_CPUBOARD;
        }
-       wd = gvpscsi[devnum];
 
-       if (devnum > 0 && !wd->enabled)
+       if (!wd)
                return &expamem_null;
 
        init_wd_scsi(wd);
-       wd->name = _T("GVP");
        wd->configured = 0;
+       wd->bank = &gvp_bank;
        wd->autoconfig = true;
        wd->rombankswitcher = 0;
        memset(wd->dmacmemory, 0xff, sizeof wd->dmacmemory);
@@ -3662,68 +3614,67 @@ static addrbank *gvp_init(int devnum, bool series2)
        roms[3] = -1;
 
        wd->rom_size = 32768;
-       wd->rom = xcalloc(uae_u8, wd->rom_size);
-       memset(wd->rom, 0xff, wd->rom_size);
+       wd->rom = xcalloc(uae_u8, 2 * wd->rom_size);
+       memset(wd->rom, 0xff, 2 * wd->rom_size);
        wd->rom_mask = 32768 - 1;
        wd->gdmac.s1_subtype = 0;
        ac = gvp_scsi_ii_autoconfig;
 
-       rc = get_device_romconfig(&currprefs, devnum, romtype);
-       if (rc) {
-               ac = gvp_scsi_ii_autoconfig;
-               if (!series2) {
-                       ac = gvp_scsi_i_autoconfig_1;
-                       wd->gdmac.s1_rammask = GVP_SERIES_I_RAM_MASK_1;
-                       wd->gdmac.s1_ramoffset = GVP_SERIES_I_RAM_OFFSET_1;
-                       if (rc->subtype == 1) {
-                               ac = gvp_scsi_i_autoconfig_2;
-                               wd->gdmac.s1_rammask = GVP_SERIES_I_RAM_MASK_2;
-                               wd->gdmac.s1_ramoffset = GVP_SERIES_I_RAM_OFFSET_2;
-                       } else if (rc->subtype == 2) {
-                               ac = gvp_scsi_i_autoconfig_3;
-                               wd->gdmac.s1_rammask = GVP_SERIES_I_RAM_MASK_3;
-                               wd->gdmac.s1_ramoffset = GVP_SERIES_I_RAM_OFFSET_3;
-                               wd->board_mask = 131071;
-                       }
-                       wd->gdmac.s1_subtype = rc->subtype;
-               }
-               xfree(wd->gdmac.buffer);
-               wd->gdmac.buffer = xcalloc(uae_u8, 16384);
-               if (!rc->autoboot_disabled) {
-                       if (is_device_rom(&currprefs, devnum, romtype)) {
-                               struct zfile *z = read_device_rom(&currprefs, devnum, romtype, roms);
-                               if (z) {
-                                       write_log(_T("GVP BOOT ROM '%s'\n"), zfile_getname(z));
-                                       int size = zfile_size(z);
-                                       if (series2) {
-                                               zfile_fread(wd->rom, 1, wd->rom_size, z);
-                                       } else {
-                                               int j = 0;
-                                               bool oddonly = false;
-                                               for (int i = 0; i < 16384; i++) {
-                                                       uae_u8 b;
-                                                       zfile_fread(&b, 1, 1, z);
-                                                       wd->rom[j++] = b;
-                                                       if (i == 0 && (b & 0xc0) != 0x80) {
-                                                               // was not wordwide
-                                                               oddonly = true;
-                                                               wd->gdmac.use_version = true;
-                                                       }
-                                                       if (oddonly) {
-                                                               wd->rom[j++] = 0xff;
-                                                       }
-                                               }
+       ac = gvp_scsi_ii_autoconfig;
+       if (!series2) {
+               ac = gvp_scsi_i_autoconfig_1;
+               wd->gdmac.s1_rammask = GVP_SERIES_I_RAM_MASK_1;
+               wd->gdmac.s1_ramoffset = GVP_SERIES_I_RAM_OFFSET_1;
+               if (rc->subtype == 1) {
+                       ac = gvp_scsi_i_autoconfig_2;
+                       wd->gdmac.s1_rammask = GVP_SERIES_I_RAM_MASK_2;
+                       wd->gdmac.s1_ramoffset = GVP_SERIES_I_RAM_OFFSET_2;
+               } else if (rc->subtype == 2) {
+                       ac = gvp_scsi_i_autoconfig_3;
+                       wd->gdmac.s1_rammask = GVP_SERIES_I_RAM_MASK_3;
+                       wd->gdmac.s1_ramoffset = GVP_SERIES_I_RAM_OFFSET_3;
+                       wd->board_mask = 131071;
+               }
+               wd->gdmac.s1_subtype = rc->subtype;
+       }
+       xfree(wd->gdmac.buffer);
+       wd->gdmac.buffer = xcalloc(uae_u8, 16384);
+       if (!rc->autoboot_disabled) {
+               struct zfile *z = read_device_from_romconfig(rc, roms);
+               if (z) {
+                       int size = zfile_size(z);
+                       if (series2) {
+                               int total = 0;
+                               while (total < 32768) {
+                                       int prevtotal = total;
+                                       zfile_fseek(z, 0, SEEK_SET);
+                                       total += zfile_fread(wd->rom + total, 1, wd->rom_size - total >= wd->rom_size ? wd->rom_size : wd->rom_size - total, z);
+                                       if (prevtotal == total)
+                                               break;
+                               }
+                       } else {
+                               int j = 0;
+                               bool oddonly = false;
+                               for (int i = 0; i < 16384; i++) {
+                                       uae_u8 b;
+                                       zfile_fread(&b, 1, 1, z);
+                                       wd->rom[j + 16384] = b;
+                                       wd->rom[j++] = b;
+                                       if (i == 0 && (b & 0xc0) != 0x80) {
+                                               // was not wordwide
+                                               oddonly = true;
+                                               wd->gdmac.use_version = true;
                                        }
-                                       zfile_fclose(z);
-                                       if (series2 && size > 16384) {
-                                               wd->rombankswitcher = 1;
+                                       if (oddonly) {
+                                               wd->rom[j + 16384] = 0xff;
+                                               wd->rom[j++] = 0xff;
                                        }
-                               } else {
-                                       isscsi = false;
-                                       if (!is_gvp_accelerator())
-                                               romwarning(roms);
                                }
                        }
+                       zfile_fclose(z);
+                       if (series2 && size > 16384) {
+                               wd->rombankswitcher = 1;
+                       }
                } else {
                        isscsi = false;
                }
@@ -3748,22 +3699,32 @@ static addrbank *gvp_init(int devnum, bool series2)
                ew(wd, i * 4, b);
        }
        gvp_reset_device(wd);
-       return wd == &wd_gvp ? &gvp_bank : &gvp_2_bank;
+       return wd->bank;
 }
 
-addrbank *gvp_init_s1(int devnum)
+addrbank *gvp_init_s1(struct romconfig *rc)
+{
+       return gvp_init(rc, false, false);
+}
+addrbank *gvp_init_s2(struct romconfig *rc)
 {
-       return gvp_init(devnum, false);
+       return gvp_init(rc, true, false);
 }
-addrbank *gvp_init_s2(int devnum)
+addrbank *gvp_init_accelerator(struct romconfig *rc)
 {
-       return gvp_init(devnum, true);
+       return gvp_init(rc, true, true);
 }
-addrbank *gvp_init_accelerator(int devnum)
+
+void cdtv_add_scsi_unit (int ch, struct uaedev_config_info *ci, struct romconfig *rc)
 {
-       return gvp_init(-1, true);
+       struct wd_state *wd = allocscsi(&wd_cdtv, rc);
+       if (!wd || ch < 0)
+               return;
+       add_scsi_device(&wd_cdtv->scsis[ch], ch, ci, rc, 1);
 }
 
+
+#if 0
 uae_u8 *save_scsi_dmac (int wdtype, int *len, uae_u8 *dstptr)
 {
        struct wd_state *wd = wdscsi[wdtype];
@@ -3904,7 +3865,7 @@ uae_u8 *restore_scsi_device (int wdtype, uae_u8 *src)
                        wd->cdmac.xt_control = restore_u8();
                }
                if (size)
-                       add_scsi_hd (wd->scsis, num, hfd, NULL, s->hfd->ansi_version);
+                       add_scsi_hd (&wd->scsis[num], num, hfd, NULL, s->hfd->ansi_version);
                xfree (path);
        break;
        case UAEDEV_CD:
@@ -3916,9 +3877,10 @@ uae_u8 *restore_scsi_device (int wdtype, uae_u8 *src)
                blocksize = restore_u32 ();
                readonly = restore_u32 ();
                path = restore_string ();
-               add_scsi_tape (wd->scsis, num, path, readonly != 0);
+               add_scsi_tape (&wd->scsis[num], num, path, readonly != 0);
                xfree (path);
        break;
        }
        return src;
 }
+#endif
index 83fabdde73b77d0b3c627db933ea4b76ae4ae107..708b3bf4f68f77147aa3c2864662645573149e8b 100644 (file)
--- a/amax.cpp
+++ b/amax.cpp
@@ -145,11 +145,11 @@ void amax_init (void)
 {
        struct zfile *z = NULL;
 
-       if (is_device_rom(&currprefs, 0, ROMTYPE_AMAX) < 0)
+       if (is_device_rom(&currprefs, ROMTYPE_AMAX, 0) < 0)
                return;
        amax_reset ();
-       if (is_device_rom(&currprefs, 0, ROMTYPE_AMAX) > 0)
-               z = read_device_rom(&currprefs, 0, ROMTYPE_AMAX, NULL);
+       if (is_device_rom(&currprefs, ROMTYPE_AMAX, 0) > 0)
+               z = read_device_rom(&currprefs, ROMTYPE_AMAX, 0, NULL);
        if (z) {
                zfile_fseek (z, 0, SEEK_END);
                amax_rom_size = zfile_ftell (z);
index d20778044b71ee9747d4214055a067f1a7d7f9a4..e7923e08277c4308a496a0ff49206146129c75b9 100644 (file)
--- a/cdtv.cpp
+++ b/cdtv.cpp
@@ -1045,7 +1045,7 @@ static void dmac_start_dma (void)
        if (!(dmac_cntr & CNTR_PDMD)) { // non-scsi dma
                write_comm_pipe_u32 (&requests, 0x0100, 1);
        } else {
-               scsi_dmac_a2091_start_dma (&wd_cdtv);
+               scsi_dmac_a2091_start_dma (wd_cdtv);
        }
 }
 static void dmac_stop_dma (void)
@@ -1053,7 +1053,7 @@ static void dmac_stop_dma (void)
        if (!(dmac_cntr & CNTR_PDMD)) { // non-scsi dma
                ;
        } else {
-               scsi_dmac_a2091_stop_dma (&wd_cdtv);
+               scsi_dmac_a2091_stop_dma (wd_cdtv);
        }
 }
 
@@ -1066,7 +1066,7 @@ static void checkint (void)
 {
        int irq = 0;
 
-       if (currprefs.cs_cdtvscsi && (wdscsi_getauxstatus (&wd_cdtv.wc) & 0x80)) {
+       if (currprefs.cs_cdtvscsi && (wdscsi_getauxstatus (&wd_cdtv->wc) & 0x80)) {
                dmac_istr |= ISTR_INTS;
                if ((dmac_cntr & CNTR_INTEN) && (dmac_istr & ISTR_INTS))
                        irq = 1;
@@ -1258,11 +1258,11 @@ static uae_u32 dmac_bget2 (uaecptr addr)
                break;
        case 0x91:
                if (currprefs.cs_cdtvscsi)
-                       v = wdscsi_getauxstatus (&wd_cdtv.wc);
+                       v = wdscsi_getauxstatus (&wd_cdtv->wc);
                break;
        case 0x93:
                if (currprefs.cs_cdtvscsi) {
-                       v = wdscsi_get (&wd_cdtv.wc, &wd_cdtv);
+                       v = wdscsi_get (&wd_cdtv->wc, wd_cdtv);
                        checkint ();
                }
                break;
@@ -1365,13 +1365,13 @@ static void dmac_bput2 (uaecptr addr, uae_u32 b)
                break;
        case 0x91:
                if (currprefs.cs_cdtvscsi) {
-                       wdscsi_sasr (&wd_cdtv.wc, b);
+                       wdscsi_sasr (&wd_cdtv->wc, b);
                        checkint ();
                }
                break;
        case 0x93:
                if (currprefs.cs_cdtvscsi) {
-                       wdscsi_put (&wd_cdtv.wc, &wd_cdtv, b);
+                       wdscsi_put (&wd_cdtv->wc, wd_cdtv, b);
                        checkint ();
                }
                break;
@@ -1634,11 +1634,6 @@ uae_u8 cdtv_battram_read (int addr)
        return v;
 }
 
-int cdtv_add_scsi_hd_unit (int ch, struct uaedev_config_info *ci)
-{
-       return add_scsi_hd (wd_cdtv.scsis, ch, NULL, ci, 1);
-}
-
 void cdtv_free (void)
 {
        if (thread_alive > 0) {
@@ -1655,7 +1650,7 @@ void cdtv_free (void)
        configured = 0;
 }
 
-addrbank *cdtv_init (int devnum)
+addrbank *cdtv_init (struct romconfig *rc)
 {
        close_unit ();
        if (!thread_alive) {
@@ -1697,8 +1692,8 @@ addrbank *cdtv_init (int devnum)
        open_unit ();
        gui_flicker_led (LED_CD, 0, -1);
        if (currprefs.cs_cdtvscsi) {
-               init_wd_scsi (&wd_cdtv);
-               wd_cdtv.dmac_type = COMMODORE_DMAC;
+               init_wd_scsi (wd_cdtv);
+               wd_cdtv->dmac_type = COMMODORE_DMAC;
        }
        return &dmac_bank;
 }
index a7618f9b0bde8352469dc6cf46971e8baf54420c..6565b663ecfa40ad5c8659bd455a969be85b88cc 100644 (file)
@@ -261,7 +261,13 @@ static const TCHAR *uaescsidevmodes[] = {
        _T("rename_scsi"),
        NULL
 };
-
+static const TCHAR *uaebootrom[] = {
+       _T("automatic"),
+       _T("disabled"), 
+       _T("min"),
+       _T("full"),
+       NULL
+};
 static const TCHAR *obsolete[] = {
        _T("accuracy"), _T("gfx_opengl"), _T("gfx_32bit_blits"), _T("32bit_blits"),
        _T("gfx_immediate_blits"), _T("gfx_ntsc"), _T("win32"), _T("gfx_filter_bits"),
@@ -836,7 +842,7 @@ static void write_filesys_config (struct uae_prefs *p, struct zfile *f)
                        _stprintf(hdcs, hdcontrollers[ct], ci->controller_unit);
                }
                if (ci->controller_type_unit > 0)
-                       _stprintf(hdcs + _tcslen(hdcs), _T("-%d"), ci->controller_type_unit);
+                       _stprintf(hdcs + _tcslen(hdcs), _T("-%d"), ci->controller_type_unit + 1);
 
                str1b = cfgfile_escape (str1, _T(":,"), true);
                str2b = cfgfile_escape (str2, _T(":,"), true);
@@ -962,7 +968,7 @@ static void write_resolution (struct zfile *f, const TCHAR *ws, const TCHAR *hs,
 static void cfgfile_write_board_rom(struct zfile *f, struct multipath *mp, struct boardromconfig *br)
 {
        TCHAR buf[256];
-       const TCHAR *name;
+       TCHAR name[256];
        const struct expansionromtype *ert;
        
        if (br->device_type == 0)
@@ -971,7 +977,10 @@ static void cfgfile_write_board_rom(struct zfile *f, struct multipath *mp, struc
        if (!ert)
                return;
        for (int i = 0; i < MAX_BOARD_ROMS; i++) {
-               name = ert->name;
+               if (br->device_num == 0)
+                       _tcscpy(name, ert->name);
+               else
+                       _stprintf(name, _T("%s-%d"), ert->name, br->device_num + 1);
                if (i == 0 || _tcslen(br->roms[i].romfile)) {
                        _stprintf(buf, _T("%s%s_rom_file"), name, i ? _T("_ext") : _T(""));
                        cfgfile_write_rom (f, mp, br->roms[i].romfile, buf);
@@ -1284,6 +1293,7 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
 
        cfgfile_write_bool (f, _T("synchronize_clock"), p->tod_hack);
        cfgfile_write (f, _T("maprom"), _T("0x%x"), p->maprom);
+       cfgfile_dwrite_str (f, _T("boot_rom_uae"), uaebootrom[p->boot_rom]);
        cfgfile_dwrite_str (f, _T("parallel_matrix_emulation"), epsonprinter[p->parallel_matrix_emulation]);
        cfgfile_write_bool (f, _T("parallel_postscript_emulation"), p->parallel_postscript_emulation);
        cfgfile_write_bool (f, _T("parallel_postscript_detection"), p->parallel_postscript_detection);
@@ -1388,9 +1398,16 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
                cfgfile_dwrite_ext (f, _T("gfx_filter_horiz_zoom_multf"), ext, _T("%f"), gf->gfx_filter_horiz_zoom_mult);
                cfgfile_dwrite_ext (f, _T("gfx_filter_vert_offsetf"), ext, _T("%f"), gf->gfx_filter_vert_offset);
                cfgfile_dwrite_ext (f, _T("gfx_filter_horiz_offsetf"), ext, _T("%f"), gf->gfx_filter_horiz_offset);
+               
+               cfgfile_dwrite_ext (f, _T("gfx_filter_left_border"), ext, _T("%d"), gf->gfx_filter_left_border);
+               cfgfile_dwrite_ext (f, _T("gfx_filter_right_border"), ext, _T("%d"), gf->gfx_filter_right_border);
+               cfgfile_dwrite_ext (f, _T("gfx_filter_top_border"), ext, _T("%d"), gf->gfx_filter_top_border);
+               cfgfile_dwrite_ext (f, _T("gfx_filter_bottom_border"), ext, _T("%d"), gf->gfx_filter_bottom_border);
+               
                cfgfile_dwrite_ext (f, _T("gfx_filter_scanlines"), ext, _T("%d"), gf->gfx_filter_scanlines);
                cfgfile_dwrite_ext (f, _T("gfx_filter_scanlinelevel"), ext, _T("%d"), gf->gfx_filter_scanlinelevel);
                cfgfile_dwrite_ext (f, _T("gfx_filter_scanlineratio"), ext, _T("%d"), gf->gfx_filter_scanlineratio);
+               
                cfgfile_dwrite_ext (f, _T("gfx_filter_luminance"), ext, _T("%d"), gf->gfx_filter_luminance);
                cfgfile_dwrite_ext (f, _T("gfx_filter_contrast"), ext, _T("%d"), gf->gfx_filter_contrast);
                cfgfile_dwrite_ext (f, _T("gfx_filter_saturation"), ext, _T("%d"), gf->gfx_filter_saturation);
@@ -1398,9 +1415,11 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
                cfgfile_dwrite_ext (f, _T("gfx_filter_gamma_r"), ext, _T("%d"), gf->gfx_filter_gamma_ch[0]);
                cfgfile_dwrite_ext (f, _T("gfx_filter_gamma_g"), ext, _T("%d"), gf->gfx_filter_gamma_ch[1]);
                cfgfile_dwrite_ext (f, _T("gfx_filter_gamma_b"), ext, _T("%d"), gf->gfx_filter_gamma_ch[2]);
+               
                cfgfile_dwrite_ext (f, _T("gfx_filter_blur"), ext, _T("%d"), gf->gfx_filter_blur);
                cfgfile_dwrite_ext (f, _T("gfx_filter_noise"), ext, _T("%d"), gf->gfx_filter_noise);
                cfgfile_dwrite_bool (f, _T("gfx_filter_bilinear"), ext, gf->gfx_filter_bilinear != 0);
+               
                cfgfile_dwrite_ext (f, _T("gfx_filter_keep_autoscale_aspect"), ext, _T("%d"), gf->gfx_filter_keep_autoscale_aspect);
                cfgfile_dwrite_str (f, _T("gfx_filter_keep_aspect"), ext, aspects[gf->gfx_filter_keep_aspect]);
                cfgfile_dwrite_str(f, _T("gfx_filter_autoscale"), ext, ext == NULL ? autoscale[gf->gfx_filter_autoscale] : autoscale_rtg[gf->gfx_filter_autoscale]);
@@ -2304,6 +2323,10 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value)
                        || cfgfile_floatval (option, value, _T("gfx_filter_horiz_zoom_multf"), ext, &gf->gfx_filter_horiz_zoom_mult)
                        || cfgfile_floatval (option, value, _T("gfx_filter_vert_offsetf"), ext, &gf->gfx_filter_vert_offset)
                        || cfgfile_floatval (option, value, _T("gfx_filter_horiz_offsetf"), ext, &gf->gfx_filter_horiz_offset)
+                       || cfgfile_intval (option, value, _T("gfx_filter_left_border"), ext, &gf->gfx_filter_left_border, 1)
+                       || cfgfile_intval (option, value, _T("gfx_filter_right_border"), ext, &gf->gfx_filter_right_border, 1)
+                       || cfgfile_intval (option, value, _T("gfx_filter_top_border"), ext, &gf->gfx_filter_top_border, 1)
+                       || cfgfile_intval (option, value, _T("gfx_filter_bottom_border"), ext, &gf->gfx_filter_bottom_border, 1)
                        || cfgfile_intval (option, value, _T("gfx_filter_scanlines"), ext, &gf->gfx_filter_scanlines, 1)
                        || cfgfile_intval (option, value, _T("gfx_filter_scanlinelevel"), ext, &gf->gfx_filter_scanlinelevel, 1)
                        || cfgfile_intval (option, value, _T("gfx_filter_scanlineratio"), ext, &gf->gfx_filter_scanlineratio, 1)
@@ -3101,10 +3124,11 @@ struct uaedev_config_data *add_filesys_config (struct uae_prefs *p, int index, s
        if (index < 0) {
                if (ci->controller_type != HD_CONTROLLER_TYPE_UAE) {
                        int ctrl = ci->controller_type;
+                       int ctrlunit = ci->controller_type_unit;
                        int cunit = ci->controller_unit;
                        for (;;) {
                                for (i = 0; i < p->mountitems; i++) {
-                                       if (p->mountconfig[i].ci.controller_type == ctrl && p->mountconfig[i].ci.controller_unit == cunit) {
+                                       if (p->mountconfig[i].ci.controller_type == ctrl && p->mountconfig[i].ci.controller_type_unit == ctrlunit && p->mountconfig[i].ci.controller_unit == cunit) {
                                                cunit++;
                                                if (ctrl >= HD_CONTROLLER_TYPE_IDE_FIRST && ctrl <= HD_CONTROLLER_TYPE_IDE_LAST && cunit == 4)
                                                        return NULL;
@@ -3241,8 +3265,8 @@ static void get_filesys_controller (const TCHAR *hdc, int *type, int *typenum, i
        } else if (_tcslen (hdc) >= 5 && !_tcsncmp (hdc, _T("scide"), 6)) {
                hdcv = HD_CONTROLLER_TYPE_PCMCIA_IDE;
        }
-       if (idx > 1)
-               idx = 1;
+       if (idx >= MAX_DUPLICATE_EXPANSION_BOARDS)
+               idx = MAX_DUPLICATE_EXPANSION_BOARDS - 1;
        *type = hdcv;
        *typenum = idx;
        *num = hdunit;
@@ -3710,10 +3734,10 @@ invalid_fs:
        return 0;
 }
 
-bool cfgfile_board_enabled(struct uae_prefs *p, int romtype)
+bool cfgfile_board_enabled(struct uae_prefs *p, int romtype, int devnum)
 {
        int idx;
-       struct boardromconfig *brc = get_device_rom(p, romtype, &idx);
+       struct boardromconfig *brc = get_device_rom(p, romtype, devnum, &idx);
        if (!brc)
                return false;
        return brc->roms[idx].romfile[0] != 0;
@@ -3805,69 +3829,78 @@ static bool cfgfile_read_board_rom(struct uae_prefs *p, const TCHAR *option, con
                int idx;
                ert = &expansionroms[i];
 
-               _stprintf(buf, _T("scsi_%s"), ert->name);
-               if (cfgfile_yesno(option, value, buf, &dummy)) {
-                       return true;
-               }
+               for (int j = 0; j < MAX_DUPLICATE_EXPANSION_BOARDS; j++) {
+                       TCHAR name[256];
+
+                       if (j == 0)
+                               _tcscpy(name, ert->name);
+                       else
+                               _stprintf(name, _T("%s-%d"), ert->name, j + 1);
 
-               _stprintf(buf, _T("%s_rom_file"), ert->name);
-               if (cfgfile_path(option, value, buf, buf2, MAX_DPATH / sizeof (TCHAR), mp)) {
-                       if (buf2[0]) {
-                               brc = get_device_rom_new(p, ert->romtype, &idx);
-                               _tcscpy(brc->roms[idx].romfile, buf2);
+                       _stprintf(buf, _T("scsi_%s"), name);
+                       if (cfgfile_yesno(option, value, buf, &dummy)) {
+                               return true;
                        }
-                       return true;
-               }
 
-               _stprintf(buf, _T("%s_rom_file_id"), ert->name);
-               if (cfgfile_rom (option, value, buf, buf2, MAX_DPATH / sizeof (TCHAR))) {
-                       if (buf2[0]) {
-                               brc = get_device_rom_new(p, ert->romtype, &idx);
-                               _tcscpy(brc->roms[idx].romfile, buf2);
+                       _stprintf(buf, _T("%s_rom_file"), name);
+                       if (cfgfile_path(option, value, buf, buf2, MAX_DPATH / sizeof (TCHAR), mp)) {
+                               if (buf2[0]) {
+                                       brc = get_device_rom_new(p, ert->romtype, j, &idx);
+                                       _tcscpy(brc->roms[idx].romfile, buf2);
+                               }
+                               return true;
                        }
-                       return true;
-               }
 
-               _stprintf(buf, _T("%s_rom"), ert->name);
-               if (cfgfile_string (option, value, buf, buf2, sizeof buf2 / sizeof (TCHAR))) {
-                       if (buf2[0]) {
-                               decode_rom_ident (buf3, sizeof(buf3) / sizeof (TCHAR), buf2, ert->romtype);
-                               if (buf3[0]) {
-                                       brc = get_device_rom_new(p, ert->romtype, &idx);
-                                       _tcscpy(brc->roms[idx].romident, buf3);
+                       _stprintf(buf, _T("%s_rom_file_id"), name);
+                       if (cfgfile_rom (option, value, buf, buf2, MAX_DPATH / sizeof (TCHAR))) {
+                               if (buf2[0]) {
+                                       brc = get_device_rom_new(p, ert->romtype, j, &idx);
+                                       _tcscpy(brc->roms[idx].romfile, buf2);
                                }
+                               return true;
                        }
-                       return true;
-               }
 
-               _stprintf(buf, _T("%s_rom_options"), ert->name);
-               if (cfgfile_string (option, value, buf, buf2, sizeof buf2 / sizeof (TCHAR))) {
-                       brc = get_device_rom_new(p, ert->romtype, &idx);
-                       if (cfgfile_option_bool(buf2, _T("autoboot_disabled")) == 1) {
-                               brc->roms[idx].autoboot_disabled = true;
+                       _stprintf(buf, _T("%s_rom"), name);
+                       if (cfgfile_string (option, value, buf, buf2, sizeof buf2 / sizeof (TCHAR))) {
+                               if (buf2[0]) {
+                                       decode_rom_ident (buf3, sizeof(buf3) / sizeof (TCHAR), buf2, ert->romtype);
+                                       if (buf3[0]) {
+                                               brc = get_device_rom_new(p, ert->romtype, j, &idx);
+                                               _tcscpy(brc->roms[idx].romident, buf3);
+                                       }
+                               }
+                               return true;
                        }
-                       if (ert->subtypes) {
-                               const struct expansionsubromtype *srt = ert->subtypes;
-                               TCHAR tmp[MAX_DPATH], *p;
-                               p = tmp;
-                               *p = 0;
-                               while (srt->name) {
-                                       _tcscpy(p, srt->configname);
-                                       p += _tcslen(p) + 1;
-                                       p[0] = 0;
-                                       srt++;
+
+                       _stprintf(buf, _T("%s_rom_options"), name);
+                       if (cfgfile_string (option, value, buf, buf2, sizeof buf2 / sizeof (TCHAR))) {
+                               brc = get_device_rom_new(p, ert->romtype, j, &idx);
+                               if (cfgfile_option_bool(buf2, _T("autoboot_disabled")) == 1) {
+                                       brc->roms[idx].autoboot_disabled = true;
+                               }
+                               if (ert->subtypes) {
+                                       const struct expansionsubromtype *srt = ert->subtypes;
+                                       TCHAR tmp[MAX_DPATH], *p;
+                                       p = tmp;
+                                       *p = 0;
+                                       while (srt->name) {
+                                               _tcscpy(p, srt->configname);
+                                               p += _tcslen(p) + 1;
+                                               p[0] = 0;
+                                               srt++;
+                                       }
+                                       int v = cfgfile_option_select(buf2, _T("subtype"), tmp);
+                                       if (v >= 0)
+                                               brc->roms[idx].subtype = v;
                                }
-                               int v = cfgfile_option_select(buf2, _T("subtype"), tmp);
-                               if (v >= 0)
-                                       brc->roms[idx].subtype = v;
+                               return true;
                        }
-                       return true;
                }
 
                _stprintf(buf, _T("%s_mem_size"), ert->name);
                if (cfgfile_intval (option, value, buf, &val, 0x40000)) {
                        if (val) {
-                               brc = get_device_rom_new(p, ert->romtype, &idx);
+                               brc = get_device_rom_new(p, ert->romtype, 0, &idx);
                                brc->roms[idx].board_ram_size = val;
                        }
                        return true;
@@ -4040,6 +4073,7 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH
                || cfgfile_strval (option, value, _T("floppy_auto_extended_adf"), &p->floppy_auto_ext2, autoext2, 0)
                || cfgfile_strval (option, value,  _T("z3mapping"), &p->z3_mapping_mode, z3mapping, 0)
                || cfgfile_strval (option, value,  _T("scsidev_mode"), &p->uaescsidevmode, uaescsidevmodes, 0)
+               || cfgfile_strval (option, value,  _T("boot_rom_uae"), &p->boot_rom, uaebootrom, 0)
                || cfgfile_strboolval (option, value, _T("comp_flushmode"), &p->comp_hardflush, flushmode, 0))
                return 1;
 
@@ -5750,6 +5784,7 @@ void default_prefs (struct uae_prefs *p, int type)
        p->catweasel = 0;
        p->tod_hack = 0;
        p->maprom = 0;
+       p->boot_rom = 0;
        p->filesys_no_uaefsdb = 0;
        p->filesys_custom_uaefsdb = 1;
        p->picasso96_nocustom = 1;
@@ -6044,8 +6079,8 @@ static void buildin_default_prefs (struct uae_prefs *p)
 
        _tcscpy (p->romextfile, _T(""));
        _tcscpy (p->romextfile2, _T(""));
-       set_device_rom(p, NULL, ROMTYPE_CPUBOARD);
-       set_device_rom(p, NULL, ROMTYPE_CPUBOARDEXT);
+       set_device_rom(p, NULL, ROMTYPE_CPUBOARD, 0);
+       set_device_rom(p, NULL, ROMTYPE_CPUBOARDEXT, 0);
 
        p->prtname[0] = 0;
        p->sername[0] = 0;
@@ -6169,8 +6204,7 @@ static int bip_a4000 (struct uae_prefs *p, int config, int compa, int romcheck)
                p->cpu_model = 68060;
                p->fpu_model = 68060;
                p->ppc_mode = 1;
-               p->cpuboard_type = BOARD_CYBERSTORM;
-               p->cpuboard_subtype = BOARD_CYBERSTORM_SUB_PPC;
+               cpuboard_setboard(p, BOARD_CYBERSTORM, BOARD_CYBERSTORM_SUB_PPC);
                p->cpuboardmem1_size = 128 * 1024 * 1024;
                int roms_ppc[] = { 98, -1 };
                configure_rom(p, roms_ppc, romcheck);
@@ -6226,12 +6260,8 @@ static int bip_a4000t (struct uae_prefs *p, int config, int compa, int romcheck)
        return configure_rom (p, roms, romcheck);
 }
 
-static int bip_velvet(struct uae_prefs *p, int config, int compa, int romcheck)
+static void bip_velvet(struct uae_prefs *p, int config, int compa, int romcheck)
 {
-       int roms[2];
-
-       roms[0] = 125;
-       roms[1] = -1;
        p->chipset_mask = 0;
        p->bogomem_size = 0;
        p->sound_filter = FILTER_SOUND_ON;
@@ -6245,7 +6275,6 @@ static int bip_velvet(struct uae_prefs *p, int config, int compa, int romcheck)
        p->cs_denisenoehb = 1;
        p->cs_cia6526 = 1;
        p->chipmem_size = 0x40000;
-       return configure_rom (p, roms, romcheck);
 }
 
 static int bip_a1000 (struct uae_prefs *p, int config, int compa, int romcheck)
@@ -6268,8 +6297,11 @@ static int bip_a1000 (struct uae_prefs *p, int config, int compa, int romcheck)
                p->cs_denisenoehb = 1;
        if (config > 1)
                p->chipmem_size = 0x40000;
-       if (config > 2)
+       if (config > 2) {
+               roms[0] = 125;
+               roms[1] = -1;
                bip_velvet(p, config, compa, romcheck);
+       }
        return configure_rom (p, roms, romcheck);
 }
 
@@ -6402,8 +6434,7 @@ static int bip_a1200 (struct uae_prefs *p, int config, int compa, int romcheck)
                p->cs_rtc = 1;
                break;
                case 2:
-               p->cpuboard_type = BOARD_BLIZZARD;
-               p->cpuboard_subtype = BOARD_BLIZZARD_SUB_1230IV;
+               cpuboard_setboard(p, BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_1230IV);
                p->cpuboardmem1_size = 32 * 1024 * 1024;
                p->cpu_model = 68030;
                p->cs_rtc = 1;
@@ -6411,8 +6442,7 @@ static int bip_a1200 (struct uae_prefs *p, int config, int compa, int romcheck)
                configure_rom(p, roms_bliz, romcheck);
                break;
                case 3:
-               p->cpuboard_type = BOARD_BLIZZARD;
-               p->cpuboard_subtype = BOARD_BLIZZARD_SUB_1260;
+               cpuboard_setboard(p, BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_1260);
                p->cpuboardmem1_size = 32 * 1024 * 1024;
                p->cpu_model = 68040;
                p->fpu_model = 68040;
@@ -6421,8 +6451,7 @@ static int bip_a1200 (struct uae_prefs *p, int config, int compa, int romcheck)
                configure_rom(p, roms_bliz, romcheck);
                break;
                case 4:
-               p->cpuboard_type = BOARD_BLIZZARD;
-               p->cpuboard_subtype = BOARD_BLIZZARD_SUB_1260;
+               cpuboard_setboard(p, BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_1260);
                p->cpuboardmem1_size = 32 * 1024 * 1024;
                p->cpu_model = 68060;
                p->fpu_model = 68060;
@@ -6431,8 +6460,7 @@ static int bip_a1200 (struct uae_prefs *p, int config, int compa, int romcheck)
                configure_rom(p, roms_bliz, romcheck);
                break;
                case 5:
-               p->cpuboard_type = BOARD_BLIZZARD;
-               p->cpuboard_subtype = BOARD_BLIZZARD_SUB_PPC;
+               cpuboard_setboard(p, BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_PPC);
                p->cpuboardmem1_size = 256 * 1024 * 1024;
                p->cpu_model = 68060;
                p->fpu_model = 68060;
@@ -6770,6 +6798,13 @@ int built_in_chipset_prefs (struct uae_prefs *p)
                p->cs_dipagnus = 1;
                p->cs_ciatodbug = true;
                break;
+       case CP_VELVET: // A1000 Prototype
+               p->cs_ciaatod = p->ntscmode ? 2 : 1;
+               p->cs_ksmirror_e0 = 0;
+               p->cs_agnusbltbusybug = 1;
+               p->cs_dipagnus = 1;
+               p->cs_denisenoehb = 1;
+               break;
        case CP_A1200: // A1200
                p->cs_ide = IDE_A600A1200;
                p->cs_pcmcia = 1;
@@ -6836,7 +6871,7 @@ int built_in_cpuboard_prefs(struct uae_prefs *p)
        roms2[0] = -1;
        roms2[1] = -1;
 
-       switch(p->cpuboard_type)
+       switch(cpuboards[p->cpuboard_type].id)
        {
                case BOARD_MACROSYSTEM:
                switch(p->cpuboard_subtype)
diff --git a/cia.cpp b/cia.cpp
index a73f7b9e41ee05be3af6fd559c4575e531a2100a..c2b3765d612324e150bb599be0d338f91b4172f0 100644 (file)
--- a/cia.cpp
+++ b/cia.cpp
@@ -992,7 +992,7 @@ static uae_u8 ReadCIAA (unsigned int addr)
 #ifdef ACTION_REPLAY
                action_replay_ciaread ();
 #endif
-               tmp = DISK_status() & 0x3c;
+               tmp = DISK_status_ciaa() & 0x3c;
                tmp |= handle_joystick_buttons (ciaapra, ciaadra);
                tmp |= (ciaapra | (ciaadra ^ 3)) & 0x03;
                tmp = dongle_cia_read (0, reg, tmp);
@@ -1183,6 +1183,7 @@ static uae_u8 ReadCIAB (unsigned int addr)
                        write_log (_T("BFD100 R %02X %s\n"), ciabprb, debuginfo(0));
 #endif
                tmp = ciabprb;
+               tmp = DISK_status_ciab(tmp);
                tmp = dongle_cia_read (1, reg, tmp);
                if (ciabcrb & 2) {
                        int pb7 = 0;
@@ -1297,7 +1298,7 @@ static void WriteCIAA (uae_u16 addr, uae_u8 val)
                handle_cd32_joystick_cia (ciaapra, ciaadra);
                dongle_cia_write (0, reg, val);
 #ifdef AMAX
-               if (is_device_rom(&currprefs, 0, ROMTYPE_AMAX) > 0)
+               if (is_device_rom(&currprefs, ROMTYPE_AMAX, 0) > 0)
                        amax_bfe001_write (val, ciaadra);
 #endif
                break;
index f0465d7ea696c0a88df6104ce2a3b4239b44ca6e..6133268ec7d61b2bdcb495fdbdcb8e002d2a34e2 100644 (file)
@@ -281,6 +281,10 @@ static bool is_apollo(void)
 {
        return ISCPUBOARD(BOARD_ACT, BOARD_ACT_SUB_APOLLO);
 }
+static bool is_kupke(void)
+{
+       return ISCPUBOARD(BOARD_KUPKE, 0);
+}
 
 DECLARE_MEMORY_FUNCTIONS(blizzardio);
 static addrbank blizzardio_bank = {
@@ -302,7 +306,7 @@ DECLARE_MEMORY_FUNCTIONS(blizzardea);
 static addrbank blizzardea_bank = {
        blizzardea_lget, blizzardea_wget, blizzardea_bget,
        blizzardea_lput, blizzardea_wput, blizzardea_bput,
-       blizzardea_xlate, blizzardea_check, NULL, _T("rom_ea"), _T("CPUBoard EA Autoconfig"),
+       blizzardea_xlate, blizzardea_check, NULL, _T("rom_ea"), _T("CPUBoard E9/EA Autoconfig"),
        blizzardea_lget, blizzardea_wget, ABFLAG_IO | ABFLAG_SAFE
 };
 
@@ -749,7 +753,7 @@ static void REGPARAM2 blizzarde8_bput(uaecptr addr, uae_u32 b)
        b &= 0xff;
        addr &= 65535;
        if (addr == 0x48 && !configured) {
-               map_banks(&blizzardea_bank, b, 0x20000 >> 16, 0x20000);
+               map_banks(&blizzardea_bank, b, blizzardea_bank.allocated >> 16, 0);
                write_log(_T("Accelerator Z2 board autoconfigured at %02X0000\n"), b);
                configured = 1;
                expamem_next (&blizzardea_bank, NULL);
@@ -880,7 +884,7 @@ static void cyberstormmk2_maprom(void)
                map_banks_nojitdirect(&blizzardmaprom_bank, blizzardmaprom_bank.start >> 16, 524288 >> 16, 0);
 }
 
-void cyberstorm_irq(int level)
+void cyberstorm_mk3_ppc_irq(int level)
 {
        if (level)
                io_reg[CSIII_REG_IRQ] &= ~P5_IRQ_SCSI;
@@ -1074,7 +1078,7 @@ static void REGPARAM2 blizzardio_bput(uaecptr addr, uae_u32 v)
                                                        write_log(_T("CS: SCSI reset cleared\n"));
                                                map_banks(&blizzardf0_bank, 0xf00000 >> 16, 0x40000 >> 16, 0);
                                                if (is_blizzardppc() || flash_size(flashrom) >= 262144) {
-                                                       map_banks(&ncr_bank_blizzardppc, 0xf40000 >> 16, 0x10000 >> 16, 0);
+                                                       map_banks(&ncr_bank_generic, 0xf40000 >> 16, 0x10000 >> 16, 0);
                                                } else {
                                                        map_banks(&ncr_bank_cyberstorm, 0xf40000 >> 16, 0x10000 >> 16, 0);
                                                        map_banks(&blizzardio_bank, 0xf50000 >> 16, 0x10000 >> 16, 0);
@@ -1400,6 +1404,12 @@ void cpuboard_init(void)
                blizzardea_bank.mask = blizzardea_bank.allocated - 1;
                mapped_malloc(&blizzardea_bank);
 
+       } else if (is_kupke()) {
+
+               blizzardea_bank.allocated = 65536;
+               blizzardea_bank.mask = blizzardea_bank.allocated - 1;
+               mapped_malloc(&blizzardea_bank);
+
        } else if (is_apollo()) {
 
                blizzardf0_bank.start = 0x00f00000;
@@ -1653,6 +1663,20 @@ int cpuboard_maxmemory(struct uae_prefs *p)
        return 0;
 }
 
+void cpuboard_setboard(struct uae_prefs *p, int type, int subtype)
+{
+       p->cpuboard_type = 0;
+       p->cpuboard_subtype = 0;
+       for (int i = 0; cpuboards[i].name; i++) {
+               if (cpuboards[i].id == type) {
+                       p->cpuboard_type = type;
+                       if (subtype >= 0)
+                               p->cpuboard_subtype = subtype;
+                       return;
+               }
+       }
+}
+
 bool cpuboard_io_special(int addr, uae_u32 *val, int size, bool write)
 {
        addr &= 65535;
@@ -1821,7 +1845,7 @@ static void ew(uae_u8 *p, int addr, uae_u8 value)
        }
 }
 
-addrbank *cpuboard_autoconfig_init(int devnum)
+addrbank *cpuboard_autoconfig_init(struct romconfig *rc)
 {
        struct zfile *autoconfig_rom = NULL;
        struct boardromconfig *brc, *brc2;
@@ -1834,8 +1858,8 @@ addrbank *cpuboard_autoconfig_init(int devnum)
        struct romdata *rd = NULL;
 
        int idx, idx2;
-       brc = get_device_rom(&currprefs, ROMTYPE_CPUBOARD, &idx);
-       brc2 = get_device_rom(&currprefs, ROMTYPE_CPUBOARDEXT, &idx2);
+       brc = get_device_rom(&currprefs, ROMTYPE_CPUBOARD, 0, &idx);
+       brc2 = get_device_rom(&currprefs, ROMTYPE_CPUBOARDEXT, 0, &idx2);
        if (brc)
                romname = brc->roms[idx].romfile;
 
@@ -1846,7 +1870,8 @@ addrbank *cpuboard_autoconfig_init(int devnum)
        roms2[1] = -1;
        roms2[2] = -1;
        cpuboard_non_byte_ea = false;
-       switch (currprefs.cpuboard_type)
+       int boardid = cpuboards[currprefs.cpuboard_type].id;
+       switch (boardid)
        {
                case BOARD_COMMODORE:
                switch(currprefs.cpuboard_subtype)
@@ -1950,6 +1975,10 @@ addrbank *cpuboard_autoconfig_init(int devnum)
                }
                break;
 
+               case BOARD_KUPKE:
+                       roms[0] = 126;
+               break;
+
                default:
                        return &expamem_null;
        }
@@ -2017,6 +2046,14 @@ addrbank *cpuboard_autoconfig_init(int devnum)
                zfile_fread(blizzardf0_bank.baseaddr, 1, f0rom_size, autoconfig_rom);
                autoconf = false;
                autoconf_stop = true;
+       } else if (is_kupke()) {
+               earom_size = 65536;
+               for (int i = 0; i < 8192; i++) {
+                       uae_u8 b = 0xff;
+                       zfile_fread(&b, 1, 1, autoconfig_rom);
+                       blizzardea_bank.baseaddr[i * 2 + 0] = b;
+                       blizzardea_bank.baseaddr[i * 2 + 1] = 0xff;
+               }
        } else if (is_apollo()) {
                f0rom_size = 131072;
                zfile_fread(blizzardf0_bank.baseaddr, 1, 131072, autoconfig_rom);
index a19fcd822a8a6cb3166412390c061f2c82b1e8b3..a0a998d7497c7a2f9ec35e9a3ccaba3d8f8f9218 100644 (file)
@@ -68,7 +68,6 @@ static void mmu_dump_ttr(const TCHAR * label, uae_u32 ttr)
        from_addr = ttr & MMU_TTR_LOGICAL_BASE;
        to_addr = (ttr & MMU_TTR_LOGICAL_MASK) << 8;
 
-       
 #if MMUDEBUG > 0
        write_log(_T("%s: [%08lx] %08lx - %08lx enabled=%d supervisor=%d wp=%d cm=%02d\n"),
                        label, ttr,
index aff8fbbcabbc9602e9eb3c9e37722e5e8f6f43d7..9e2c60a6747507081861763edcdae2f667559bc6 100644 (file)
@@ -712,7 +712,6 @@ int mmu030_do_match_lrmw_ttr(uae_u32 tt, TT_info comp, uaecptr addr, uae_u32 fc)
 
 static void mmu030_do_fake_prefetch(void)
 {
-       uaecptr pc = m68k_getpci();
        // fetch next opcode before MMU state switches.
        // There are programs that do following:
        // - enable MMU
index c67623c14b5d61f041618bad044266e7b56bfaf3..09870d06b75221da62a5a31b77d78d98c7559c18 100644 (file)
@@ -8100,7 +8100,7 @@ void custom_reset (bool hardreset, bool keyboardreset)
 
                if (hardreset) {
                        if (!aga_mode) {
-                               uae_u16 c = ((currprefs.chipset_mask & CSMASK_ECS_DENISE) && !(currprefs.chipset_mask & CSMASK_AGA)) ? 0xfff : 0x000;
+                               uae_u16 c = (((currprefs.chipset_mask & CSMASK_ECS_DENISE) && !(currprefs.chipset_mask & CSMASK_AGA)) || currprefs.cs_denisenoehb) ? 0xfff : 0x000;
                                for (i = 0; i < 32; i++) {
                                        current_colors.color_regs_ecs[i] = c;
                                        current_colors.acolors[i] = getxcolor (c);
@@ -8333,7 +8333,7 @@ int custom_init (void)
 {
 
 #ifdef AUTOCONFIG
-       if (uae_boot_rom) {
+       if (uae_boot_rom_type) {
                uaecptr pos;
                pos = here ();
 
@@ -9330,8 +9330,8 @@ uae_u8 *save_custom_extra (int *len, uae_u8 *dstptr)
        SB (currprefs.cs_a1000ram ? 1 : 0);
        SB (currprefs.cs_slowmemisfast ? 1 : 0);
 
-       SB (cfgfile_board_enabled(&currprefs, ROMTYPE_A2091) ? 1 : 0);
-       SB (cfgfile_board_enabled(&currprefs, ROMTYPE_A4091) ? 1 : 0);
+       SB (cfgfile_board_enabled(&currprefs, ROMTYPE_A2091, 0) ? 1 : 0);
+       SB (cfgfile_board_enabled(&currprefs, ROMTYPE_A4091, 0) ? 1 : 0);
        SB (currprefs.cs_cdtvscsi ? 1 : 0);
 
        SB (currprefs.cs_pcmcia ? 1 : 0);
index 51fb97145928d1be25e6e8249b3b46502323f60c..7c6614b64adb162a6e68900da41b0cfa7c374974 100644 (file)
--- a/debug.cpp
+++ b/debug.cpp
@@ -1828,7 +1828,7 @@ static void illg_init (void)
        if (currprefs.cs_ksmirror_a8)
                memset (illgdebug + 0xa80000, 1, 2 * 512 * 1024);
 #ifdef FILESYS
-       if (uae_boot_rom) /* filesys "rom" */
+       if (uae_boot_rom_type) /* filesys "rom" */
                memset (illgdebug + rtarea_base, 1, 0x10000);
 #endif
        if (currprefs.cs_ide > 0)
@@ -1887,7 +1887,8 @@ static int debug_mem_off (uaecptr *addrp)
        ba = debug_mem_banks[offset];
        if (!ba)
                return offset;
-       addr = (addr & ba->mask) | ba->startmask;
+       if (ba->mask || ba->startmask)
+               addr = (addr & ba->mask) | ba->startmask;
        *addrp = addr;
        return offset;
 }
@@ -3393,7 +3394,7 @@ static void show_exec_lists (TCHAR *t)
                                                (diagarea[12] << 8) | diagarea[13]);
                                        if (nameoffset != 0 && nameoffset != 0xffff) {
                                                copyromdata(config, rom, nameoffset, diagarea, 256);
-                                               diagarea[256] = 0;
+                                               diagarea[sizeof diagarea - 1] = 0;
                                                TCHAR *str = au((char*)diagarea);
                                                console_out_f(_T(" '%s'\n"), str);
                                                xfree(str);
index ad0986274201f646a0d7dbac2aa2f184971afae0..7a6afbc6aa2fa7906a13f8a20daadb201c7a053d 100644 (file)
@@ -65,8 +65,7 @@ void devices_reset(int hardreset)
        DISK_reset ();
        CIA_reset ();
        gayle_reset (0);
-       apolloscsi_reset();
-       ncr5380scsi_reset();
+       soft_scsi_reset();
 #ifdef A2091
        a2091_reset ();
        gvp_reset ();
@@ -78,7 +77,6 @@ void devices_reset(int hardreset)
        sndboard_reset();
 #endif
 #ifdef NCR
-       ncr710_reset();
        ncr_reset();
 #endif
 #ifdef NCR9X
@@ -277,10 +275,8 @@ void do_leave_program (void)
        gvp_free ();
        a3000scsi_free ();
 #endif
-       apolloscsi_free();
-       ncr5380scsi_free();
+       soft_scsi_free();
 #ifdef NCR
-       ncr710_free();
        ncr_free();
 #endif
 #ifdef NCR9X
@@ -362,7 +358,6 @@ void virtualdevice_init (void)
        tabletlib_install ();
 #endif
 #ifdef NCR
-       ncr710_init();
        ncr_init();
 #endif
 #ifdef NCR9X
index 01d102a1c693ed6b382731f190d53505a00bb18f..63ebe24341a979245e3fe33c44f8a61d954db6cd 100644 (file)
--- a/disk.cpp
+++ b/disk.cpp
@@ -127,6 +127,7 @@ static uae_u8 prev_data;
 static int prev_step;
 static bool initial_disk_statusline;
 static struct diskinfo disk_info_data = { 0 };
+static bool amax_enabled;
 
 typedef enum { TRACK_AMIGADOS, TRACK_RAW, TRACK_RAW1, TRACK_PCDOS, TRACK_DISKSPARE, TRACK_NONE } image_tracktype;
 typedef struct {
@@ -658,9 +659,11 @@ static void reset_drive_gui (int num)
 static void setamax (void)
 {
 #ifdef AMAX
-       if (is_device_rom(&currprefs, 0, ROMTYPE_AMAX) > 0) {
+       amax_enabled = false;
+       if (is_device_rom(&currprefs, ROMTYPE_AMAX, 0) > 0) {
                /* Put A-Max as last drive in drive chain */
                int j;
+               amax_enabled = true;
                for (j = 0; j < MAX_FLOPPY_DRIVES; j++)
                        if (floppy[j].amax)
                                return;
@@ -1055,7 +1058,11 @@ static void update_disk_statusline(int num)
        drive *drv = &floppy[num];
        if (!drv->diskfile)
                return;
-       TCHAR *fname = zfile_getname(drv->diskfile);
+       TCHAR *fname = zfile_getoriginalname(drv->diskfile);
+       if (!fname)
+               fname = zfile_getname(drv->diskfile);
+       if (!fname)
+               fname = _T("?");
        if (disk_info_data.diskname[0])
                statusline_add_message(_T("DF%d: [%s] %s"), num, disk_info_data.diskname, my_getfilepart(fname));
        else
@@ -2824,7 +2831,11 @@ static TCHAR *tobin (uae_u8 v)
 
 static void fetch_DISK_select(uae_u8 data)
 {
-       selected = (data >> 3) & 15;
+       if (currprefs.cs_compatible == CP_VELVET) {
+               selected = (data >> 3) & 3;
+       } else {
+               selected = (data >> 3) & 15;
+       }
        side = 1 - ((data >> 2) & 1);
        direction = (data >> 1) & 1;
 }
@@ -2839,6 +2850,7 @@ void DISK_select_set (uae_u8 data)
 
 void DISK_select (uae_u8 data)
 {
+       bool velvet = currprefs.cs_compatible == CP_VELVET;
        int step_pulse, prev_selected, dr;
 
        prev_selected = selected;
@@ -2846,11 +2858,16 @@ void DISK_select (uae_u8 data)
        fetch_DISK_select (data);
        step_pulse = data & 1;
 
-       if (disk_debug_logging > 1)
-               write_log (_T("%08X %02X->%02X %s drvmask=%x"), M68K_GETPC, prev_data, data, tobin(data), selected ^ 15);
+       if (disk_debug_logging > 1) {
+               if (velvet) {
+                       write_log (_T("%08X %02X->%02X %s drvmask=%x"), M68K_GETPC, prev_data, data, tobin(data), selected ^ 3);
+               } else {
+                       write_log (_T("%08X %02X->%02X %s drvmask=%x"), M68K_GETPC, prev_data, data, tobin(data), selected ^ 15);
+               }
+       }
 
 #ifdef AMAX
-       if (is_device_rom(&currprefs, 0, ROMTYPE_AMAX) > 0) {
+       if (amax_enabled) {
                for (dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) {
                        drive *drv = floppy + dr;
                        if (drv->amax)
@@ -2859,24 +2876,42 @@ void DISK_select (uae_u8 data)
        }
 #endif
 
-       if ((prev_data & 0x80) != (data & 0x80)) {
-               for (dr = 0; dr < 4; dr++) {
-                       if (floppy[dr].indexhackmode > 1 && !(selected & (1 << dr))) {
-                               floppy[dr].indexhack = 1;
-                               if (disk_debug_logging > 1)
-                                       write_log (_T(" indexhack!"));
+       if (!velvet) {
+               if ((prev_data & 0x80) != (data & 0x80)) {
+                       for (dr = 0; dr < 4; dr++) {
+                               if (floppy[dr].indexhackmode > 1 && !(selected & (1 << dr))) {
+                                       floppy[dr].indexhack = 1;
+                                       if (disk_debug_logging > 1)
+                                               write_log (_T(" indexhack!"));
+                               }
                        }
                }
        }
 
        if (disk_debug_logging > 1) {
-               write_log (_T(" %d%d%d%d% "), (selected & 1) ? 0 : 1, (selected & 2) ? 0 : 1, (selected & 4) ? 0 : 1, (selected & 8) ? 0 : 1);
-               if ((prev_data & 0x80) != (data & 0x80))
-                       write_log (_T(" dskmotor %d "), (data & 0x80) ? 1 : 0);
-               if ((prev_data & 0x02) != (data & 0x02))
-                       write_log (_T(" direct %d "), (data & 0x02) ? 1 : 0);
-               if ((prev_data & 0x04) != (data & 0x04))
-                       write_log (_T(" side %d "), (data & 0x04) ? 1 : 0);
+               if (velvet) {
+                       write_log (_T(" %d%d "), (selected & 1) ? 0 : 1, (selected & 2) ? 0 : 1);
+                       if ((prev_data & 0x08) != (data & 0x08))
+                               write_log (_T(" dsksel0 %d "), (data & 0x08) ? 0 : 1);
+                       if ((prev_data & 0x10) != (data & 0x10))
+                               write_log (_T(" dsksel1 %d "), (data & 0x10) ? 0 : 1);
+                       if ((prev_data & 0x20) != (data & 0x20))
+                               write_log (_T(" dskmotor0 %d "), (data & 0x20) ? 0 : 1);
+                       if ((prev_data & 0x40) != (data & 0x40))
+                               write_log (_T(" dskmotor1 %d "), (data & 0x40) ? 0 : 1);
+                       if ((prev_data & 0x02) != (data & 0x02))
+                               write_log (_T(" direct %d "), (data & 0x02) ? 1 : 0);
+                       if ((prev_data & 0x04) != (data & 0x04))
+                               write_log (_T(" side %d "), (data & 0x04) ? 1 : 0);
+               } else {
+                       write_log (_T(" %d%d%d%d% "), (selected & 1) ? 0 : 1, (selected & 2) ? 0 : 1, (selected & 4) ? 0 : 1, (selected & 8) ? 0 : 1);
+                       if ((prev_data & 0x80) != (data & 0x80))
+                               write_log (_T(" dskmotor %d "), (data & 0x80) ? 1 : 0);
+                       if ((prev_data & 0x02) != (data & 0x02))
+                               write_log (_T(" direct %d "), (data & 0x02) ? 1 : 0);
+                       if ((prev_data & 0x04) != (data & 0x04))
+                               write_log (_T(" side %d "), (data & 0x04) ? 1 : 0);
+               }
        }
 
        // step goes high and drive was selected when step pulse changes: step
@@ -2896,30 +2931,45 @@ void DISK_select (uae_u8 data)
        }
 
        if (!savestate_state) {
-               for (dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) {
-                       drive *drv = floppy + dr;
-                       /* motor on/off workings tested with small assembler code on real Amiga 1200. */
-                       /* motor/id flipflop is set only when drive select goes from high to low */
-                       if (!(selected & (1 << dr)) && (prev_selected & (1 << dr)) ) {
-                               drv->drive_id_scnt++;
-                               drv->drive_id_scnt &= 31;
-                               drv->idbit = (drv->drive_id & (1L << (31 - drv->drive_id_scnt))) ? 1 : 0;
-                               if (!(disabled & (1 << dr))) {
-                                       if ((prev_data & 0x80) == 0 || (data & 0x80) == 0) {
-                                               /* motor off: if motor bit = 0 in prevdata or data -> turn motor on */
-                                               drive_motor (drv, 0);
-                                       } else if (prev_data & 0x80) {
-                                               /* motor on: if motor bit = 1 in prevdata only (motor flag state in data has no effect)
-                                               -> turn motor off */
-                                               drive_motor (drv, 1);
+               if (velvet) {
+                       for (dr = 0; dr < 2; dr++) {
+                               drive *drv = floppy + dr;
+                               int motormask = 0x20 << dr;
+                               int selectmask = 0x08 << dr;
+                               if (!(selected & (1 << dr)) && !(disabled & (1 << dr))) {
+                                       if (!(prev_data & motormask) && (data & motormask)) {
+                                               drive_motor(drv, 1);
+                                       } else if ((prev_data & motormask) && !(data & motormask)) {
+                                               drive_motor(drv, 0);
                                        }
                                }
-                               if (!currprefs.cs_df0idhw && dr == 0)
-                                       drv->idbit = 0;
+                       }
+               } else {
+                       for (dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) {
+                               drive *drv = floppy + dr;
+                               /* motor on/off workings tested with small assembler code on real Amiga 1200. */
+                               /* motor/id flipflop is set only when drive select goes from high to low */
+                               if (!(selected & (1 << dr)) && (prev_selected & (1 << dr)) ) {
+                                       drv->drive_id_scnt++;
+                                       drv->drive_id_scnt &= 31;
+                                       drv->idbit = (drv->drive_id & (1L << (31 - drv->drive_id_scnt))) ? 1 : 0;
+                                       if (!(disabled & (1 << dr))) {
+                                               if ((prev_data & 0x80) == 0 || (data & 0x80) == 0) {
+                                                       /* motor off: if motor bit = 0 in prevdata or data -> turn motor on */
+                                                       drive_motor (drv, 0);
+                                               } else if (prev_data & 0x80) {
+                                                       /* motor on: if motor bit = 1 in prevdata only (motor flag state in data has no effect)
+                                                       -> turn motor off */
+                                                       drive_motor (drv, 1);
+                                               }
+                                       }
+                                       if (!currprefs.cs_df0idhw && dr == 0)
+                                               drv->idbit = 0;
 #ifdef DEBUG_DRIVE_ID
-                               write_log (_T("DISK_status: sel %d id %s (%08X) [0x%08lx, bit #%02d: %d]\n"),
-                                       dr, drive_id_name(drv), drv->drive_id, drv->drive_id << drv->drive_id_scnt, 31 - drv->drive_id_scnt, drv->idbit);
+                                       write_log (_T("DISK_status: sel %d id %s (%08X) [0x%08lx, bit #%02d: %d]\n"),
+                                               dr, drive_id_name(drv), drv->drive_id, drv->drive_id << drv->drive_id_scnt, 31 - drv->drive_id_scnt, drv->idbit);
 #endif
+                               }
                        }
                }
        }
@@ -2933,12 +2983,46 @@ void DISK_select (uae_u8 data)
                write_log (_T("\n"));
 }
 
-uae_u8 DISK_status (void)
+uae_u8 DISK_status_ciab(uae_u8 st)
+{
+       if (currprefs.cs_compatible == CP_VELVET) {
+               st |= 0x80;
+               for (int dr = 0; dr < 2; dr++) {
+                       drive *drv = floppy + dr;
+                       if (!(((selected >> 3) | disabled) & (1 << dr))) {
+                               if (drive_writeprotected (drv))
+                                       st &= ~0x80;
+                       }
+               }
+               if (disk_debug_logging > 1) {
+                       write_log(_T("DISK_STATUS_CIAB %08x %02x\n"), M68K_GETPC, st);
+               }
+       }
+
+       return st;
+}
+
+uae_u8 DISK_status_ciaa(void)
 {
        uae_u8 st = 0x3c;
-       int dr;
 
-       for (dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) {
+       if (currprefs.cs_compatible == CP_VELVET) {
+               for (int dr = 0; dr < 2; dr++) {
+                       drive *drv = floppy + dr;
+                       if (!(((selected >> 3) | disabled) & (1 << dr))) {
+                               if (drv->dskchange)
+                                       st &= ~0x20;
+                               if (drive_track0 (drv))
+                                       st &= ~0x10;
+                       }
+               }
+               if (disk_debug_logging > 1) {
+                       write_log(_T("DISK_STATUS_CIAA %08x %02x\n"), M68K_GETPC, st);
+               }
+               return st;
+       }
+
+       for (int dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) {
                drive *drv = floppy + dr;
                if (drv->amax) {
                        if (amax_active())
@@ -3164,10 +3248,10 @@ static void disk_doupdate_write (drive * drv, int floppybits)
                                                        drv2->bigmfmbuf[(drv2->mfmpos >> 4) + 1] = 0x5555;
                                                        drv2->writtento = 1;
                                                }
-       #ifdef AMAX
-                                               if (is_device_rom(&currprefs, 0, ROMTYPE_AMAX) > 0)
+#ifdef AMAX
+                                               if (amax_enabled)
                                                        amax_diskwrite (w);
-       #endif
+#endif
                                        }
                                        dsklength--;
                                        if (dsklength <= 0) {
@@ -3729,7 +3813,7 @@ void DSKLEN (uae_u16 v, int hpos)
                        break;
        }
        if (dr == 4) {
-               if (is_device_rom(&currprefs, 0, ROMTYPE_AMAX) <= 0) {
+               if (!amax_enabled) {
                        write_log (_T("disk %s DMA started, drvmask=%x motormask=%x PC=%08x\n"),
                                dskdmaen == DSKDMA_WRITE ? _T("write") : _T("read"), selected ^ 15, motormask, M68K_GETPC);
                }
@@ -3807,7 +3891,7 @@ void DSKLEN (uae_u16 v, int hpos)
                                        uae_u16 w = chipmem_wget_indirect (dskpt + i * 2);
                                        drv->bigmfmbuf[pos >> 4] = w;
 #ifdef AMAX
-                                       if (is_device_rom(&currprefs, 0, ROMTYPE_AMAX) > 0)
+                                       if (amax_enabled)
                                                amax_diskwrite (w);
 #endif
                                        pos += 16;
@@ -3824,7 +3908,7 @@ void DSKLEN (uae_u16 v, int hpos)
                                if (dskdmaen == DSKDMA_WRITE) {
                                        uae_u16 w = chipmem_wget_indirect (dskpt);
 #ifdef AMAX
-                                       if (is_device_rom(&currprefs, 0, ROMTYPE_AMAX) > 0) {
+                                       if (amax_enabled) {
                                                amax_diskwrite (w);
                                                if (w) {
                                                        for (int i = 0; i < 16; i++) {
index d4d59571cc5071da8fcff5d339d8fef063ca12bb..03f8dbff8076afee8c5739a80261b086224be815 100644 (file)
@@ -2740,6 +2740,16 @@ static void center_image (void)
        gfxvidinfo.drawbuffer.xoffset = (DISPLAY_LEFT_SHIFT << RES_MAX) + (visible_left_border << (RES_MAX - currprefs.gfx_resolution));
        gfxvidinfo.drawbuffer.yoffset = thisframe_y_adjust << VRES_MAX;
 
+       struct gfx_filterdata *f = &currprefs.gf[0];
+       if (f->gfx_filter_left_border > 0 && f->gfx_filter_left_border > visible_left_border)
+               visible_left_border = f->gfx_filter_left_border;
+       if (f->gfx_filter_right_border > 0 && f->gfx_filter_right_border < visible_right_border)
+               visible_right_border = f->gfx_filter_right_border;
+       if (f->gfx_filter_top_border > 0 && f->gfx_filter_top_border > visible_top_start)
+               visible_top_start = f->gfx_filter_top_border;
+       if (f->gfx_filter_bottom_border > 0 && f->gfx_filter_bottom_border < visible_bottom_stop)
+               visible_bottom_stop = f->gfx_filter_bottom_border;
+
        center_reset = false;
        horizontal_changed = false;
        vertical_changed = false;
@@ -2770,7 +2780,7 @@ static void init_drawing_frame (void)
                                // enable full doubling/superhires support if programmed mode. It may be "half-width" only and may fit in normal display window.
                                gfxvidinfo.gfx_resolution_reserved = RES_SUPERHIRES;
                                gfxvidinfo.gfx_vresolution_reserved = VRES_DOUBLE;
-                               graphics_reset();
+                               graphics_reset(false);
                        }
                        int newres = largest_res;
                        if (htotal < 190)
index 1b2b8dbc247a9d6203cfd081e1b24981efa65a1a..fb8319e01f5946297b9ce213c913356c99ed8fcc 100644 (file)
@@ -141,16 +141,23 @@ uaecptr ROM_filesys_resname, ROM_filesys_resid;
 uaecptr ROM_filesys_diagentry;
 uaecptr ROM_hardfile_resname, ROM_hardfile_resid;
 uaecptr ROM_hardfile_init;
-bool uae_boot_rom;
+int uae_boot_rom_type;
 int uae_boot_rom_size; /* size = code size only */
 static bool chipdone;
 
 /* ********************************************************** */
 
-static addrbank* (*card_init[MAX_EXPANSION_BOARD_SPACE])(int);
-static addrbank* (*card_map[MAX_EXPANSION_BOARD_SPACE])(void);
-static const TCHAR *card_name[MAX_EXPANSION_BOARD_SPACE];
-static int card_flags[MAX_EXPANSION_BOARD_SPACE];
+struct card_data
+{
+       addrbank *(*initrc)(struct romconfig*);
+       addrbank *(*initnum)(int);
+       addrbank *(*map)(void);
+       struct romconfig *rc;
+       const TCHAR *name;
+       int flags;
+};
+
+static struct card_data cards[MAX_EXPANSION_BOARD_SPACE];
 
 static int ecard, cardno, z3num;
 static addrbank *expamem_bank_current;
@@ -333,8 +340,11 @@ static void call_card_init(int index)
        uae_u8 code;
        uae_u32 expamem_z3_pointer_old;
 
-       expamem_bank.name = card_name[ecard] ? card_name[ecard] : _T("None");
-       ab = (*card_init[ecard])(0);
+       expamem_bank.name = cards[ecard].name ? cards[ecard].name : _T("None");
+       if (cards[ecard].initnum)
+               ab = cards[ecard].initnum(0);
+       else
+               ab = cards[ecard].initrc(cards[ecard].rc);
        expamem_z3_size = 0;
        if (ab == &expamem_none) {
                expamem_init_clear();
@@ -406,7 +416,7 @@ static void call_card_init(int index)
        if (ab) {
                // non-NULL: not using expamem_bank
                expamem_bank_current = ab;
-               if ((card_flags[ecard] & 1) && currprefs.cs_z3autoconfig && !currprefs.address_space_24) {
+               if ((cards[ecard].flags & 1) && currprefs.cs_z3autoconfig && !currprefs.address_space_24) {
                        map_banks(&expamemz3_bank, 0xff000000 >> 16, 1, 0);
                        map_banks(&dummy_bank, 0xE8, 1, 0);
                } else {
@@ -415,7 +425,7 @@ static void call_card_init(int index)
                                map_banks(&dummy_bank, 0xff000000 >> 16, 1, 0);
                }
        } else {
-               if ((card_flags[ecard] & 1) && currprefs.cs_z3autoconfig && !currprefs.address_space_24) {
+               if ((cards[ecard].flags & 1) && currprefs.cs_z3autoconfig && !currprefs.address_space_24) {
                        map_banks(&expamemz3_bank, 0xff000000 >> 16, 1, 0);
                        map_banks(&dummy_bank, 0xE8, 1, 0);
                        expamem_bank_current = &expamem_bank;
@@ -574,8 +584,8 @@ static void REGPARAM2 expamem_wput (uaecptr addr, uae_u32 value)
                        expamem_hi = (value >> 8) & 0xff;
                        expamem_z2_pointer = (expamem_hi | (expamem_lo >> 4)) << 16; 
                        expamem_board_pointer = expamem_z2_pointer;
-                       if (card_map[ecard]) {
-                               expamem_next((*card_map[ecard]) (), NULL);
+                       if (cards[ecard].map) {
+                               expamem_next(cards[ecard].map(), NULL);
                                return;
                        }
                        if (expamem_bank_current && expamem_bank_current != &expamem_bank) {
@@ -599,13 +609,13 @@ static void REGPARAM2 expamem_wput (uaecptr addr, uae_u32 value)
                        }
                        expamem_board_pointer = expamem_z3_pointer;
                }
-               if (card_map[ecard]) {
-                       expamem_next((*card_map[ecard])(), NULL);
+               if (cards[ecard].map) {
+                       expamem_next(cards[ecard].map(), NULL);
                        return;
                }
                break;
        case 0x4c:
-               if (card_map[ecard]) {
+               if (cards[ecard].map) {
                        expamem_next (NULL, NULL);
                        return;
                }
@@ -636,8 +646,8 @@ static void REGPARAM2 expamem_bput (uaecptr addr, uae_u32 value)
                        expamem_hi = value & 0xff;
                        expamem_z2_pointer = (expamem_hi | (expamem_lo >> 4)) << 16; 
                        expamem_board_pointer = expamem_z2_pointer;
-                       if (card_map[ecard]) {
-                               expamem_next((*card_map[ecard]) (), NULL);
+                       if (cards[ecard].map) {
+                               expamem_next(cards[ecard].map(), NULL);
                                return;
                        }
                } else {
@@ -651,7 +661,7 @@ static void REGPARAM2 expamem_bput (uaecptr addr, uae_u32 value)
                break;
 
        case 0x4c:
-               if (card_map[ecard]) {
+               if (cards[ecard].map) {
                        expamem_next(expamem_bank_current, NULL);
                        return;
                }
@@ -1110,8 +1120,8 @@ static addrbank *expamem_init_fastcard(int boardnum)
        }
        for (int i = 0; expansionroms[i].name; i++) {
                const struct expansionromtype *erc = &expansionroms[i];
-               if (erc->zorro == 2 && cfgfile_board_enabled(&currprefs, erc->romtype)) {
-                       struct romconfig *rc = get_device_romconfig(&currprefs, 0, erc->romtype);
+               if (erc->zorro == 2 && cfgfile_board_enabled(&currprefs, erc->romtype, 0)) {
+                       struct romconfig *rc = get_device_romconfig(&currprefs, erc->romtype, 0);
                        if (erc->subtypes) {
                                const struct expansionsubromtype *srt = &erc->subtypes[rc->subtype];
                                if (srt->memory_mid) {
@@ -1612,11 +1622,15 @@ static void allocate_expamem (void)
 #endif /* SAVESTATE */
 }
 
-static uaecptr check_boot_rom (void)
+static uaecptr check_boot_rom (int *boot_rom_type)
 {
        uaecptr b = RTAREA_DEFAULT;
        addrbank *ab;
 
+       *boot_rom_type = 0;
+       if (currprefs.boot_rom == 1)
+               return 0;
+       *boot_rom_type = 1;
        if (currprefs.cs_cdtvcd || currprefs.cs_cdtvscsi || currprefs.uae_hide > 1)
                b = RTAREA_BACKUP;
        if (currprefs.cs_mbdmac == 1 || currprefs.cpuboard_type)
@@ -1651,6 +1665,13 @@ static uaecptr check_boot_rom (void)
                return b;
        if (currprefs.z3chipmem_size)
                return b;
+       if (currprefs.boot_rom >= 3)
+               return b;
+       if (currprefs.boot_rom == 2 && b == 0xf00000) {
+               *boot_rom_type = -1;
+               return b;
+       }
+       *boot_rom_type = 0;
        return 0;
 }
 
@@ -1658,17 +1679,59 @@ uaecptr need_uae_boot_rom (void)
 {
        uaecptr v;
 
-       uae_boot_rom = 0;
-       v = check_boot_rom ();
-       if (v)
-               uae_boot_rom = 1;
+       uae_boot_rom_type = 0;
+       v = check_boot_rom (&uae_boot_rom_type);
        if (!rtarea_base) {
-               uae_boot_rom = 0;
+               uae_boot_rom_type = 0;
                v = 0;
        }
        return v;
 }
 
+static void add_cpu_expansions(int zorro)
+{
+       const struct cpuboardsubtype *cst = &cpuboards[currprefs.cpuboard_type].subtypes[currprefs.cpuboard_subtype];
+       if (cst->init && cst->initzorro == zorro) {
+               int idx;
+               struct boardromconfig *brc = get_device_rom(&currprefs, ROMTYPE_CPUBOARD, 0, &idx);
+               struct romconfig *rc = &brc->roms[idx];
+               cards[cardno].flags = cst->initflag;
+               cards[cardno].name = cst->name;
+               cards[cardno].initrc = cst->init;
+               cards[cardno].rc = rc;
+               cards[cardno++].map = NULL;
+               if (cst->init2) {
+                       cards[cardno].flags = cst->initflag;
+                       cards[cardno].name = cst->name;
+                       cards[cardno].initrc = cst->init2;
+                       cards[cardno++].map = NULL;
+               }
+       }
+}
+
+static void add_expansions(int zorro)
+{
+       for (int i = 0; expansionroms[i].name; i++) {
+               const struct expansionromtype *erc = &expansionroms[i];
+               if (erc->zorro == zorro) {
+                       for (int j = 0; j < MAX_DUPLICATE_EXPANSION_BOARDS; j++) {
+                               struct romconfig *rc = get_device_romconfig(&currprefs, erc->romtype, j);
+                               if (rc) {
+                                       if (zorro == 1) {
+                                               erc->init(rc);
+                                       } else {
+                                               cards[cardno].flags = 0;
+                                               cards[cardno].name = erc->name;
+                                               cards[cardno].initrc = erc->init;
+                                               cards[cardno].rc = rc;
+                                               cards[cardno++].map = NULL;
+                                       }
+                               }
+                       }
+               }
+       }
+}
+
 void expamem_reset (void)
 {
        int do_mount = 1;
@@ -1698,27 +1761,29 @@ void expamem_reset (void)
        }
        if (need_uae_boot_rom () == 0)
                do_mount = 0;
+       if (uae_boot_rom_type <= 0)
+               do_mount = 0;
 
        if (currprefs.cpuboard_type) {
                // This may require first 128k slot.
-               card_flags[cardno] = 1;
-               card_name[cardno] = _T("CPUBoard");
-               card_init[cardno] = cpuboard_autoconfig_init;
-               card_map[cardno++] = NULL;
+               cards[cardno].flags = 1;
+               cards[cardno].name = _T("CPUBoard");
+               cards[cardno].initrc = cpuboard_autoconfig_init;
+               cards[cardno++].map = NULL;
        }
 
        if (currprefs.fastmem_autoconfig) {
                if (fastmem_bank.baseaddr != NULL && (fastmem_bank.allocated <= 262144 || currprefs.chipmem_size <= 2 * 1024 * 1024)) {
-                       card_flags[cardno] = 0;
-                       card_name[cardno] = _T("Z2Fast");
-                       card_init[cardno] = expamem_init_fastcard;
-                       card_map[cardno++] = expamem_map_fastcard;
+                       cards[cardno].flags = 0;
+                       cards[cardno].name = _T("Z2Fast");
+                       cards[cardno].initnum = expamem_init_fastcard;
+                       cards[cardno++].map = expamem_map_fastcard;
                }
                if (fastmem2_bank.baseaddr != NULL && (fastmem2_bank.allocated <= 262144  || currprefs.chipmem_size <= 2 * 1024 * 1024)) {
-                       card_flags[cardno] = 0;
-                       card_name[cardno] = _T("Z2Fast2");
-                       card_init[cardno] = expamem_init_fastcard;
-                       card_map[cardno++] = expamem_map_fastcard2;
+                       cards[cardno].flags = 0;
+                       cards[cardno].name = _T("Z2Fast2");
+                       cards[cardno].initnum = expamem_init_fastcard;
+                       cards[cardno++].map = expamem_map_fastcard2;
                }
        } else {
                if (fastmem_bank.baseaddr) {
@@ -1733,131 +1798,101 @@ void expamem_reset (void)
 
        // immediately after Z2Fast so that they can be emulated as A590/A2091 with fast ram.
 
-       const struct cpuboardsubtype *cst = &cpuboards[currprefs.cpuboard_type].subtypes[currprefs.cpuboard_subtype];
-       if (cst->init && cst->initzorro == 2) {
-               card_flags[cardno] = cst->initflag;
-               card_name[cardno] = cst->name;
-               card_init[cardno] = cst->init;
-               card_map[cardno++] = NULL;
-               if (cst->init2) {
-                       card_flags[cardno] = cst->initflag;
-                       card_name[cardno] = cst->name;
-                       card_init[cardno] = cst->init2;
-                       card_map[cardno++] = NULL;
-               }
-       }
+       add_cpu_expansions(2);
 
-       for (int i = 0; expansionroms[i].name; i++) {
-               const struct expansionromtype *erc = &expansionroms[i];
-               if (erc->zorro == 2 && cfgfile_board_enabled(&currprefs, erc->romtype)) {
-                       card_flags[cardno] = 0;
-                       card_name[cardno] = erc->name;
-                       card_init[cardno] = erc->init;
-                       card_map[cardno++] = NULL;
-               }
-       }
+       add_expansions(2);
 
 #ifdef CDTV
        if (currprefs.cs_cdtvcd && !currprefs.cs_cdtvcr) {
-               card_flags[cardno] = 0;
-               card_name[cardno] = _T("CDTV DMAC");
-               card_init[cardno] = cdtv_init;
-               card_map[cardno++] = NULL;
+               cards[cardno].flags = 0;
+               cards[cardno].name = _T("CDTV DMAC");
+               cards[cardno].initrc = cdtv_init;
+               cards[cardno++].map = NULL;
        }
 #endif
 #ifdef CD32
        if (currprefs.cs_cd32cd && currprefs.fastmem_size == 0 && currprefs.chipmem_size <= 0x200000 && currprefs.cs_cd32fmv) {
-               card_flags[cardno] = 0;
-               card_name[cardno] = _T("CD32MPEG");
-               card_init[cardno] = expamem_init_cd32fmv;
-               card_map[cardno++] = expamem_map_cd32fmv;
+               cards[cardno].flags = 0;
+               cards[cardno].name = _T("CD32MPEG");
+               cards[cardno].initnum = expamem_init_cd32fmv;
+               cards[cardno++].map = expamem_map_cd32fmv;
        }
 #endif
 #ifdef A2065
        if (currprefs.a2065name[0]) {
-               card_flags[cardno] = 0;
-               card_name[cardno] = _T("A2065");
-               card_init[cardno] = a2065_init;
-               card_map[cardno++] = NULL;
+               cards[cardno].flags = 0;
+               cards[cardno].name = _T("A2065");
+               cards[cardno].initnum = a2065_init;
+               cards[cardno++].map = NULL;
        }
 #endif
 #ifdef FILESYS
        if (do_mount) {
-               card_flags[cardno] = 0;
-               card_name[cardno] = _T("UAEFS");
-               card_init[cardno] = expamem_init_filesys;
-               card_map[cardno++] = expamem_map_filesys;
+               cards[cardno].flags = 0;
+               cards[cardno].name = _T("UAEFS");
+               cards[cardno].initnum = expamem_init_filesys;
+               cards[cardno++].map = expamem_map_filesys;
        }
 #endif
 #ifdef CATWEASEL
        if (currprefs.catweasel && catweasel_init ()) {
-               card_flags[cardno] = 0;
-               card_name[cardno] = _T("CWMK2");
-               card_init[cardno] = expamem_init_catweasel;
-               card_map[cardno++] = expamem_map_catweasel;
+               cards[cardno].flags = 0;
+               cards[cardno].name = _T("CWMK2");
+               cards[cardno].initnum = expamem_init_catweasel;
+               cards[cardno++].map = expamem_map_catweasel;
        }
 #endif
 #ifdef PICASSO96
        if (currprefs.rtgmem_type == GFXBOARD_UAE_Z2 && gfxmem_bank.baseaddr != NULL) {
-               card_flags[cardno] = 4;
-               card_name[cardno] = _T("Z2RTG");
-               card_init[cardno] = expamem_init_gfxcard_z2;
-               card_map[cardno++] = expamem_map_gfxcard_z2;
+               cards[cardno].flags = 4;
+               cards[cardno].name = _T("Z2RTG");
+               cards[cardno].initnum = expamem_init_gfxcard_z2;
+               cards[cardno++].map = expamem_map_gfxcard_z2;
        }
 #endif
 #ifdef GFXBOARD
        if (currprefs.rtgmem_type >= GFXBOARD_HARDWARE && !gfxboard_is_z3 (currprefs.rtgmem_type)) {
-               card_flags[cardno] = 4;
-               card_name[cardno] = _T("Gfxboard VRAM Zorro II");
-               card_init[cardno] = gfxboard_init_memory;
-               card_map[cardno++] = NULL;
+               cards[cardno].flags = 4;
+               cards[cardno].name = _T("Gfxboard VRAM Zorro II");
+               cards[cardno++].initnum = gfxboard_init_memory;
                if (gfxboard_num_boards (currprefs.rtgmem_type) == 3) {
-                       card_flags[cardno] = 0;
-                       card_name[cardno] = _T("Gfxboard VRAM Zorro II Extra");
-                       card_init[cardno] = gfxboard_init_memory_p4_z2;
-                       card_map[cardno++] = NULL;
+                       cards[cardno].flags = 0;
+                       cards[cardno].name = _T("Gfxboard VRAM Zorro II Extra");
+                       cards[cardno++].initnum = gfxboard_init_memory_p4_z2;
                }
                if (gfxboard_is_registers (currprefs.rtgmem_type)) {
-                       card_flags[cardno] = 0;
-                       card_name[cardno] = _T ("Gfxboard Registers");
-                       card_init[cardno] = gfxboard_init_registers;
-                       card_map[cardno++] = NULL;
+                       cards[cardno].flags = 0;
+                       cards[cardno].name = _T ("Gfxboard Registers");
+                       cards[cardno++].initnum = gfxboard_init_registers;
                }
        }
 #endif
 #ifdef WITH_TOCCATA
        if (currprefs.sound_toccata) {
-               card_flags[cardno] = 0;
-               card_name[cardno] = _T("Toccata");
-               card_init[cardno] = sndboard_init;
-               card_map[cardno++] = NULL;
+               cards[cardno].flags = 0;
+               cards[cardno].name = _T("Toccata");
+               cards[cardno++].initnum = sndboard_init;
        }
 #endif
 
        /* Z3 boards last */
        if (!currprefs.address_space_24) {
 
-               const struct cpuboardsubtype *cst = &cpuboards[currprefs.cpuboard_type].subtypes[currprefs.cpuboard_subtype];
-               if (cst->init && cst->initzorro == 3) {
-                       card_flags[cardno] = cst->initflag;
-                       card_name[cardno] = cst->name;
-                       card_init[cardno] = cst->init;
-                       card_map[cardno++] = NULL;
-               }
+               add_cpu_expansions(3);
 
                if (z3fastmem_bank.baseaddr != NULL) {
                        z3num = 0;
-                       card_flags[cardno] = 2 | 1;
-                       card_name[cardno] = _T("Z3Fast");
-                       card_init[cardno] = expamem_init_z3fastmem;
-                       card_map[cardno++] = expamem_map_z3fastmem;
+                       cards[cardno].flags = 2 | 1;
+                       cards[cardno].name = _T("Z3Fast");
+                       cards[cardno].initnum = expamem_init_z3fastmem;
+                       cards[cardno++].map = expamem_map_z3fastmem;
                        if (expamem_z3hack(&currprefs))
                                map_banks (&z3fastmem_bank, z3fastmem_bank.start >> 16, currprefs.z3fastmem_size >> 16, z3fastmem_bank.allocated);
                        if (z3fastmem2_bank.baseaddr != NULL) {
-                               card_flags[cardno] = 2 | 1;
-                               card_name[cardno] = _T("Z3Fast2");
-                               card_init[cardno] = expamem_init_z3fastmem2;
-                               card_map[cardno++] = expamem_map_z3fastmem2;
+                               cards[cardno].flags = 2 | 1;
+                               cards[cardno].name = _T("Z3Fast2");
+                               cards[cardno].initnum = expamem_init_z3fastmem2;
+                               cards[cardno++].map = expamem_map_z3fastmem2;
                                if (expamem_z3hack(&currprefs))
                                        map_banks (&z3fastmem2_bank, z3fastmem2_bank.start >> 16, currprefs.z3fastmem2_size >> 16, z3fastmem2_bank.allocated);
                        }
@@ -1866,37 +1901,30 @@ void expamem_reset (void)
                        map_banks (&z3chipmem_bank, z3chipmem_bank.start >> 16, currprefs.z3chipmem_size >> 16, z3chipmem_bank.allocated);
 #ifdef PICASSO96
                if (currprefs.rtgmem_type == GFXBOARD_UAE_Z3 && gfxmem_bank.baseaddr != NULL) {
-                       card_flags[cardno] = 4 | 1;
-                       card_name[cardno] = _T("Z3RTG");
-                       card_init[cardno] = expamem_init_gfxcard_z3;
-                       card_map[cardno++] = expamem_map_gfxcard_z3;
+                       cards[cardno].flags = 4 | 1;
+                       cards[cardno].name = _T("Z3RTG");
+                       cards[cardno].initnum = expamem_init_gfxcard_z3;
+                       cards[cardno++].map = expamem_map_gfxcard_z3;
                }
 #endif
 #ifdef GFXBOARD
                if (currprefs.rtgmem_type >= GFXBOARD_HARDWARE && gfxboard_is_z3 (currprefs.rtgmem_type)) {
-                       card_flags[cardno] = 4 | 1;
-                       card_name[cardno] = _T ("Gfxboard VRAM Zorro III");
-                       card_init[cardno] = gfxboard_init_memory;
-                       card_map[cardno++] = NULL;
-                       card_flags[cardno] = 1;
-                       card_name[cardno] = _T ("Gfxboard Registers");
-                       card_init[cardno] = gfxboard_init_registers;
-                       card_map[cardno++] = NULL;
+                       cards[cardno].flags = 4 | 1;
+                       cards[cardno].name = _T ("Gfxboard VRAM Zorro III");
+                       cards[cardno++].initnum = gfxboard_init_memory;
+                       cards[cardno].flags = 1;
+                       cards[cardno].name = _T ("Gfxboard Registers");
+                       cards[cardno++].initnum = gfxboard_init_registers;
                }
 #endif
 
-               for (int i = 0; expansionroms[i].name; i++) {
-                       const struct expansionromtype *erc = &expansionroms[i];
-                       if (erc->zorro == 3 && cfgfile_board_enabled(&currprefs, erc->romtype)) {
-                               card_flags[cardno] = 0;
-                               card_name[cardno] = erc->name;
-                               card_init[cardno] = erc->init;
-                               card_map[cardno++] = NULL;
-                       }
-               }
+               add_expansions(3);
 
        }
 
+       // zorro == 1: non-autoconfig/hardwired
+       add_expansions(1);
+
        expamem_z3_pointer = 0;
        expamem_z3_sum = 0;
        if (cardno == 0 || savestate_state)
@@ -2100,7 +2128,7 @@ uae_u8 *restore_expansion (uae_u8 *src)
 
 #endif /* SAVESTATE */
 
-int add_cpuboard_unit(int unit, struct uaedev_config_info *uci);
+void add_cpuboard_unit(int unit, struct uaedev_config_info *uci, struct romconfig *rc);
 
 #if 0
 static const struct expansionsubromtype a2090_sub[] = {
@@ -2202,105 +2230,144 @@ static const struct expansionsubromtype supra_sub[] = {
 
 const struct expansionromtype expansionroms[] = {
        {
-               _T("cpuboard"), _T("Accelerator"),
-               NULL, add_cpuboard_unit, ROMTYPE_CPUBOARD, 0, 0, 0,
+               _T("cpuboard"), _T("Accelerator"), _T("Accelerator"),
+               NULL, add_cpuboard_unit, ROMTYPE_CPUBOARD, 0, 0, 0, true,
                NULL, 0,
                false, EXPANSIONTYPE_SCSI | EXPANSIONTYPE_IDE
        },
        {
-               _T("cpuboard_ext"), _T("Blizzard SCSI Kit IV"),
-               NULL, NULL, ROMTYPE_CPUBOARDEXT, ROMTYPE_CPUBOARD, 0, 0,
+               _T("cpuboard_ext"), _T("SCSI Kit IV"), _T("Blizzard"),
+               NULL, NULL, ROMTYPE_CPUBOARDEXT, ROMTYPE_CPUBOARD, 0, 0, true,
                NULL, 0,
                false, EXPANSIONTYPE_SCSI
        },
        {
-               _T("a2090a"), _T("A2090a"),
-               a2090_init, a2090_add_scsi_unit, ROMTYPE_A2090 | ROMTYPE_NONE, 0, 0, 2,
+               _T("a2090a"), _T("A2090a"), _T("Commodore"),
+               a2090_init, a2090_add_scsi_unit, ROMTYPE_A2090 | ROMTYPE_NONE, 0, 0, 2, false,
                NULL, 0,
                true, EXPANSIONTYPE_SCSI
        },
        {
-               _T("a2091"), _T("A590/A2091"),
-               a2091_init, a2091_add_scsi_unit, ROMTYPE_A2091 | ROMTYPE_NONE, 0, 0, 2,
+               _T("a2091"), _T("A590/A2091"), _T("Commodore"),
+               a2091_init, a2091_add_scsi_unit, ROMTYPE_A2091 | ROMTYPE_NONE, 0, 0, 2, false,
                a2091_sub, 1,
                true, EXPANSIONTYPE_SCSI
        },
        {
-               _T("a4091"), _T("A4091"),
-               ncr710_a4091_autoconfig_init, a4091_add_scsi_unit, ROMTYPE_A4091, 0, 0, 3,
+               _T("a4091"), _T("A4091"), _T("Commodore"),
+               ncr710_a4091_autoconfig_init, a4091_add_scsi_unit, ROMTYPE_A4091, 0, 0, 3, false,
                NULL, 0,
                false, EXPANSIONTYPE_SCSI
        },
        {
-               _T("fastlane"), _T("Fastlane"),
-               ncr_fastlane_autoconfig_init, fastlane_add_scsi_unit, ROMTYPE_FASTLANE, 0, 0, 3,
+               _T("fastlane"), _T("Fastlane"), _T("Phase 5"),
+               ncr_fastlane_autoconfig_init, fastlane_add_scsi_unit, ROMTYPE_FASTLANE, 0, 0, 3, false,
                NULL, 0,
                false, EXPANSIONTYPE_SCSI
        },
        {
-               _T("oktagon2008"), _T("Oktagon 2008"),
-               ncr_oktagon_autoconfig_init, oktagon_add_scsi_unit, ROMTYPE_OKTAGON, 0, 0, 2,
+               _T("oktagon2008"), _T("Oktagon 2008"), _T("BSC/Alfa Data"),
+               ncr_oktagon_autoconfig_init, oktagon_add_scsi_unit, ROMTYPE_OKTAGON, 0, 0, 2, false,
                NULL, 0,
                false, EXPANSIONTYPE_SCSI
        },
        {
-               _T("gvp1"), _T("GVP Series I"),
-               gvp_init_s1, gvp_add_scsi_unit, ROMTYPE_GVPS1 | ROMTYPE_NONE, ROMTYPE_GVPS12, 0, 2,
+               _T("gvp1"), _T("Series I"), _T("GVP"),
+               gvp_init_s1, gvp_add_scsi_unit, ROMTYPE_GVPS1 | ROMTYPE_NONE, ROMTYPE_GVPS12, 0, 2, false,
                gvp1_sub, 1,
                true, EXPANSIONTYPE_SCSI
        },
        {
-               _T("gvp"), _T("GVP Series II"),
-               gvp_init_s2, gvp_add_scsi_unit, ROMTYPE_GVPS2 | ROMTYPE_NONE, ROMTYPE_GVPS12, 0, 2,
+               _T("gvp"), _T("Series II"), _T("GVP"),
+               gvp_init_s2, gvp_add_scsi_unit, ROMTYPE_GVPS2 | ROMTYPE_NONE, ROMTYPE_GVPS12, 0, 2, false,
                NULL, 0,
                true, EXPANSIONTYPE_SCSI,
                2017, 10, 0
        },
        {
-               _T("amax"), _T("AMAX ROM dongle"),
-               NULL, 0,
-               NULL, NULL, ROMTYPE_AMAX | ROMTYPE_NONE, 0, 0, 0
-       },
-       {
-               _T("alfapower"), _T("AlfaPower/AT-Bus 2008"),
-               alf_init, alf_add_ide_unit, ROMTYPE_ALFA, 0, 0, 2,
+               _T("alfapower"), _T("AlfaPower/AT-Bus 2008"), _T("BSC/Alfa Data"),
+               alf_init, alf_add_ide_unit, ROMTYPE_ALFA, 0, 0, 2, false,
                NULL, 0,
                false, EXPANSIONTYPE_IDE,
                2092, 8, 0
        },
        {
-               _T("alfapowerplus"), _T("AlfaPower Plus"),
-               alf_init, alf_add_ide_unit, ROMTYPE_ALFAPLUS, 0, 0, 2,
+               _T("alfapowerplus"), _T("AlfaPower Plus"), _T("BSC/Alfa Data"),
+               alf_init, alf_add_ide_unit, ROMTYPE_ALFAPLUS, 0, 0, 2, false,
                NULL, 0,
                false, EXPANSIONTYPE_IDE,
                2092, 8, 0
        },
        {
-               _T("apollo"), _T("Apollo"),
-               apollo_init, apollo_add_scsi_unit, ROMTYPE_APOLLO, 0, 0, 2,
+               _T("apollo"), _T("Apollo"), _T("ACT"),
+               apollo_init_hd, apollo_add_scsi_unit, ROMTYPE_APOLLO, 0, 0, 2, false,
                NULL, 0,
                false, EXPANSIONTYPE_SCSI | EXPANSIONTYPE_IDE,
                8738, 0, 0
        },
        {
-               _T("masoboshi"), _T("Masoboshi"),
-               masoboshi_init, masoboshi_add_idescsi_unit, ROMTYPE_MASOBOSHI | ROMTYPE_NONE, 0, 0, 2,
+               _T("masoboshi"), _T("MasterCard"), _T("Masoboshi"),
+               masoboshi_init, masoboshi_add_idescsi_unit, ROMTYPE_MASOBOSHI | ROMTYPE_NONE, 0, 0, 2, false,
                masoboshi_sub, 0,
                true, EXPANSIONTYPE_SCSI | EXPANSIONTYPE_IDE
        },
        {
-               _T("supradrive"), _T("SupraDrive"),
-               supra_init, supra_add_scsi_unit, ROMTYPE_SUPRA | ROMTYPE_NONE, 0, 0, 2,
+               _T("supradrive"), _T("SupraDrive"), _T("Supra"),
+               supra_init, supra_add_scsi_unit, ROMTYPE_SUPRA | ROMTYPE_NONE, 0, 0, 2, false,
                supra_sub, 0,
                true, EXPANSIONTYPE_SCSI
        },
        {
-               _T("golem"), _T("Kupke Golem"),
-               golem_init, golem_add_scsi_unit, ROMTYPE_GOLEM, 0, 0, 2,
+               _T("golem"), _T("Golem"), _T("Kupke"),
+               golem_init, golem_add_scsi_unit, ROMTYPE_GOLEM, 0, 0, 2, false,
                NULL, 0,
                true, EXPANSIONTYPE_SCSI,
                2079, 3, 0
        },
+       {
+               _T("adide"), _T("AdIDE"), _T("ICD"),
+               adide_init, adide_add_ide_unit, ROMTYPE_ADIDE, 0, 0, 2, false,
+               NULL, 0,
+               true, EXPANSIONTYPE_IDE
+       },
+       {
+               _T("mtecat"), _T("AT 500"), _T("M-Tec"),
+               mtec_init, mtec_add_ide_unit, ROMTYPE_MTEC, 0, 0, 2, false,
+               NULL, 0,
+               true, EXPANSIONTYPE_IDE
+       },
+       {
+               _T("protar"), _T("A500 HD"), _T("Protar"),
+               protar_init, protar_add_ide_unit, ROMTYPE_PROTAR, 0, 0, 2, false,
+               NULL, 0,
+               true, EXPANSIONTYPE_SCSI,
+               4149, 51, 0
+       },
+       {
+               _T("stardrive"), _T("StarDrive"), _T("Microbotics"),
+               stardrive_init, stardrive_add_scsi_unit, ROMTYPE_STARDRIVE | ROMTYPE_NONE, 0, 0, 2, true,
+               NULL, 0,
+               false, EXPANSIONTYPE_SCSI,
+               1010, 0, 0,
+               { 0xc1, 2, 0x00, 0x00, 0x03, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+
+       },
+       {
+               _T("kommos"), _T("A500/A2000 SCSI"), _T("Jürgen Kommos"),
+               kommos_init, kommos_add_scsi_unit, ROMTYPE_KOMMOS, 0, 0, 1, true,
+               NULL, 0,
+               false, EXPANSIONTYPE_SCSI,
+       },
+       {
+               _T("vector"), _T("Vector Falcon 8000"), _T("HK-Computer"),
+               vector_init, vector_add_scsi_unit, ROMTYPE_VECTOR, 0, 0, 2, false,
+               NULL, 0,
+               false, EXPANSIONTYPE_SCSI,
+       },
+       {
+               _T("amax"), _T("AMAX ROM dongle"), _T("ReadySoft"),
+               NULL, 0, NULL, NULL, ROMTYPE_AMAX | ROMTYPE_NONE, 0, 0, 0, false
+       },
        {
                NULL
        }
@@ -2536,47 +2603,75 @@ static const struct cpuboardsubtype apollo_sub[] = {
                NULL
        }
 };
+static const struct cpuboardsubtype kupkeboard_sub[] = {
+       {
+               _T("Golem 030"),
+               _T("golem030"),
+               ROMTYPE_CB_GOLEM030, 0,
+               NULL, 0,
+               BOARD_MEMORY_25BITMEM,
+               16 * 1024 * 1024
+       },
+       {
+               NULL
+       }
+};
+
 static const struct cpuboardsubtype dummy_sub[] = {
        { NULL }
 };
 
 const struct cpuboardtype cpuboards[] = {
        {
+               -1,
                _T("-"),
                dummy_sub, 0
        },
        {
+               BOARD_BLIZZARD,
                _T("Phase 5 - Blizzard"),
                blizzardboard_sub, 0
        },
        {
+               BOARD_CYBERSTORM,
                _T("Phase 5 - CyberStorm"),
                cyberstormboard_sub, 0
        },
        {
+               BOARD_MACROSYSTEM,
                _T("MacroSystem"),
                warpengine_sub, 0
        },
        {
+               BOARD_COMMODORE,
                _T("Commodore"),
                commodore_sub, 0
        },
        {
+               BOARD_DKB,
                _T("DKB"),
                dbk_sub, 0
        },
        {
+               BOARD_RCS,
                _T("RCS Management"),
                fusionforty_sub, 0
        },
        {
+               BOARD_ACT,
                _T("ACT"),
                apollo_sub, 0
        },
        {
+               BOARD_GVP,
                _T("GVP"),
                gvpboard_sub, 0
        },
+       {
+               BOARD_KUPKE,
+               _T("Kupke"),
+               kupkeboard_sub, 0
+       },
        {
                NULL
        }
index 086a311385da02d00eac7d5842650d364f8ba48a..c97d71f4902f24a18be9cdc140c524d7bcb8b446 100644 (file)
@@ -793,16 +793,35 @@ static void allocuci (struct uae_prefs *p, int nr, int idx)
        allocuci (p, nr, idx, -1);
 }
 
-int add_cpuboard_unit(int unit, struct uaedev_config_info *uci)
+static int cpuboard_hd;
+
+void add_cpuboard_unit(int unit, struct uaedev_config_info *uci, struct romconfig *rc)
 {
-       bool added = false;
        int flags = (uci->controller_type >= HD_CONTROLLER_TYPE_IDE_FIRST && uci->controller_type <= HD_CONTROLLER_TYPE_IDE_LAST) ? EXPANSIONTYPE_IDE : EXPANSIONTYPE_SCSI;
        const struct cpuboardtype *cbt = &cpuboards[currprefs.cpuboard_type];
+       cpuboard_hd = 0;
        if (cbt->subtypes) {
-               if (cbt->subtypes[currprefs.cpuboard_subtype].add && (cbt->subtypes[currprefs.cpuboard_subtype].deviceflags & flags))
-                       added = cbt->subtypes[currprefs.cpuboard_subtype].add(unit, uci);
+               if (cbt->subtypes[currprefs.cpuboard_subtype].add && (cbt->subtypes[currprefs.cpuboard_subtype].deviceflags & flags)) {
+                       cbt->subtypes[currprefs.cpuboard_subtype].add(unit, uci, rc);
+                       cpuboard_hd = 1;
+               }
+       }
+}
+
+static void add_cpuboard_unit_init(void)
+{
+       if (currprefs.cpuboard_type) {
+               struct romconfig *rc = get_device_romconfig(&currprefs, ROMTYPE_CPUBOARD, 0);
+               if (rc) {
+                       const struct cpuboardtype *cbt = &cpuboards[currprefs.cpuboard_type];
+                       if (cbt->subtypes) {
+                               if (cbt->subtypes[currprefs.cpuboard_subtype].add) {
+                                       struct uaedev_config_info ci = { 0 };
+                                       cbt->subtypes[currprefs.cpuboard_subtype].add(-1, &ci, rc);
+                               }
+                       }
+               }
        }
-       return added;
 }
 
 static bool add_ide_unit(int type, int unit, struct uaedev_config_info *uci)
@@ -817,10 +836,14 @@ static bool add_ide_unit(int type, int unit, struct uaedev_config_info *uci)
                for (int i = 0; expansionroms[i].name; i++) {
                        if (i == type - HD_CONTROLLER_TYPE_IDE_EXPANSION_FIRST) {
                                const struct expansionromtype *ert = &expansionroms[i];
-                               if ((ert->deviceflags & 2) && cfgfile_board_enabled(&currprefs, ert->romtype)) {
-                                       if (ert->add)
-                                               ert->add(unit, uci);
-                                       added = true;
+                               if ((ert->deviceflags & 2) && cfgfile_board_enabled(&currprefs, ert->romtype, uci->controller_type_unit)) {
+                                       cpuboard_hd = 1;
+                                       if (ert->add) {
+                                               struct romconfig *rc = get_device_romconfig(&currprefs, ert->romtype, uci->controller_type_unit);
+                                               ert->add(unit, uci, rc);
+                                       }
+                                       if (cpuboard_hd)
+                                               added = true;
                                }
                        }
                }
@@ -834,21 +857,21 @@ static bool add_scsi_unit(int type, int unit, struct uaedev_config_info *uci)
        if (type == HD_CONTROLLER_TYPE_SCSI_A3000) {
 #ifdef A2091
                if (currprefs.cs_mbdmac == 1) {
-                       a3000_add_scsi_unit (unit, uci);
+                       a3000_add_scsi_unit (unit, uci, NULL);
                        added = true;
                }
 #endif
        } else if (type == HD_CONTROLLER_TYPE_SCSI_A4000T) {
 #ifdef NCR
                if (currprefs.cs_mbdmac == 2) {
-                       a4000t_add_scsi_unit (unit, uci);
+                       a4000t_add_scsi_unit (unit, uci, NULL);
                        added = true;
                }
 #endif
        } else if (type == HD_CONTROLLER_TYPE_SCSI_CDTV) {
 #ifdef CDTV
                if (currprefs.cs_cdtvscsi) {
-                       cdtv_add_scsi_hd_unit (unit, uci);
+                       cdtv_add_scsi_unit (unit, uci, NULL);
                        added = true;
                }
 #endif
@@ -856,12 +879,14 @@ static bool add_scsi_unit(int type, int unit, struct uaedev_config_info *uci)
                for (int i = 0; expansionroms[i].name; i++) {
                        if (i == type - HD_CONTROLLER_TYPE_SCSI_EXPANSION_FIRST) {
                                const struct expansionromtype *ert = &expansionroms[i];
-                               if ((ert->deviceflags & 1) && cfgfile_board_enabled(&currprefs, ert->romtype)) {
+                               if ((ert->deviceflags & 1) && cfgfile_board_enabled(&currprefs, ert->romtype, uci->controller_type_unit)) {
+                                       cpuboard_hd = 1;
                                        if (ert->add) {
-                                               added = ert->add(unit, uci);
-                                       } else {
-                                               added = true;
+                                               struct romconfig *rc = get_device_romconfig(&currprefs, ert->romtype, uci->controller_type_unit);
+                                               ert->add(unit, uci, rc);
                                        }
+                                       if (cpuboard_hd)
+                                               added = true;
                                }
                        }
                }
@@ -926,6 +951,22 @@ static void initialize_mountinfo (void)
                }
        }
 
+       // init all controllers first
+       add_cpuboard_unit_init();
+       for (int i = 0; expansionroms[i].name; i++) {
+               const struct expansionromtype *ert = &expansionroms[i];
+               for (int j = 0; j < MAX_DUPLICATE_EXPANSION_BOARDS; j++) {
+                       struct romconfig *rc = get_device_romconfig(&currprefs, ert->romtype, j);
+                       if ((ert->deviceflags & 3) && rc) {
+                               if (ert->add) {
+                                       struct uaedev_config_info ci = { 0 };
+                                       ci.controller_type_unit = j;
+                                       ert->add(-1, &ci, rc);
+                               }
+                       }
+               }
+       }
+
        for (nr = 0; nr < currprefs.mountitems; nr++) {
                struct uaedev_config_info *uci = &currprefs.mountconfig[nr].ci;
                int type = uci->controller_type;
@@ -7814,7 +7855,7 @@ void filesys_vsync (void)
 {
        Unit *u;
 
-       if (!uae_boot_rom)
+       if (uae_boot_rom_type <= 0)
                return;
        if (heartbeat == get_long (rtarea_base + RTAREA_HEARTBEAT)) {
                if (heartbeat_count > 0)
@@ -7931,6 +7972,9 @@ void filesys_install_code (void)
 {
        uae_u32 a, b, items;
 
+       if (uae_boot_rom_type <= 0)
+               return;
+
        bootrom_header = 3 * 4;
        align(4);
        a = here ();
index 1667199125fb45a83276f8685a4d31c5c7ba8edd..60c8a9a885ad9527693d90dec7667aedf6a447da 100644 (file)
--- a/gayle.cpp
+++ b/gayle.cpp
@@ -1332,7 +1332,7 @@ static int initpcmcia (const TCHAR *path, int readonly, int type, int reset, str
        } else if (type == PCMCIA_IDE) {
 
                if (reset && path) {    
-                       add_ide_unit (idedrive, TOTAL_IDE * 2, PCMCIA_IDE_ID * 2, uci);
+                       add_ide_unit (idedrive, TOTAL_IDE * 2, PCMCIA_IDE_ID * 2, uci, NULL);
                }
                ide_initialize(idedrive, PCMCIA_IDE_ID);
 
@@ -1608,7 +1608,7 @@ int gayle_add_ide_unit (int ch, struct uaedev_config_info *ci)
 
        if (ch >= 2 * 2)
                return -1;
-       ide = add_ide_unit (idedrive, TOTAL_IDE * 2, ch, ci);
+       ide = add_ide_unit (idedrive, TOTAL_IDE * 2, ch, ci, NULL);
        if (ide == NULL)
                return 0;
        //dumphdf (&ide->hdhfd.hfd);
@@ -1682,8 +1682,8 @@ void gayle_reset (int hardreset)
 #ifdef NCR
        if (currprefs.cs_mbdmac == 2) {
                _tcscat (bankname, _T(" + NCR53C710 SCSI"));
-               ncr710_init();
-               ncr710_reset();
+               ncr_init();
+               ncr_reset();
        }
 #endif
        gayle_bank.name = bankname;
index 4ecb52852891bba362f0a24a53e07c8892267704..b9705af94b68d7818711e753bdbac2e60815f513 100644 (file)
@@ -27,6 +27,7 @@
 #include "gayle.h"
 #include "execio.h"
 #include "zfile.h"
+#include "ide.h"
 
 #ifdef WITH_CHD
 #include "archivers/chd/chdtypes.h"
@@ -978,48 +979,7 @@ static void adide_decode (void *v, int len)
        for (i = 0; i < len; i += 2) {
                uae_u8 *b =  buffer + i;
                uae_u16 w = (b[0] << 8) | (b[1] << 0);
-               uae_u16 o = 0;
-
-               if (w & 0x8000)
-                       o |= 0x0001;
-               if (w & 0x0001)
-                       o |= 0x0002;
-
-               if (w & 0x4000)
-                       o |= 0x0004;
-               if (w & 0x0002)
-                       o |= 0x0008;
-
-               if (w & 0x2000)
-                       o |= 0x0010;
-               if (w & 0x0004)
-                       o |= 0x0020;
-
-               if (w & 0x1000)
-                       o |= 0x0040;
-               if (w & 0x0008)
-                       o |= 0x0080;
-
-               if (w & 0x0800)
-                       o |= 0x0100;
-               if (w & 0x0010)
-                       o |= 0x0200;
-
-               if (w & 0x0400)
-                       o |= 0x0400;
-               if (w & 0x0020)
-                       o |= 0x0800;
-
-               if (w & 0x0200)
-                       o |= 0x1000;
-               if (w & 0x0040)
-                       o |= 0x2000;
-
-               if (w & 0x0100)
-                       o |= 0x4000;
-               if (w & 0x0080)
-                       o |= 0x8000;
-
+               uae_u16 o = adide_decode_word(w);
                b[0] = o >> 8;
                b[1] = o >> 0;
        }
@@ -1031,48 +991,7 @@ static void adide_encode (void *v, int len)
        for (i = 0; i < len; i += 2) {
                uae_u8 *b =  buffer + i;
                uae_u16 w = (b[0] << 8) | (b[1] << 0);
-               uae_u16 o = 0;
-
-               if (w & 0x0001)
-                       o |= 0x8000;
-               if (w & 0x0002)
-                       o |= 0x0001;
-
-               if (w & 0x0004)
-                       o |= 0x4000;
-               if (w & 0x0008)
-                       o |= 0x0002;
-
-               if (w & 0x0010)
-                       o |= 0x2000;
-               if (w & 0x0020)
-                       o |= 0x0004;
-
-               if (w & 0x0040)
-                       o |= 0x1000;
-               if (w & 0x0080)
-                       o |= 0x0008;
-
-               if (w & 0x0100)
-                       o |= 0x0800;
-               if (w & 0x0200)
-                       o |= 0x0010;
-
-               if (w & 0x0400)
-                       o |= 0x0400;
-               if (w & 0x0800)
-                       o |= 0x0020;
-
-               if (w & 0x1000)
-                       o |= 0x0200;
-               if (w & 0x2000)
-                       o |= 0x0040;
-
-               if (w & 0x4000)
-                       o |= 0x0100;
-               if (w & 0x8000)
-                       o |= 0x0080;
-
+               uae_u16 o = adide_encode_word(w);
                b[0] = o >> 8;
                b[1] = o >> 0;
        }
@@ -1303,6 +1222,11 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua
                        goto nodisk;
                scsi_len = 0;
                break;
+       case 0x01: /* REZERO UNIT */
+               if (nodisk (hfd))
+                       goto nodisk;
+               scsi_len = 0;
+               break;
        case 0x04: /* FORMAT UNIT */
                // do nothing
                if (nodisk (hfd))
diff --git a/ide.cpp b/ide.cpp
index 3ba63645b38da76fed0732c89297292d419c3e03..eec552494a7c8cf15e54ce845953e148cb5985a6 100644 (file)
--- a/ide.cpp
+++ b/ide.cpp
@@ -6,7 +6,7 @@
 * (c) 2006 - 2015 Toni Wilen
 */
 
-#define IDE_LOG 0
+#define IDE_LOG 2
 
 #include "sysconfig.h"
 #include "sysdeps.h"
 #define ATAPI_MAX_TRANSFER 32768
 #define MAX_IDE_MULTIPLE_SECTORS 64
 
+
+uae_u16 adide_decode_word(uae_u16 w)
+{
+       uae_u16 o = 0;
+
+       if (w & 0x8000)
+               o |= 0x0001;
+       if (w & 0x0001)
+               o |= 0x0002;
+
+       if (w & 0x4000)
+               o |= 0x0004;
+       if (w & 0x0002)
+               o |= 0x0008;
+
+       if (w & 0x2000)
+               o |= 0x0010;
+       if (w & 0x0004)
+               o |= 0x0020;
+
+       if (w & 0x1000)
+               o |= 0x0040;
+       if (w & 0x0008)
+               o |= 0x0080;
+
+       if (w & 0x0800)
+               o |= 0x0100;
+       if (w & 0x0010)
+               o |= 0x0200;
+
+       if (w & 0x0400)
+               o |= 0x0400;
+       if (w & 0x0020)
+               o |= 0x0800;
+
+       if (w & 0x0200)
+               o |= 0x1000;
+       if (w & 0x0040)
+               o |= 0x2000;
+
+       if (w & 0x0100)
+               o |= 0x4000;
+       if (w & 0x0080)
+               o |= 0x8000;
+
+       return o;
+}
+
+uae_u16 adide_encode_word(uae_u16 w)
+{
+       uae_u16 o = 0;
+
+       if (w & 0x0001)
+               o |= 0x8000;
+       if (w & 0x0002)
+               o |= 0x0001;
+
+       if (w & 0x0004)
+               o |= 0x4000;
+       if (w & 0x0008)
+               o |= 0x0002;
+
+       if (w & 0x0010)
+               o |= 0x2000;
+       if (w & 0x0020)
+               o |= 0x0004;
+
+       if (w & 0x0040)
+               o |= 0x1000;
+       if (w & 0x0080)
+               o |= 0x0008;
+
+       if (w & 0x0100)
+               o |= 0x0800;
+       if (w & 0x0200)
+               o |= 0x0010;
+
+       if (w & 0x0400)
+               o |= 0x0400;
+       if (w & 0x0800)
+               o |= 0x0020;
+
+       if (w & 0x1000)
+               o |= 0x0200;
+       if (w & 0x2000)
+               o |= 0x0040;
+
+       if (w & 0x4000)
+               o |= 0x0100;
+       if (w & 0x8000)
+               o |= 0x0080;
+
+       return o;
+}
+
+
+
 static void ide_grow_buffer(struct ide_hdf *ide, int newsize)
 {
        if (ide->secbuf_size >= newsize)
@@ -64,30 +161,29 @@ static void ide_grow_buffer(struct ide_hdf *ide, int newsize)
 
 static void pw (struct ide_hdf *ide, int offset, uae_u16 w)
 {
-       if (ide->byteswap) {
-               ide->secbuf[offset * 2 + 1] = (uae_u8)w;
-               ide->secbuf[offset * 2 + 0] = w >> 8;
-       } else {
-               ide->secbuf[offset * 2 + 0] = (uae_u8)w;
-               ide->secbuf[offset * 2 + 1] = w >> 8;
-       }
+       if (ide->adide)
+               w = adide_decode_word(w);
+       if (ide->byteswap)
+               w = (w >> 8) | (w << 8);
+       ide->secbuf[offset * 2 + 0] = (uae_u8)w;
+       ide->secbuf[offset * 2 + 1] = w >> 8;
 }
 
 static void ps (struct ide_hdf *ide, int offset, const TCHAR *src, int max)
 {
-       int i, len, swap;
+       int i, len;
        char *s;
 
-       swap = ide->byteswap ? 0 : 1;
-       offset *= 2;
        s = ua (src);
        len = strlen (s);
-       for (i = 0; i < max; i++) {
-               char c = ' ';
+       for (i = 0; i < max; i += 2) {
+               char c1 = ' ';
                if (i < len)
-                       c = s[i];
-               ide->secbuf[offset ^ swap] = c;
-               offset++;
+                       c1 = s[i];
+               char c2 = ' ';
+               if (i + 1 < len)
+                       c2 = s[i + 1];
+               pw(ide, offset + i / 2, (c2 << 8) | c1);
        }
        xfree (s);
 }
@@ -130,7 +226,7 @@ static bool ide_interrupt_do (struct ide_hdf *ide)
 
 bool ide_drq_check(struct ide_hdf *idep)
 {
-       for (int i = 0; i < 2; i++) {
+       for (int i = 0; idep && i < 2; i++) {
                struct ide_hdf *ide = i == 0 ? idep : idep->pair;
                if (ide) {
                        if (ide->regs.ide_status & IDE_STATUS_DRQ)
@@ -142,7 +238,7 @@ bool ide_drq_check(struct ide_hdf *idep)
 
 bool ide_irq_check(struct ide_hdf *idep)
 {
-       for (int i = 0; i < 2; i++) {
+       for (int i = 0; idep && i < 2; i++) {
                struct ide_hdf *ide = i == 0 ? idep : idep->pair;
                if (ide->irq)
                        return true;
@@ -153,7 +249,7 @@ bool ide_irq_check(struct ide_hdf *idep)
 bool ide_interrupt_hsync(struct ide_hdf *idep)
 {
        bool irq = false;
-       for (int i = 0; i < 2; i++) {
+       for (int i = 0; idep && i < 2; i++) {
                struct ide_hdf *ide = i == 0 ? idep : idep->pair;
                if (ide) {
                        if (ide->irq_delay > 0) {
@@ -1146,11 +1242,13 @@ void remove_ide_unit(struct ide_hdf **idetable, int ch)
        }
 }
 
-struct ide_hdf *add_ide_unit (struct ide_hdf **idetable, int max, int ch, struct uaedev_config_info *ci)
+struct ide_hdf *add_ide_unit (struct ide_hdf **idetable, int max, int ch, struct uaedev_config_info *ci, struct romconfig *rc)
 {
        struct ide_hdf *ide;
 
        alloc_ide_mem(idetable, max, NULL);
+       if (ch < 0)
+               return NULL;
        ide = idetable[ch];
        if (ci)
                memcpy (&ide->hdhfd.hfd.ci, ci, sizeof (struct uaedev_config_info));
index 1b5354915b713b969f25c22cb37d985ec016aac9..973d1ba381c47bad5a6e25028076646935847e4d 100644 (file)
@@ -26,6 +26,7 @@
 #include "cpuboard.h"
 #include "scsi.h"
 #include "ncr9x_scsi.h"
+#include "autoconf.h"
 
 #define DEBUG_IDE 0
 #define DEBUG_IDE_GVP 0
 
 #define GVP_IDE 0 // GVP A3001
 #define ALF_IDE 1
-#define APOLLO_IDE 3
-#define MASOBOSHI_IDE 5
-#define TOTAL_IDE 7
+#define APOLLO_IDE (ALF_IDE + MAX_DUPLICATE_EXPANSION_BOARDS)
+#define MASOBOSHI_IDE (APOLLO_IDE + MAX_DUPLICATE_EXPANSION_BOARDS)
+#define ADIDE_IDE (MASOBOSHI_IDE + MAX_DUPLICATE_EXPANSION_BOARDS)
+#define MTEC_IDE (ADIDE_IDE + MAX_DUPLICATE_EXPANSION_BOARDS)
+#define PROTAR_IDE (MTEC_IDE + MAX_DUPLICATE_EXPANSION_BOARDS)
+#define TOTAL_IDE (PROTAR_IDE + MAX_DUPLICATE_EXPANSION_BOARDS)
 
 #define ALF_ROM_OFFSET 0x0100
 #define GVP_IDE_ROM_OFFSET 0x8000
 #define APOLLO_ROM_OFFSET 0x8000
+#define ADIDE_ROM_OFFSET 0x8000
 #define MASOBOSHI_ROM_OFFSET 0x0080
 #define MASOBOSHI_ROM_OFFSET_END 0xf000
 #define MASOBOSHI_SCSI_OFFSET 0xf800
@@ -75,26 +80,72 @@ IDE
 
 */
 
-static struct ide_board gvp_ide_rom_board, gvp_ide_controller_board;
-static struct ide_board alf_board[2];
-static struct ide_board apollo_board[2];
-static struct ide_board masoboshi_board[2];
+#define MAX_IDE_UNITS 10
+
+static struct ide_board *gvp_ide_rom_board, *gvp_ide_controller_board;
+static struct ide_board *alf_board[MAX_DUPLICATE_EXPANSION_BOARDS];
+static struct ide_board *apollo_board[MAX_DUPLICATE_EXPANSION_BOARDS];
+static struct ide_board *masoboshi_board[MAX_DUPLICATE_EXPANSION_BOARDS];
+static struct ide_board *adide_board[MAX_DUPLICATE_EXPANSION_BOARDS];
+static struct ide_board *mtec_board[MAX_DUPLICATE_EXPANSION_BOARDS];
+static struct ide_board *protar_board[MAX_DUPLICATE_EXPANSION_BOARDS];
+
 static struct ide_hdf *idecontroller_drive[TOTAL_IDE * 2];
 static struct ide_thread_state idecontroller_its;
 
-static struct ide_board *ide_boards[] =
+static struct ide_board *ide_boards[MAX_IDE_UNITS + 1];
+
+static struct ide_board *allocide(struct ide_board **idep, struct romconfig *rc, int ch)
 {
-       &gvp_ide_rom_board,
-       &alf_board[0],
-       &alf_board[1],
-       &apollo_board[0],
-       &apollo_board[1],
-       &masoboshi_board[0],
-       &masoboshi_board[1],
-       NULL
-};
+       struct ide_board *ide;
+
+       if (ch < 0) {
+               if (*idep) {
+                       remove_ide_unit(&(*idep)->ide, 0);
+                       xfree(*idep);
+                       *idep = NULL;
+               }
+               ide = xcalloc(struct ide_board, 1);
+               for (int i = 0; i < MAX_IDE_UNITS; i++) {
+                       if (ide_boards[i] == NULL) {
+                               ide_boards[i] = ide;
+                               rc->unitdata = ide;
+                               ide->rc = rc;
+                               if (idep)
+                                       *idep = ide;
+                               return ide;
+                       }
+               }
+       }
+       return *idep;
+}
 
-static void init_ide(struct ide_board *board, int ide_num, bool byteswap)
+static struct ide_board *getide(struct romconfig *rc)
+{
+       for (int i = 0; i < MAX_IDE_UNITS; i++) {
+               if (ide_boards[i]) {
+                       struct ide_board *ide = ide_boards[i];
+                       if (ide->rc == rc) {
+                               ide->rc = NULL;
+                               return ide;
+                       }
+               }
+       }
+       return NULL;
+}
+
+static struct ide_board *getideboard(uaecptr addr)
+{
+       for (int i = 0; ide_boards[i]; i++) {
+               if (!ide_boards[i]->baseaddress && !ide_boards[i]->configured)
+                       return ide_boards[i];
+               if ((addr & ~ide_boards[i]->mask) == ide_boards[i]->baseaddress)
+                       return ide_boards[i];
+       }
+       return NULL;
+}
+
+static void init_ide(struct ide_board *board, int ide_num, bool byteswap, bool adide)
 {
        struct ide_hdf **idetable = &idecontroller_drive[ide_num * 2];
        alloc_ide_mem (idetable, 2, &idecontroller_its);
@@ -103,18 +154,33 @@ static void init_ide(struct ide_board *board, int ide_num, bool byteswap)
        idetable[1]->board = board;
        idetable[0]->byteswap = byteswap;
        idetable[1]->byteswap = byteswap;
+       idetable[0]->adide = adide;
+       idetable[1]->adide = adide;
        ide_initialize(idecontroller_drive, ide_num);
        idecontroller_its.idetable = idecontroller_drive;
        idecontroller_its.idetotal = TOTAL_IDE * 2;
        start_ide_thread(&idecontroller_its);
 }
 
+static void add_ide_standard_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc, struct ide_board **ideboard, int idetype, bool byteswap, bool adide)
+{
+       struct ide_hdf *ide;
+       struct ide_board *ideb;
+       ideb = allocide(&ideboard[ci->controller_type_unit], rc, ch);
+       if (!ideb)
+               return;
+       ideb->keepautoconfig = true;
+       ideb->type = idetype;
+       ide = add_ide_unit (&idecontroller_drive[(idetype + ci->controller_type_unit) * 2], 2, ch, ci, rc);
+       init_ide(ideb, idetype + ci->controller_type_unit, byteswap, adide);
+}
+
 static bool ide_interrupt_check(struct ide_board *board)
 {
        if (!board->configured)
                return false;
        bool irq = ide_irq_check(board->ide);
-#if 1
+#if 0
        if (board->irq != irq)
                write_log(_T("IDE irq %d -> %d\n"), board->irq, irq);
 #endif
@@ -196,9 +262,29 @@ static bool is_gvp1_intreq(uaecptr addr)
        return false;
 }
 
-static int get_gvp_reg(uaecptr addr, struct ide_board *board, struct ide_hdf **idep)
+static uae_u32 get_ide_reg(struct ide_board *board, int reg)
+{
+       struct ide_hdf *ide = board->ide;
+       if (ide->ide_drv)
+               ide = ide->pair;
+       if (reg == 0)
+               return ide_get_data(ide);
+       else
+               return ide_read_reg(ide, reg);
+}
+static void put_ide_reg(struct ide_board *board, int reg, uae_u32 v)
+{
+       struct ide_hdf *ide = board->ide;
+       if (ide->ide_drv)
+               ide = ide->pair;
+       if (reg == 0)
+               ide_put_data(ide, v);
+       else
+               ide_write_reg(ide, reg, v);
+}
+
+static int get_gvp_reg(uaecptr addr, struct ide_board *board)
 {
-       struct ide_hdf *ide;
        int reg = -1;
 
        if (addr & 0x1000) {
@@ -217,41 +303,27 @@ static int get_gvp_reg(uaecptr addr, struct ide_board *board, struct ide_hdf **i
        if (reg >= 0)
                reg &= IDE_SECONDARY | 7;
 
-       ide = board->ide;
-       if (idecontroller_drive[GVP_IDE * 2]->ide_drv)
-               ide = ide->pair;
-       *idep = ide;
        return reg;
 }
 
-static int get_apollo_reg(uaecptr addr, struct ide_board *board, struct ide_hdf **idep)
+static int get_apollo_reg(uaecptr addr, struct ide_board *board)
 {
-       struct ide_hdf *ide;
        if (addr & 0x4000)
                return -1;
        int reg = addr & 0x1fff;
        reg >>= 10;
        if (addr & 0x2000)
                reg |= IDE_SECONDARY;
-       ide = board->ide;
-       if (idecontroller_drive[APOLLO_IDE * 2]->ide_drv)
-               ide = ide->pair;
-       *idep = ide;
        if (reg != 0 && !(addr & 1))
                reg = -1;
        write_log(_T("APOLLO %04x = %d\n"), addr, reg);
        return reg;
 }
 
-static int get_alf_reg(uaecptr addr, struct ide_board *board, struct ide_hdf **idep)
+static int get_alf_reg(uaecptr addr, struct ide_board *board)
 {
-       struct ide_hdf *ide;
        if (addr & 0x8000)
                return -1;
-       ide = board->ide;
-       if (idecontroller_drive[ALF_IDE * 2]->ide_drv)
-               ide = ide->pair;
-       *idep = ide;
        if (addr & 0x4000) {
                ;
        } else if (addr & 0x1000) {
@@ -265,26 +337,41 @@ static int get_alf_reg(uaecptr addr, struct ide_board *board, struct ide_hdf **i
        return addr;
 }
 
-static int get_masoboshi_reg(uaecptr addr, struct ide_board *board, struct ide_hdf **idep)
+static int get_masoboshi_reg(uaecptr addr, struct ide_board *board)
 {
        int reg;
-       struct ide_hdf *ide;
        if (addr < 0xfc00)
                return -1;
-       ide = board->ide;
-       if (idecontroller_drive[MASOBOSHI_IDE * 2]->ide_drv)
-               ide = ide->pair;
-       *idep = ide;
        reg = 7 - ((addr >> 6) & 7);
        if (addr < 0xfe00)
                reg |= IDE_SECONDARY;
        return reg;
 }
 
+static int get_adide_reg(uaecptr addr, struct ide_board *board)
+{
+       int reg;
+       if (addr & 0x8000)
+               return -1;
+       reg = (addr >> 1) & 7;
+       if (addr & 0x10)
+               reg |= IDE_SECONDARY;
+       return reg;
+}
+
+static int getidenum(struct ide_board *board, struct ide_board **arr)
+{
+       for (int i = 0; i < MAX_DUPLICATE_EXPANSION_BOARDS; i++) {
+               if (board == arr[i])
+                       return i;
+       }
+       return 0;
+}
+
 static uae_u32 ide_read_byte(struct ide_board *board, uaecptr addr)
 {
+       uaecptr oaddr = addr;
        uae_u8 v = 0xff;
-       addr &= 0xffff;
 
 #ifdef JIT
        special_mem |= S_READ;
@@ -296,8 +383,9 @@ static uae_u32 ide_read_byte(struct ide_board *board, uaecptr addr)
        write_log(_T("IDE IO BYTE READ %08x %08x\n"), addr, M68K_GETPC);
 #endif
        
-       if (addr < 0x40)
+       if (addr < 0x40 && (!board->configured || board->keepautoconfig))
                return board->acmemory[addr];
+
        if (board->type == ALF_IDE) {
 
                if (addr < 0x1100 || (addr & 1)) {
@@ -305,10 +393,9 @@ static uae_u32 ide_read_byte(struct ide_board *board, uaecptr addr)
                                v = board->rom[addr & board->rom_mask];
                        return v;
                }
-               struct ide_hdf *ide;
-               int regnum = get_alf_reg(addr, board, &ide);
+               int regnum = get_alf_reg(addr, board);
                if (regnum >= 0) {
-                       v = ide_read_reg(ide, regnum);
+                       v = get_ide_reg(board, regnum);
                }
 #if DEBUG_IDE_ALF
                write_log(_T("ALF GET %08x %02x %d %08x\n"), addr, v, regnum, M68K_GETPC);
@@ -324,7 +411,7 @@ static uae_u32 ide_read_byte(struct ide_board *board, uaecptr addr)
                        }
                } else if (addr >= 0xf000 && addr <= 0xf007) {
                        if (board->subtype)
-                               v = masoboshi_ncr9x_scsi_get(addr, board == &masoboshi_board[0] ? 0 : 1);
+                               v = masoboshi_ncr9x_scsi_get(oaddr, getidenum(board, masoboshi_board));
                } else if (addr == 0xf040) {
                        v = 1;
                        if (ide_irq_check(board->ide)) {
@@ -334,17 +421,16 @@ static uae_u32 ide_read_byte(struct ide_board *board, uaecptr addr)
                        if (board->irq) {
                                v &= ~1;
                        }
-                       v |= masoboshi_ncr9x_scsi_get(addr, board == &masoboshi_board[0] ? 0 : 1);
+                       v |= masoboshi_ncr9x_scsi_get(oaddr, getidenum(board, masoboshi_board));
                } else if (addr == 0xf047) {
                        v = board->state;
                } else {
-                       struct ide_hdf *ide;
-                       regnum = get_masoboshi_reg(addr, board, &ide);
+                       regnum = get_masoboshi_reg(addr, board);
                        if (regnum >= 0) {
-                               v = ide_read_reg(ide, regnum);
+                               v = get_ide_reg(board, regnum);
                        } else if (addr >= MASOBOSHI_SCSI_OFFSET && addr < MASOBOSHI_SCSI_OFFSET_END) {
                                if (board->subtype)
-                                       v = masoboshi_ncr9x_scsi_get(addr, board == &masoboshi_board[0] ? 0 : 1);
+                                       v = masoboshi_ncr9x_scsi_get(oaddr, getidenum(board, masoboshi_board));
                                else
                                        v = 0xff;
                        }
@@ -360,12 +446,11 @@ static uae_u32 ide_read_byte(struct ide_board *board, uaecptr addr)
                                v = board->rom[(addr - APOLLO_ROM_OFFSET) & board->rom_mask];
                } else if (board->configured) {
                        if ((addr & 0xc000) == 0x4000) {
-                               v = apollo_scsi_bget(addr);
+                               v = apollo_scsi_bget(oaddr);
                        } else if (addr < 0x4000) {
-                               struct ide_hdf *ide;
-                               int regnum = get_apollo_reg(addr, board, &ide);
+                               int regnum = get_apollo_reg(addr, board);
                                if (regnum >= 0) {
-                                       v = ide_read_reg(ide, regnum);
+                                       v = get_ide_reg(board, regnum);
                                } else {
                                        v = 0;
                                }
@@ -389,7 +474,7 @@ static uae_u32 ide_read_byte(struct ide_board *board, uaecptr addr)
                        return v;
                }
                if (board->configured) {
-                       if (board == &gvp_ide_rom_board && ISCPUBOARD(BOARD_GVP, BOARD_GVP_SUB_A3001SII)) {
+                       if (board == gvp_ide_rom_board && ISCPUBOARD(BOARD_GVP, BOARD_GVP_SUB_A3001SII)) {
                                if (addr == 0x42) {
                                        v = 0xff;
                                }
@@ -397,13 +482,12 @@ static uae_u32 ide_read_byte(struct ide_board *board, uaecptr addr)
                                write_log(_T("GVP BOOT GET %08x %02x %08x\n"), addr, v, M68K_GETPC);
 #endif
                        } else {
-                               struct ide_hdf *ide;
-                               int regnum = get_gvp_reg(addr, board, &ide);
+                               int regnum = get_gvp_reg(addr, board);
 #if DEBUG_IDE_GVP
                                write_log(_T("GVP IDE GET %08x %02x %d %08x\n"), addr, v, regnum, M68K_GETPC);
 #endif
                                if (regnum >= 0) {
-                                       v = ide_read_reg(ide, regnum);
+                                       v = get_ide_reg(board, regnum);
                                } else if (is_gvp2_intreq(addr)) {
                                        v = board->irq ? 0x40 : 0x00;
 #if DEBUG_IDE_GVP
@@ -411,7 +495,7 @@ static uae_u32 ide_read_byte(struct ide_board *board, uaecptr addr)
 #endif
                                        ide_interrupt_check(board);
                                } else if (is_gvp1_intreq(addr)) {
-                                       v = gvp_ide_controller_board.irq ? 0x80 : 0x00;
+                                       v = board->irq ? 0x80 : 0x00;
 #if DEBUG_IDE_GVP
                                        write_log(_T("GVP IRQ %02x\n"), v);
 #endif
@@ -421,6 +505,29 @@ static uae_u32 ide_read_byte(struct ide_board *board, uaecptr addr)
                } else {
                        v = 0xff;
                }
+
+       } else if (board->type == ADIDE_IDE) {
+
+               if (addr & ADIDE_ROM_OFFSET) {
+                       v = board->rom[addr & board->rom_mask];
+               } else if (board->configured) {
+                       int regnum = get_adide_reg(addr, board);
+                       v = get_ide_reg(board, regnum);
+                       v = adide_decode_word(v);
+               }
+
+       } else if (board->type == MTEC_IDE) {
+
+               if (!(addr & 0x8000)) {
+                       v = board->rom[addr & board->rom_mask];
+               } else if (board->configured) {
+                       v = get_ide_reg(board, (addr >> 8) & 7);
+               }
+
+       } else if (board->type == PROTAR_IDE) {
+
+               v = board->rom[addr & board->rom_mask];
+
        }
        return v;
 }
@@ -435,6 +542,12 @@ static uae_u32 ide_read_word(struct ide_board *board, uaecptr addr)
 
        addr &= board->mask;
 
+       if (addr < 0x40 && (!board->configured || board->keepautoconfig)) {
+               v = board->acmemory[addr] << 8;
+               v |= board->acmemory[addr + 1];
+               return v;
+       }
+
        if (board->type == APOLLO_IDE) {
 
                if (addr >= APOLLO_ROM_OFFSET) {
@@ -451,10 +564,9 @@ static uae_u32 ide_read_word(struct ide_board *board, uaecptr addr)
 
                if (board->type == ALF_IDE) {
 
-                       struct ide_hdf *ide;
-                       int regnum = get_alf_reg(addr, board, &ide);
+                       int regnum = get_alf_reg(addr, board);
                        if (regnum == IDE_DATA) {
-                               v = ide_get_data(ide);
+                               v = get_ide_reg(board, IDE_DATA);
                        } else {
                                v = 0;
                                if (addr == 0x4000 && board->intena)
@@ -464,35 +576,33 @@ static uae_u32 ide_read_word(struct ide_board *board, uaecptr addr)
 #endif
                        }
 
-       } else if (board->type == MASOBOSHI_IDE) {
+               } else if (board->type == MASOBOSHI_IDE) {
 
-               if (addr >= MASOBOSHI_ROM_OFFSET && addr < MASOBOSHI_ROM_OFFSET_END) {
-                       if (board->rom) {
-                               v = board->rom[addr & board->rom_mask] << 8;
-                               v |= board->rom[(addr + 1) & board->rom_mask];
-                       }
-               } else {
-                       struct ide_hdf *ide;
-                       int regnum = get_masoboshi_reg(addr, board, &ide);
-                       if (regnum == IDE_DATA) {
-                               v = ide_get_data(ide);
+                       if (addr >= MASOBOSHI_ROM_OFFSET && addr < MASOBOSHI_ROM_OFFSET_END) {
+                               if (board->rom) {
+                                       v = board->rom[addr & board->rom_mask] << 8;
+                                       v |= board->rom[(addr + 1) & board->rom_mask];
+                               }
                        } else {
-                               v = ide_read_byte(board, addr) << 8;
-                               v |= ide_read_byte(board, addr + 1);
+                               int regnum = get_masoboshi_reg(addr, board);
+                               if (regnum == IDE_DATA) {
+                                       v = get_ide_reg(board, IDE_DATA);
+                               } else {
+                                       v = ide_read_byte(board, addr) << 8;
+                                       v |= ide_read_byte(board, addr + 1);
+                               }
                        }
-               }
 
-       } else if (board->type == APOLLO_IDE) {
+               } else if (board->type == APOLLO_IDE) {
 
                        if ((addr & 0xc000) == 0x4000) {
                                v = apollo_scsi_bget(addr);
                                v <<= 8;
                                v |= apollo_scsi_bget(addr + 1);
                        } else if (addr < 0x4000) {
-                               struct ide_hdf *ide;
-                               int regnum = get_apollo_reg(addr, board, &ide);
+                               int regnum = get_apollo_reg(addr, board);
                                if (regnum == IDE_DATA) {
-                                       v = ide_get_data(ide);
+                                       v = get_ide_reg(board, IDE_DATA);
                                } else {
                                        v = 0;
                                }
@@ -500,10 +610,10 @@ static uae_u32 ide_read_word(struct ide_board *board, uaecptr addr)
 
                } else if (board->type == GVP_IDE) {
 
-                       if (board == &gvp_ide_controller_board || ISCPUBOARD(BOARD_GVP, BOARD_GVP_SUB_A3001SI)) {
+                       if (board == gvp_ide_controller_board || ISCPUBOARD(BOARD_GVP, BOARD_GVP_SUB_A3001SI)) {
                                if (addr < 0x60) {
                                        if (is_gvp1_intreq(addr))
-                                               v = gvp_ide_controller_board.irq ? 0x8000 : 0x0000;
+                                               v = gvp_ide_controller_board->irq ? 0x8000 : 0x0000;
                                        else if (addr == 0x40) {
                                                if (ISCPUBOARD(BOARD_GVP, BOARD_GVP_SUB_A3001SII))
                                                        v = board->intena ? 8 : 0;
@@ -512,10 +622,9 @@ static uae_u32 ide_read_word(struct ide_board *board, uaecptr addr)
                                        write_log(_T("GVP IO WORD READ %08x %08x\n"), addr, M68K_GETPC);
 #endif
                                } else {
-                                       struct ide_hdf *ide;
-                                       int regnum = get_gvp_reg(addr, board, &ide);
+                                       int regnum = get_gvp_reg(addr, board);
                                        if (regnum == IDE_DATA) {
-                                               v = ide_get_data(ide);
+                                               v = get_ide_reg(board, IDE_DATA);
 #if DEBUG_IDE_GVP > 2
                                                write_log(_T("IDE WORD READ %04x\n"), v);
 #endif
@@ -525,6 +634,27 @@ static uae_u32 ide_read_word(struct ide_board *board, uaecptr addr)
                                        }
                                }       
                        }
+
+               } else if (board->type == ADIDE_IDE) {
+
+                       int regnum = get_adide_reg(addr, board);
+                       if (regnum == IDE_DATA) {
+                               v = get_ide_reg(board, IDE_DATA);
+                       } else {
+                               v = get_ide_reg(board, regnum) << 8;
+                               v = adide_decode_word(v);
+                       }
+
+               } else if (board->type == MTEC_IDE) {
+
+                       if (board->configured && (addr & 0x8000)) {
+                               int regnum = (addr >> 8) & 7;
+                               if (regnum == IDE_DATA)
+                                       v = get_ide_reg(board, regnum);
+                               else
+                                       v = ide_read_byte(board, addr) << 8;
+                       }
+
                }
        }
 
@@ -537,6 +667,7 @@ static uae_u32 ide_read_word(struct ide_board *board, uaecptr addr)
 
 static void ide_write_byte(struct ide_board *board, uaecptr addr, uae_u8 v)
 {
+       uaecptr oaddr = addr;
        addr &= board->mask;
 
 #ifdef JIT
@@ -551,6 +682,7 @@ static void ide_write_byte(struct ide_board *board, uaecptr addr, uae_u8 v)
                addrbank *ab = board->bank;
                if (addr == 0x48) {
                        map_banks_z2(ab, v, (board->mask + 1) >> 16);
+                       board->baseaddress = v << 16;
                        board->configured = 1;
                        expamem_next(ab, NULL);
                        return;
@@ -563,30 +695,31 @@ static void ide_write_byte(struct ide_board *board, uaecptr addr, uae_u8 v)
        }
        if (board->configured) {
                if (board->type == ALF_IDE) {
-                       struct ide_hdf *ide;
-                       int regnum = get_alf_reg(addr, board, &ide);
+                       int regnum = get_alf_reg(addr, board);
                        if (regnum >= 0)
-                               ide_write_reg(ide, regnum, v);
+                               put_ide_reg(board, regnum, v);
 #if DEBUG_IDE_ALF
                        write_log(_T("ALF PUT %08x %02x %d %08x\n"), addr, v, regnum, M68K_GETPC);
 #endif
-       } else if (board->type == MASOBOSHI_IDE) {
+               } else if (board->type == MASOBOSHI_IDE) {
 
 #if DEBUG_IDE_MASOBOSHI
                        write_log(_T("MASOBOSHI IO BYTE PUT %08x %02x %08x\n"), addr, v, M68K_GETPC);
 #endif
-                       struct ide_hdf *ide;
-                       int regnum = get_masoboshi_reg(addr, board, &ide);
+                       int regnum = get_masoboshi_reg(addr, board);
                        if (regnum >= 0) {
-                               ide_write_reg(ide, regnum, v);
+                               put_ide_reg(board, regnum, v);
                        } else if (addr >= MASOBOSHI_SCSI_OFFSET && addr < MASOBOSHI_SCSI_OFFSET_END) {
                                if (board->subtype)
-                                       masoboshi_ncr9x_scsi_put(addr, v, board == &masoboshi_board[0] ? 0 : 1);
-                       } else if ((addr >= 0xf000 && addr <= 0xf007) || (addr >= 0xf04a && addr <= 0xf04f)) {
+                                       masoboshi_ncr9x_scsi_put(oaddr, v, getidenum(board, masoboshi_board));
+                       } else if ((addr >= 0xf000 && addr <= 0xf007)) {
                                if (board->subtype)
-                                       masoboshi_ncr9x_scsi_put(addr, v, board == &masoboshi_board[0] ? 0 : 1);
+                                       masoboshi_ncr9x_scsi_put(oaddr, v, getidenum(board, masoboshi_board));
+                       } else if (addr >= 0xf04a && addr <= 0xf04f) {
+                               // dma controller
+                               masoboshi_ncr9x_scsi_put(oaddr, v, getidenum(board, masoboshi_board));
                        } else if (addr >= 0xf040 && addr < 0xf048) {
-                               masoboshi_ncr9x_scsi_put(addr, v, board == &masoboshi_board[0] ? 0 : 1);
+                               masoboshi_ncr9x_scsi_put(oaddr, v, getidenum(board, masoboshi_board));
                                if (addr == 0xf047) {
                                        board->state = v;
                                        board->intena = (v & 8) != 0;
@@ -597,33 +730,48 @@ static void ide_write_byte(struct ide_board *board, uaecptr addr, uae_u8 v)
                                write_log(_T("MASOBOSHI STATUS BYTE PUT %08x %02x %08x\n"), addr, v, M68K_GETPC);
                        }
 
-       } else if (board->type == APOLLO_IDE) {
+               } else if (board->type == APOLLO_IDE) {
 
                        if ((addr & 0xc000) == 0x4000) {
-                               apollo_scsi_bput(addr, v);
+                               apollo_scsi_bput(oaddr, v);
                        } else if (addr < 0x4000) {
-                               struct ide_hdf *ide;
-                               int regnum = get_apollo_reg(addr, board, &ide);
+                               int regnum = get_apollo_reg(addr, board);
                                if (regnum >= 0) {
-                                       ide_write_reg(ide, regnum, v);
+                                       put_ide_reg(board, regnum, v);
                                }
                        }
 
-       } else if (board->type == GVP_IDE) {
-                       if (board == &gvp_ide_rom_board && ISCPUBOARD(BOARD_GVP, BOARD_GVP_SUB_A3001SII)) {
+               } else if (board->type == GVP_IDE) {
+
+                       if (board == gvp_ide_rom_board && ISCPUBOARD(BOARD_GVP, BOARD_GVP_SUB_A3001SII)) {
 #if DEBUG_IDE_GVP
                                write_log(_T("GVP BOOT PUT %08x %02x %08x\n"), addr, v, M68K_GETPC);
 #endif
                        } else {
-                               struct ide_hdf *ide;
-                               int regnum = get_gvp_reg(addr, board, &ide);
+                               int regnum = get_gvp_reg(addr, board);
 #if DEBUG_IDE_GVP
                                write_log(_T("GVP IDE PUT %08x %02x %d %08x\n"), addr, v, regnum, M68K_GETPC);
 #endif
                                if (regnum >= 0)
-                                       ide_write_reg(ide, regnum, v);
+                                       put_ide_reg(board, regnum, v);
+                       }
+
+               } else if (board->type == ADIDE_IDE) {
+
+                       if (board->configured) {
+                               int regnum = get_adide_reg(addr, board);
+                               v = adide_encode_word(v);
+                               put_ide_reg(board, regnum, v);
+                       }
+
+               } else if (board->type == MTEC_IDE) {
+
+                       if (board->configured && (addr & 0x8000)) {
+                               put_ide_reg(board, (addr >> 8) & 7, v);
                        }
+
                }
+
        }
 }
 
@@ -635,16 +783,18 @@ static void ide_write_word(struct ide_board *board, uaecptr addr, uae_u16 v)
        special_mem |= S_WRITE;
 #endif
 
+       if (addr == 0xf04a)
+               addr &= 0xffff;
+
 #if DEBUG_IDE
        write_log(_T("IDE IO WORD WRITE %08x=%04x %08x\n"), addr, v, M68K_GETPC);
 #endif
        if (board->configured) {
                if (board->type == ALF_IDE) {
 
-                       struct ide_hdf *ide;
-                       int regnum = get_alf_reg(addr, board, &ide);
+                       int regnum = get_alf_reg(addr, board);
                        if (regnum == IDE_DATA) {
-                               ide_put_data(ide, v);
+                               put_ide_reg(board, IDE_DATA, v);
                        } else {
 #if DEBUG_IDE_ALF
                                write_log(_T("ALF IO WORD WRITE %08x %04x %08x\n"), addr, v, M68K_GETPC);
@@ -653,10 +803,9 @@ static void ide_write_word(struct ide_board *board, uaecptr addr, uae_u16 v)
 
                } else if (board->type == MASOBOSHI_IDE) {
 
-                       struct ide_hdf *ide;
-                       int regnum = get_masoboshi_reg(addr, board, &ide);
+                       int regnum = get_masoboshi_reg(addr, board);
                        if (regnum == IDE_DATA) {
-                               ide_put_data(ide, v);
+                               put_ide_reg(board, IDE_DATA, v);
                        } else {
                                ide_write_byte(board, addr, v >> 8);
                                ide_write_byte(board, addr + 1, v);
@@ -671,16 +820,15 @@ static void ide_write_word(struct ide_board *board, uaecptr addr, uae_u16 v)
                                apollo_scsi_bput(addr, v >> 8);
                                apollo_scsi_bput(addr + 1, v);
                        } else if (addr < 0x4000) {
-                               struct ide_hdf *ide;
-                               int regnum = get_apollo_reg(addr, board, &ide);
+                               int regnum = get_apollo_reg(addr, board);
                                if (regnum == IDE_DATA) {
-                                       ide_put_data(ide, v);
+                                       put_ide_reg(board, IDE_DATA, v);
                                }
                        }
 
                } else if (board->type == GVP_IDE) {
 
-                       if (board == &gvp_ide_controller_board || ISCPUBOARD(BOARD_GVP, BOARD_GVP_SUB_A3001SI)) {
+                       if (board == gvp_ide_controller_board || ISCPUBOARD(BOARD_GVP, BOARD_GVP_SUB_A3001SI)) {
                                if (addr < 0x60) {
 #if DEBUG_IDE_GVP
                                        write_log(_T("GVP IO WORD WRITE %08x %04x %08x\n"), addr, v, M68K_GETPC);
@@ -688,10 +836,9 @@ static void ide_write_word(struct ide_board *board, uaecptr addr, uae_u16 v)
                                        if (addr == 0x40 && ISCPUBOARD(BOARD_GVP, BOARD_GVP_SUB_A3001SII))
                                                board->intena = (v & 8) != 0;
                                } else {
-                                       struct ide_hdf *ide;
-                                       int regnum = get_gvp_reg(addr, board, &ide);
+                                       int regnum = get_gvp_reg(addr, board);
                                        if (regnum == IDE_DATA) {
-                                               ide_put_data(ide, v);
+                                               put_ide_reg(board, IDE_DATA, v);
 #if DEBUG_IDE_GVP > 2
                                                write_log(_T("IDE WORD WRITE %04x\n"), v);
 #endif
@@ -701,6 +848,27 @@ static void ide_write_word(struct ide_board *board, uaecptr addr, uae_u16 v)
                                        }
                                }
                        }
+
+               } else if (board->type == ADIDE_IDE) {
+
+                       int regnum = get_adide_reg(addr, board);
+                       if (regnum == IDE_DATA) {
+                               put_ide_reg(board, IDE_DATA, v);
+                       } else {
+                               v = adide_encode_word(v);
+                               put_ide_reg(board, regnum, v >> 8);
+                       }
+
+               } else if (board->type == MTEC_IDE) {
+
+                       if (board->configured && (addr & 0x8000)) {
+                               int regnum = (addr >> 8) & 7;
+                               if (regnum == IDE_DATA)
+                                       put_ide_reg(board, regnum, v);
+                               else
+                                       ide_write_byte(board, addr, v >> 8);
+                       }
+
                }
        }
 }
@@ -723,39 +891,57 @@ addrbank gvp_ide_rom_bank = {
        dummy_lgeti, dummy_wgeti, ABFLAG_IO | ABFLAG_SAFE
 };
 
-IDE_MEMORY_FUNCTIONS(alf, ide, alf_board[0]);
-IDE_MEMORY_FUNCTIONS(alf2, ide, alf_board[1]);
-
-addrbank alf_bank = {
-       alf_lget, alf_wget, alf_bget,
-       alf_lput, alf_wput, alf_bput,
-       default_xlate, default_check, NULL, NULL, _T("ALF"),
-       dummy_lgeti, dummy_wgeti, ABFLAG_IO | ABFLAG_SAFE
-};
-addrbank alf_bank2 = {
-       alf2_lget, alf2_wget, alf2_bget,
-       alf2_lput, alf2_wput, alf2_bput,
-       default_xlate, default_check, NULL, NULL, _T("ALF #2"),
-       dummy_lgeti, dummy_wgeti, ABFLAG_IO | ABFLAG_SAFE
-};
-
-IDE_MEMORY_FUNCTIONS(apollo_ide, ide, apollo_board[0]);
-
-addrbank apollo_bank = {
-       apollo_ide_lget, apollo_ide_wget, apollo_ide_bget,
-       apollo_ide_lput, apollo_ide_wput, apollo_ide_bput,
-       default_xlate, default_check, NULL, NULL, _T("Apollo"),
+static void REGPARAM2 ide_generic_bput (uaecptr addr, uae_u32 b)
+{
+       struct ide_board *ide = getideboard(addr);
+       if (ide)
+               ide_write_byte(ide, addr, b);
+}
+static void REGPARAM2 ide_generic_wput (uaecptr addr, uae_u32 b)
+{
+       struct ide_board *ide = getideboard(addr);
+       if (ide)
+               ide_write_word(ide, addr, b);
+}
+static void REGPARAM2 ide_generic_lput (uaecptr addr, uae_u32 b)
+{
+       struct ide_board *ide = getideboard(addr);
+       if (ide) {
+               ide_write_word(ide, addr, b >> 16);
+               ide_write_word(ide, addr + 2, b);
+       }
+}
+static uae_u32 REGPARAM2 ide_generic_bget (uaecptr addr)
+{
+       struct ide_board *ide = getideboard(addr);
+       if (ide)
+               return ide_read_byte(ide, addr);
+       return 0;
+}
+static uae_u32 REGPARAM2 ide_generic_wget (uaecptr addr)
+{
+       struct ide_board *ide = getideboard(addr);
+       if (ide)
+               return ide_read_word(ide, addr);
+       return 0;
+}
+static uae_u32 REGPARAM2 ide_generic_lget (uaecptr addr)
+{
+       struct ide_board *ide = getideboard(addr);
+       if (ide) {
+               uae_u32 v = ide_read_word(ide, addr) << 16;
+               v |= ide_read_word(ide, addr + 2);
+               return v;
+       }
+       return 0;
+}
+static addrbank ide_bank_generic = {
+       ide_generic_lget, ide_generic_wget, ide_generic_bget,
+       ide_generic_lput, ide_generic_wput, ide_generic_bput,
+       default_xlate, default_check, NULL, NULL, _T("IDE"),
        dummy_lgeti, dummy_wgeti, ABFLAG_IO | ABFLAG_SAFE
 };
 
-IDE_MEMORY_FUNCTIONS(masoboshi_ide, ide, masoboshi_board[0]);
-
-addrbank masoboshi_bank = {
-       masoboshi_ide_lget, masoboshi_ide_wget, masoboshi_ide_bget,
-       masoboshi_ide_lput, masoboshi_ide_wput, masoboshi_ide_bput,
-       default_xlate, default_check, NULL, NULL, _T("Masoboshi"),
-       dummy_lgeti, dummy_wgeti, ABFLAG_IO | ABFLAG_SAFE
-};
 
 static void ew(struct ide_board *ide, int addr, uae_u32 value)
 {
@@ -773,20 +959,20 @@ static const uae_u8 gvp_ide2_rom_autoconfig[16] = { 0xd1, 0x0d, 0x00, 0x00, 0x07
 static const uae_u8 gvp_ide2_controller_autoconfig[16] = { 0xc1, 0x0b, 0x00, 0x00, 0x07, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
 static const uae_u8 gvp_ide1_controller_autoconfig[16] = { 0xd1, 0x08, 0x00, 0x00, 0x07, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00 };
 
-addrbank *gvp_ide_rom_autoconfig_init(int devnum)
+addrbank *gvp_ide_rom_autoconfig_init(struct romconfig *rc)
 {
-       struct ide_board *ide = &gvp_ide_rom_board;
+       struct ide_board *ide = getide(rc);
        int roms[2];
-       struct romlist *rl;
        const uae_u8 *autoconfig;
 
        if (ISCPUBOARD(BOARD_GVP, BOARD_GVP_SUB_A3001SI)) {
                ide->bank = &gvp_ide_rom_bank;
                autoconfig = gvp_ide1_controller_autoconfig;
-               init_ide(ide, GVP_IDE, true);
+               init_ide(ide, GVP_IDE, true, false);
                ide->rom_size = 8192;
-               gvp_ide_controller_board.intena = true;
-               gvp_ide_controller_board.configured = -1;
+               gvp_ide_controller_board->intena = true;
+               ide->intena = true;
+               gvp_ide_controller_board->configured = -1;
                roms[0] = 114;
                roms[1] = -1;
        } else {
@@ -801,42 +987,26 @@ addrbank *gvp_ide_rom_autoconfig_init(int devnum)
        ide->configured = 0;
        memset(ide->acmemory, 0xff, sizeof ide->acmemory);
 
-
        ide->rom = xcalloc(uae_u8, ide->rom_size);
        memset(ide->rom, 0xff, ide->rom_size);
        ide->rom_mask = ide->rom_size - 1;
-       int index;
-       struct boardromconfig *brc = get_device_rom(&currprefs, ROMTYPE_CPUBOARD, &index);
-       struct zfile *z = NULL;
-       if (brc) {
-               const TCHAR *romname = brc->roms[index].romfile;
-               z = read_rom_name(romname);
-               if (!z) {
-                       rl = getromlistbyids(roms, romname);
-                       if (rl) {
-                               z = read_rom(rl->rd);
-                       }
-               }
-       }
+       struct zfile *z = read_device_from_romconfig(rc, roms);
        if (z) {
                for (int i = 0; i < 16; i++) {
                        uae_u8 b = autoconfig[i];
                        ew(ide, i * 4, b);
                }
-               write_log(_T("GVP IDE BOOT ROM '%s'\n"), zfile_getname(z));
                int size = zfile_fread(ide->rom, 1, ide->rom_size, z);
                zfile_fclose(z);
-       } else {
-               romwarning(roms);
        }
        return ide->bank;
 }
 
-addrbank *gvp_ide_controller_autoconfig_init(int devnum)
+addrbank *gvp_ide_controller_autoconfig_init(struct romconfig *rc)
 {
-       struct ide_board *ide = &gvp_ide_controller_board;
+       struct ide_board *ide = getide(rc);
 
-       init_ide(ide, GVP_IDE, true);
+       init_ide(ide, GVP_IDE, true, false);
        ide->configured = 0;
        ide->bank = &gvp_ide_controller_bank;
        memset(ide->acmemory, 0xff, sizeof ide->acmemory);
@@ -847,38 +1017,37 @@ addrbank *gvp_ide_controller_autoconfig_init(int devnum)
        return ide->bank;
 }
 
-int gvp_add_ide_unit(int ch, struct uaedev_config_info *ci)
+void gvp_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
 {
        struct ide_hdf *ide;
 
-       ide = add_ide_unit (&idecontroller_drive[GVP_IDE], 2, ch, ci);
-       if (ide == NULL)
-               return 0;
-       return 1;
+       if (!allocide(&gvp_ide_rom_board, rc, ch))
+               return;
+       if (!allocide(&gvp_ide_controller_board, rc, ch))
+               return;
+       ide = add_ide_unit (&idecontroller_drive[(GVP_IDE + ci->controller_type_unit) * 2], 2, ch, ci, rc);
 }
 
 static const uae_u8 alf_autoconfig[16] = { 0xd1, 6, 0x00, 0x00, 0x08, 0x2c, 0x00, 0x00, 0x00, 0x00, ALF_ROM_OFFSET >> 8, ALF_ROM_OFFSET & 0xff };
 static const uae_u8 alfplus_autoconfig[16] = { 0xd1, 38, 0x00, 0x00, 0x08, 0x2c, 0x00, 0x00, 0x00, 0x00, ALF_ROM_OFFSET >> 8, ALF_ROM_OFFSET & 0xff };
 
-addrbank *alf_init(int devnum)
+addrbank *alf_init(struct romconfig *rc)
 {
-       struct ide_board *ide = &alf_board[devnum];
+       struct ide_board *ide = getide(rc);
        int roms[2];
-       bool alfplus = cfgfile_board_enabled(&currprefs, ROMTYPE_ALFAPLUS);
-       struct romconfig *rc = NULL;
+       bool alfplus = cfgfile_board_enabled(&currprefs, ROMTYPE_ALFAPLUS, 0);
 
-       ide->configured = 0;
-
-       if (devnum > 0 && !ide->enabled)
+       if (!ide)
                return &expamem_null;
 
+       ide->configured = 0;
+
        roms[0] = alfplus ? 118 : 117;
        roms[1] = -1;
 
-       init_ide(ide, ALF_IDE + devnum, false);
        ide->configured = 0;
-       ide->bank = &alf_bank;
-       ide->type = ALF_IDE + devnum;
+       ide->bank = &ide_bank_generic;
+       ide->type = ALF_IDE;
        ide->rom_size = 32768 * 6;
        ide->userdata = alfplus;
        ide->intena = alfplus;
@@ -895,11 +1064,9 @@ addrbank *alf_init(int devnum)
                ew(ide, i * 4, b);
        }
 
-       rc = get_device_romconfig(&currprefs, devnum, alfplus ? ROMTYPE_ALFAPLUS : ROMTYPE_ALFA);
-       if (rc && !rc->autoboot_disabled) {
-               struct zfile *z = read_device_rom(&currprefs, devnum, alfplus ? ROMTYPE_ALFAPLUS : ROMTYPE_ALFA, roms);
+       if (!rc->autoboot_disabled) {
+               struct zfile *z = read_device_from_romconfig(rc, roms);
                if (z) {
-                       write_log(_T("ALF BOOT ROM '%s'\n"), zfile_getname(z));
                        for (int i = 0; i < 0x1000 / 2; i++) {
                                uae_u8 b;
                                zfile_fread(&b, 1, 1, z);
@@ -915,21 +1082,14 @@ addrbank *alf_init(int devnum)
                                ide->rom[0x2000 + i * 4 + 3] = b;
                        }
                        zfile_fclose(z);
-               } else {
-                       romwarning(roms);
                }
        }
        return ide->bank;
 }
 
-int alf_add_ide_unit(int ch, struct uaedev_config_info *ci)
+void alf_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
 {
-       struct ide_hdf *ide;
-
-       ide = add_ide_unit (&idecontroller_drive[(ALF_IDE + ci->controller_type_unit) * 2], 2, ch, ci);
-       if (ide == NULL)
-               return 0;
-       return 1;
+       add_ide_standard_unit(ch, ci, rc, alf_board, ALF_IDE, false, false);
 }
 
 // prod 0x22 = IDE + SCSI
@@ -940,31 +1100,21 @@ const uae_u8 apollo_autoconfig[16] = { 0xd2, 0x23, 0x00, 0x00, 0x22, 0x22, 0x00,
 const uae_u8 apollo_autoconfig_cpuboard[16] = { 0xd2, 0x23, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, APOLLO_ROM_OFFSET >> 8, APOLLO_ROM_OFFSET & 0xff };
 const uae_u8 apollo_autoconfig_cpuboard_060[16] = { 0xd2, 0x23, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x02, APOLLO_ROM_OFFSET >> 8, APOLLO_ROM_OFFSET & 0xff };
 
-addrbank *apollo_init(int devnum)
+static addrbank *apollo_init(struct romconfig *rc, bool cpuboard)
 {
-       struct ide_board *ide;
+       struct ide_board *ide = getide(rc);
        int roms[2];
        const uae_u8 *autoconfig;
-       bool cpuboard = false;
-       struct zfile *z = NULL;
-
-       if (devnum < 0) {
-               cpuboard = true;
-               devnum = 0;
-       }
 
-       ide = &apollo_board[devnum];
-       ide->configured = 0;
-       if (devnum > 0 && !ide->enabled)
+       if (!ide)
                return &expamem_null;
 
        roms[0] = -1;
-       init_ide(ide, APOLLO_IDE + devnum, false);
        ide->configured = 0;
-       ide->bank = &apollo_bank;
-       ide->type = APOLLO_IDE + devnum;
+       ide->bank = &ide_bank_generic;
        ide->rom_size = 32768;
        ide->mask = 131072 - 1;
+       ide->type = APOLLO_IDE;
 
        memset(ide->acmemory, 0xff, sizeof ide->acmemory);
 
@@ -977,17 +1127,14 @@ addrbank *apollo_init(int devnum)
                        autoconfig = apollo_autoconfig_cpuboard_060;
                else
                        autoconfig = apollo_autoconfig_cpuboard;
-               z = read_device_rom(&currprefs, devnum, ROMTYPE_CPUBOARD, roms);
-       } else {
-               z = read_device_rom(&currprefs, devnum, ROMTYPE_APOLLO, roms);
        }
+       struct zfile *z = read_device_from_romconfig(rc, roms);
        for (int i = 0; i < 16; i++) {
                uae_u8 b = autoconfig[i];
                ew(ide, i * 4, b);
        }
        if (z) {
                int len = zfile_size(z);
-               write_log(_T("Apollo BOOT ROM '%s' %d\n"), zfile_getname(z), len);
                // skip 68060 $f0 ROM block
                if (len >= 65536)
                        zfile_fseek(z, 32768, SEEK_SET);
@@ -997,44 +1144,39 @@ addrbank *apollo_init(int devnum)
                        ide->rom[i] = b;
                }
                zfile_fclose(z);
-       } else {
-               romwarning(roms);
        }
        return ide->bank;
 }
-addrbank *apollo_init_cpu(int devnum)
+
+addrbank *apollo_init_hd(struct romconfig *rc)
 {
-       return apollo_init(-1);
+       return apollo_init(rc, false);
 }
-
-int apollo_add_ide_unit(int ch, struct uaedev_config_info *ci)
+addrbank *apollo_init_cpu(struct romconfig *rc)
 {
-       struct ide_hdf *ide;
+       return apollo_init(rc, true);
+}
 
-       ide = add_ide_unit (&idecontroller_drive[(APOLLO_IDE + ci->controller_type_unit) * 2], 2, ch, ci);
-       if (ide == NULL)
-               return 0;
-       return 1;
+void apollo_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
+{
+       add_ide_standard_unit(ch, ci, rc, apollo_board, APOLLO_IDE, false, false);
 }
 
-addrbank *masoboshi_init(int devnum)
+addrbank *masoboshi_init(struct romconfig *rc)
 {
-       struct ide_board *ide;
-       struct romconfig *rc = NULL;
+       struct ide_board *ide = getide(rc);
        int roms[2];
 
-       ide = &masoboshi_board[devnum];
-       ide->configured = 0;
-
-       if (devnum > 0 && !ide->enabled)
+       if (!ide)
                return &expamem_null;
 
+       ide->configured = 0;
+
        roms[0] = 120;
        roms[1] = -1;
-       init_ide(ide, MASOBOSHI_IDE + devnum, true);
        ide->configured = 0;
-       ide->bank = &masoboshi_bank;
-       ide->type = MASOBOSHI_IDE + devnum;
+       ide->bank = &ide_bank_generic;
+       ide->type = MASOBOSHI_IDE;
        ide->rom_size = 65536;
        ide->mask = 65536 - 1;
        ide->subtype = 0;
@@ -1043,47 +1185,121 @@ addrbank *masoboshi_init(int devnum)
        memset(ide->rom, 0xff, ide->rom_size);
        memset(ide->acmemory, 0xff, sizeof ide->acmemory);
        ide->rom_mask = ide->rom_size - 1;
-       if (is_device_rom(&currprefs, devnum, ROMTYPE_MASOBOSHI)) {
-               struct zfile *z = read_device_rom(&currprefs, devnum, ROMTYPE_MASOBOSHI, roms);
-               if (z) {
-                       int len = zfile_size(z);
-                       write_log(_T("Masoboshi BOOT ROM '%s' %d\n"), zfile_getname(z), len);
-                       for (int i = 0; i < 32768; i++) {
-                               uae_u8 b;
-                               zfile_fread(&b, 1, 1, z);
-                               ide->rom[i * 2 + 0] = b;
-                               ide->rom[i * 2 + 1] = 0xff;
-                       }
-                       zfile_fclose(z);
-                       rc = get_device_romconfig(&currprefs, devnum, ROMTYPE_MASOBOSHI);
-                       ide->subtype = rc->subtype;
-                       if (rc && rc->autoboot_disabled)
-                               memcpy(ide->acmemory, ide->rom + 0x100, sizeof ide->acmemory);
-                       else
-                               memcpy(ide->acmemory, ide->rom + 0x000, sizeof ide->acmemory);
-               } else {
-                       romwarning(roms);
+       struct zfile *z = read_device_from_romconfig(rc, roms);
+       if (z) {
+               int len = zfile_size(z);
+               for (int i = 0; i < 32768; i++) {
+                       uae_u8 b;
+                       zfile_fread(&b, 1, 1, z);
+                       ide->rom[i * 2 + 0] = b;
+                       ide->rom[i * 2 + 1] = 0xff;
                }
+               zfile_fclose(z);
+               ide->subtype = rc->subtype;
+               if (rc && rc->autoboot_disabled)
+                       memcpy(ide->acmemory, ide->rom + 0x100, sizeof ide->acmemory);
+               else
+                       memcpy(ide->acmemory, ide->rom + 0x000, sizeof ide->acmemory);
        }
        // init SCSI part
-       ncr_masoboshi_autoconfig_init(devnum);
+       ncr_masoboshi_autoconfig_init(rc);
        return ide->bank;
 }
 
-static int masoboshi_add_ide_unit(int ch, struct uaedev_config_info *ci)
+static void masoboshi_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
 {
-       struct ide_hdf *ide;
+       add_ide_standard_unit(ch, ci, rc, masoboshi_board, MASOBOSHI_IDE, true, false);
+}
 
-       ide = add_ide_unit (&idecontroller_drive[(MASOBOSHI_IDE + ci->controller_type_unit) * 2], 2, ch, ci);
-       if (ide == NULL)
-               return 0;
-       return 1;
+void masoboshi_add_idescsi_unit (int ch, struct uaedev_config_info *ci, struct romconfig *rc)
+{
+       if (ch < 0) {
+               masoboshi_add_ide_unit(ch, ci, rc);
+               masoboshi_add_scsi_unit(ch, ci, rc);
+       } else {
+               if (ci->controller_type < HD_CONTROLLER_TYPE_SCSI_FIRST)
+                       masoboshi_add_ide_unit(ch, ci, rc);
+               else
+                       masoboshi_add_scsi_unit(ch, ci, rc);
+       }
 }
 
-int masoboshi_add_idescsi_unit (int ch, struct uaedev_config_info *ci)
+static const uae_u8 adide_autoconfig[16] = { 0xd1, 0x02, 0x00, 0x00, 0x08, 0x17, 0x00, 0x00, 0x00, 0x00, ADIDE_ROM_OFFSET >> 8, ADIDE_ROM_OFFSET & 0xff };
+
+addrbank *adide_init(struct romconfig *rc)
 {
-       if (ci->controller_type < HD_CONTROLLER_TYPE_SCSI_FIRST)
-               return masoboshi_add_ide_unit(ch, ci);
-       else
-               return masoboshi_add_scsi_unit(ch, ci);
+       struct ide_board *ide = getide(rc);
+       int roms[2];
+
+       roms[0] = 129;
+       roms[1] = -1;
+       ide->configured = 0;
+       ide->keepautoconfig = false;
+       ide->bank = &ide_bank_generic;
+       ide->rom_size = 32768;
+       ide->mask = 65536 - 1;
+
+       memset(ide->acmemory, 0xff, sizeof ide->acmemory);
+
+       ide->rom = xcalloc(uae_u8, ide->rom_size);
+       memset(ide->rom, 0xff, ide->rom_size);
+       ide->rom_mask = ide->rom_size - 1;
+       struct zfile *z = read_device_from_romconfig(rc, roms);
+       for (int i = 0; i < 16; i++) {
+               uae_u8 b = adide_autoconfig[i];
+               ew(ide, i * 4, b);
+       }
+       if (z) {
+               for (int i = 0; i < 16384; i++) {
+                       uae_u8 b;
+                       zfile_fread(&b, 1, 1, z);
+                       ide->rom[i * 2 + 0] = b;
+                       ide->rom[i * 2 + 1] = 0xff;
+               }
+               zfile_fclose(z);
+       }
+       return ide->bank;
+}
+
+void adide_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
+{
+       add_ide_standard_unit(ch, ci, rc, adide_board, ADIDE_IDE, true, true);
+}
+
+addrbank *mtec_init(struct romconfig *rc)
+{
+       struct ide_board *ide = getide(rc);
+       int roms[2];
+
+       roms[0] = 130;
+       roms[1] = -1;
+       ide->configured = 0;
+       ide->bank = &ide_bank_generic;
+       ide->rom_size = 32768;
+       ide->mask = 65536 - 1;
+
+       memset(ide->acmemory, 0xff, sizeof ide->acmemory);
+
+       ide->rom = xcalloc(uae_u8, ide->rom_size);
+       memset(ide->rom, 0xff, ide->rom_size);
+       ide->rom_mask = ide->rom_size - 1;
+       struct zfile *z = read_device_from_romconfig(rc, roms);
+       if (z) {
+               if (!rc->autoboot_disabled)
+                       zfile_fseek(z, 16384, SEEK_SET);
+               for (int i = 0; i < 16384; i++) {
+                       uae_u8 b;
+                       zfile_fread(&b, 1, 1, z);
+                       ide->rom[i * 2 + 0] = b;
+                       ide->rom[i * 2 + 1] = 0xff;
+               }
+               zfile_fclose(z);
+               memcpy(ide->acmemory, ide->rom, sizeof ide->acmemory);
+       }
+       return ide->bank;
+}
+
+void mtec_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
+{
+       add_ide_standard_unit(ch, ci, rc, mtec_board, MTEC_IDE, false, false);
 }
index 03cc0bfa53bbfcdf20e33c9182823f2de43d3d90..c830ec482232d3f5d6ad1131f3ced60442215068 100644 (file)
@@ -70,15 +70,16 @@ struct gvp_dmac
 
 struct wd_state {
        bool enabled;
-       const TCHAR *name;
        int configured;
        bool autoconfig;
        uae_u8 dmacmemory[100];
        uae_u8 *rom;
        int board_mask;
+       uaecptr baseaddress;
        int rombankswitcher, rombank;
        int rom_size, rom_mask;
        addrbank *bank;
+       struct romconfig *rc;
 
        smp_comm_pipe requests;
        volatile int scsi_thread_running;
@@ -93,21 +94,21 @@ struct wd_state {
        struct commodore_dmac cdmac;
        struct gvp_dmac gdmac;
 };
-extern wd_state wd_cdtv;
+extern wd_state *wd_cdtv;
 
 extern void init_wd_scsi (struct wd_state*);
 extern void scsi_dmac_a2091_start_dma (struct wd_state*);
 extern void scsi_dmac_a2091_stop_dma (struct wd_state*);
 
-extern addrbank *a2090_init (int devnum);
+extern addrbank *a2090_init (struct romconfig*);
 
-extern addrbank *a2091_init (int devnum);
+extern addrbank *a2091_init (struct romconfig*);
 extern void a2091_free(void);
 extern void a2091_reset (void);
 
-extern addrbank *gvp_init_s1(int devnum);
-extern addrbank *gvp_init_s2(int devnum);
-extern addrbank *gvp_init_accelerator(int devnum);
+extern addrbank *gvp_init_s1(struct romconfig*);
+extern addrbank *gvp_init_s2(struct romconfig*);
+extern addrbank *gvp_init_accelerator(struct romconfig*);
 extern void gvp_free(void);
 extern void gvp_reset (void);
 
@@ -131,10 +132,10 @@ extern void scsi_hsync (void);
 
 #define WD33C93 _T("WD33C93")
 
-extern int a2090_add_scsi_unit(int ch, struct uaedev_config_info *ci);
-extern int a2091_add_scsi_unit(int ch, struct uaedev_config_info *ci);
-extern int gvp_add_scsi_unit(int ch, struct uaedev_config_info *ci);
-extern int a3000_add_scsi_unit(int ch, struct uaedev_config_info *ci);
+extern void a2090_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
+extern void a2091_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
+extern void gvp_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
+extern void a3000_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 
 extern int add_wd_scsi_hd (struct wd_state *wd, int ch, struct hd_hardfiledata *hfd, struct uaedev_config_info *ci, int scsi_level);
 extern int add_wd_scsi_cd (struct wd_state *wd, int ch, int unitnum);
index ad3f4942bd2058c0268a6ab30abfeebf57186d18..7a70d40dabfdc3c732646f30725b68e342e2b004 100644 (file)
@@ -103,8 +103,8 @@ extern void uaegfx_install_code (uaecptr);
 extern uae_u32 emulib_target_getcpurate (uae_u32, uae_u32*);
 
 
-typedef addrbank*(*DEVICE_INIT)(int);
-typedef int(*DEVICE_ADD)(int, struct uaedev_config_info*);
+typedef addrbank*(*DEVICE_INIT)(struct romconfig*);
+typedef void(*DEVICE_ADD)(int, struct uaedev_config_info*, struct romconfig*);
 typedef bool(*E8ACCESS)(int, uae_u32*, int, bool);
 #define EXPANSIONTYPE_SCSI 1
 #define EXPANSIONTYPE_IDE 2
@@ -120,12 +120,14 @@ struct expansionromtype
 {
        const TCHAR *name;
        const TCHAR *friendlyname;
+       const TCHAR *friendlymanufacturer;
        DEVICE_INIT init;
        DEVICE_ADD add;
        int romtype;
        int romtype_extra;
        int parentromtype;
        int zorro;
+       bool singleonly;
        const struct expansionsubromtype *subtypes;
        int defaultsubtype;
        bool autoboot_jumper;
@@ -158,6 +160,7 @@ struct cpuboardsubtype
 };
 struct cpuboardtype
 {
+       int id;
        const TCHAR *name;
        const struct cpuboardsubtype *subtypes;
        int defaultsubtype;
index 4f3abc31518d0ef7494885fc2d3f28609a1d0508..181d3796da8e44dd19115945655bde5cd8b88230 100644 (file)
@@ -3,7 +3,7 @@
 
 extern addrbank dmac_bank;
 
-extern addrbank *cdtv_init (int);
+extern addrbank *cdtv_init (struct romconfig *rc);
 extern void cdtv_free (void);
 extern void CDTV_hsync_handler(void);
 extern void cdtv_check_banks (void);
@@ -14,7 +14,7 @@ uae_u8 cdtv_battram_read (int addr);
 extern void cdtv_loadcardmem (uae_u8*, int);
 extern void cdtv_savecardmem (uae_u8*, int);
 
-extern int cdtv_add_scsi_hd_unit (int ch, struct uaedev_config_info *ci);
+extern void cdtv_add_scsi_unit (int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 
 
 extern void cdtv_getdmadata (uae_u32*);
index 5d3b2fc06399065dd73659d225415628a39a8c3e..19549267cd7efa587a8149031a31d2e7ce0f44f3 100644 (file)
@@ -1,5 +1,5 @@
 
-extern addrbank *cpuboard_autoconfig_init(int);
+extern addrbank *cpuboard_autoconfig_init(struct romconfig*);
 extern bool cpuboard_maprom(void);
 extern void cpuboard_map(void);
 extern void cpuboard_reset(void);
@@ -16,6 +16,7 @@ extern bool cpuboard_jitdirectompatible(struct uae_prefs *p);
 extern bool is_ppc_cpu(struct uae_prefs *);
 extern bool cpuboard_io_special(int addr, uae_u32 *val, int size, bool write);
 extern void cpuboard_overlay_override(void);
+extern void cpuboard_setboard(struct uae_prefs *p, int type, int subtype);
 
 extern bool ppc_interrupt(int new_m68k_ipl);
 
@@ -31,7 +32,7 @@ extern uae_u8 *REGPARAM3 cyberstorm_scsi_ram_xlate(uaecptr addr) REGPARAM;
 #define BOARD_MEMORY_BLIZZARD_PPC 5
 #define BOARD_MEMORY_25BITMEM 6
 
-#define ISCPUBOARD(type,subtype) (currprefs.cpuboard_type == type && currprefs.cpuboard_subtype == subtype)
+#define ISCPUBOARD(type,subtype) (cpuboards[currprefs.cpuboard_type].id == type && (type < 0 || currprefs.cpuboard_subtype == subtype))
 
 #define BOARD_BLIZZARD 1
 #define BOARD_BLIZZARD_SUB_1230IV 0
@@ -59,4 +60,5 @@ extern uae_u8 *REGPARAM3 cyberstorm_scsi_ram_xlate(uaecptr addr) REGPARAM;
 #define BOARD_GVP_SUB_A530 2
 #define BOARD_GVP_SUB_GFORCE030 3
 #define BOARD_GVP_SUB_TEKMAGIC 4
+#define BOARD_KUPKE 9
 
index bf2b6e9d87158403220f9d85a4ca889b3b4580e6..038a867fcd9dda151219c9f9efb0794131e66b13 100644 (file)
@@ -31,7 +31,8 @@ extern void DISK_init (void);
 extern void DISK_free (void);
 extern void DISK_select (uae_u8 data);
 extern void DISK_select_set (uae_u8 data);
-extern uae_u8 DISK_status (void);
+extern uae_u8 DISK_status_ciaa (void);
+extern uae_u8 DISK_status_ciab (uae_u8);
 extern void disk_eject (int num);
 extern int disk_empty (int num);
 extern void disk_insert (int num, const TCHAR *name);
index 57103a9c250e277360136e2bac6c878164c9a843..730a3330e5776006d6acffae1ab94c60e6af6cd2 100644 (file)
@@ -89,6 +89,7 @@ struct hd_hardfiledata {
 };
 
 #define HD_CONTROLLER_EXPANSION_MAX 30
+#define HD_CONTROLLER_NEXT_UNIT 100
 
 #define HD_CONTROLLER_TYPE_UAE 0
 #define HD_CONTROLLER_TYPE_IDE_AUTO (HD_CONTROLLER_TYPE_UAE + 1)
index bac36399cf4bdfba9103407c189c1358e893478f..ed9be1c8a946a3d56b19d6bfb89934ec54641012 100644 (file)
@@ -2,9 +2,9 @@
 extern addrbank gfxboard_bank_memory;
 extern addrbank gfxboard_bank_registers;
 
-extern addrbank *gfxboard_init_memory (int);
-extern addrbank *gfxboard_init_memory_p4_z2(int);
-extern addrbank *gfxboard_init_registers(int);
+extern addrbank *gfxboard_init_memory (int devnum);
+extern addrbank *gfxboard_init_memory_p4_z2(int devnum);
+extern addrbank *gfxboard_init_registers(int devnum);
 extern void gfxboard_free (void);
 extern void gfxboard_reset (void);
 extern void gfxboard_vsync_handler (void);
index 58eaa8a26f7dd74f63e9029fecfbccdf39f4f941..c1edf0f874d85cb81b02d98df4daa233bd40717a 100644 (file)
@@ -29,7 +29,9 @@ struct ide_board
        uae_u8 acmemory[128];
        int rom_size;
        int rom_mask;
+       uaecptr baseaddress;
        int configured;
+       bool keepautoconfig;
        int mask;
        addrbank *bank;
        struct ide_hdf *ide;
@@ -40,6 +42,7 @@ struct ide_board
        int type;
        int userdata;
        int subtype;
+       struct romconfig *rc;
 };
 
 struct ide_hdf
@@ -52,6 +55,7 @@ struct ide_hdf
        struct ide_hdf *pair; // master<>slave
        struct ide_thread_state *its;
        bool byteswap;
+       bool adide;
 
        uae_u8 *secbuf;
        int secbuf_size;
@@ -98,41 +102,44 @@ bool ide_irq_check(struct ide_hdf *ide);
 bool ide_drq_check(struct ide_hdf *ide);
 bool ide_isdrive(struct ide_hdf *ide);
 void ide_initialize(struct ide_hdf **idetable, int chpair);
-struct ide_hdf *add_ide_unit (struct ide_hdf **idetable, int max, int ch, struct uaedev_config_info *ci);
+struct ide_hdf *add_ide_unit (struct ide_hdf **idetable, int max, int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 void remove_ide_unit(struct ide_hdf **idetable, int ch);
 void alloc_ide_mem (struct ide_hdf **ide, int max, struct ide_thread_state *its);
 
 void start_ide_thread(struct ide_thread_state *its);
 void stop_ide_thread(struct ide_thread_state *its);
 
+uae_u16 adide_decode_word(uae_u16 w);
+uae_u16 adide_encode_word(uae_u16 w);
+
 uae_u8 *ide_save_state(uae_u8 *dst, struct ide_hdf *ide);
 uae_u8 *ide_restore_state(uae_u8 *src, struct ide_hdf *ide);
 
 #define IDE_MEMORY_FUNCTIONS(x, y, z) \
 static void REGPARAM2 x ## _bput(uaecptr addr, uae_u32 b) \
 { \
-       y ## _write_byte(## z, addr, b); \
+       y ## _write_byte(## z, addr, b); \
 } \
 static void REGPARAM2 x ## _wput(uaecptr addr, uae_u32 b) \
 { \
-       y ## _write_word(## z, addr, b); \
+       y ## _write_word(## z, addr, b); \
 } \
 static void REGPARAM2 x ## _lput(uaecptr addr, uae_u32 b) \
 { \
-       y ## _write_word(## z, addr, b >> 16); \
-       y ## _write_word(## z, addr + 2, b); \
+       y ## _write_word(## z, addr, b >> 16); \
+       y ## _write_word(## z, addr + 2, b); \
 } \
 static uae_u32 REGPARAM2 x ## _bget(uaecptr addr) \
 { \
-return y ## _read_byte(## z, addr); \
+return y ## _read_byte(## z, addr); \
 } \
 static uae_u32 REGPARAM2 x ## _wget(uaecptr addr) \
 { \
-return y ## _read_word(## z, addr); \
+return y ## _read_word(## z, addr); \
 } \
 static uae_u32 REGPARAM2 x ## _lget(uaecptr addr) \
 { \
-       uae_u32 v = y ## _read_word(## z, addr) << 16; \
-       v |= y ## _read_word(## z, addr + 2); \
+       uae_u32 v = y ## _read_word(## z, addr) << 16; \
+       v |= y ## _read_word(## z, addr + 2); \
        return v; \
 }
index 57c412a6c4e907862bf0d7b8893ef06c1ae97334..977d34fab329cab596eab0fd83b19751993a5d09 100644 (file)
@@ -6,19 +6,25 @@ void idecontroller_reset(void);
 void idecontroller_rethink(void);
 void idecontroller_hsync(void);
 
-int gvp_add_ide_unit(int ch, struct uaedev_config_info *ci);
-addrbank *gvp_ide_rom_autoconfig_init(int devnum);
-addrbank *gvp_ide_controller_autoconfig_init(int devnum);
+void gvp_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
+addrbank *gvp_ide_rom_autoconfig_init(struct romconfig*);
+addrbank *gvp_ide_controller_autoconfig_init(struct romconfig*);
 
-int alf_add_ide_unit(int ch, struct uaedev_config_info *ci);
-addrbank *alf_init(int devnum);
+void alf_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
+addrbank *alf_init(struct romconfig*);
 
-int apollo_add_ide_unit(int ch, struct uaedev_config_info *ci);
-addrbank *apollo_init(int devnum);
-addrbank *apollo_init_cpu(int devnum);
+void apollo_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
+addrbank *apollo_init_hd(struct romconfig*);
+addrbank *apollo_init_cpu(struct romconfig*);
 
-int masoboshi_add_idescsi_unit (int ch, struct uaedev_config_info *ci);
-addrbank *masoboshi_init(int devnum);
+void masoboshi_add_idescsi_unit (int ch, struct uaedev_config_info *ci, struct romconfig *rc);
+addrbank *masoboshi_init(struct romconfig*);
+
+void adide_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
+addrbank *adide_init(struct romconfig *rc);
+
+void mtec_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
+addrbank *mtec_init(struct romconfig *rc);
 
 uae_u32 REGPARAM3 apollo_ide_lget (uaecptr addr) REGPARAM;
 uae_u32 REGPARAM3 apollo_ide_wget (uaecptr addr) REGPARAM;
index c9162fd97875b1f370aab7a76942dc4d490fc5be..a3c3a1c5a5d9c798edd7f6b44c797bcd042ceb1d 100644 (file)
@@ -67,7 +67,7 @@ extern void wait_cpu_cycle_write_ce020 (uaecptr addr, int mode, uae_u32 v);
 extern bool ersatzkickfile;
 extern bool cloanto_rom, kickstart_rom;
 extern uae_u16 kickstart_version;
-extern bool uae_boot_rom;
+extern int uae_boot_rom_type;
 extern int uae_boot_rom_size;
 extern uaecptr rtarea_base;
 
index a7d8faadbe5f6a67cb3ff3a577ba3f05abbed289..73fd6f88c331146b08d6a55d21520341cd332dfb 100644 (file)
@@ -5,22 +5,22 @@ extern void ncr9x_free(void);
 extern void ncr9x_reset(void);
 extern void ncr9x_rethink(void);
 
-extern int cpuboard_ncr9x_add_scsi_unit(int ch, struct uaedev_config_info *ci);
-extern int cpuboard_dkb_add_scsi_unit(int ch, struct uaedev_config_info *ci);
-extern int fastlane_add_scsi_unit(int ch, struct uaedev_config_info *ci);
-extern int oktagon_add_scsi_unit(int ch, struct uaedev_config_info *ci);
-extern int masoboshi_add_scsi_unit(int ch, struct uaedev_config_info *ci);
+extern void cpuboard_ncr9x_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
+extern void cpuboard_dkb_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
+extern void fastlane_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
+extern void oktagon_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
+extern void masoboshi_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 
-extern addrbank *ncr_fastlane_autoconfig_init(int devnum);
-extern addrbank *ncr_oktagon_autoconfig_init(int devnum);
-extern addrbank *ncr_dkb_autoconfig_init(int devnum);
+extern addrbank *ncr_fastlane_autoconfig_init(struct romconfig*);
+extern addrbank *ncr_oktagon_autoconfig_init(struct romconfig*);
+extern addrbank *ncr_dkb_autoconfig_init(struct romconfig*);
 
 extern void cpuboard_ncr9x_scsi_put(uaecptr, uae_u32);
 extern uae_u32 cpuboard_ncr9x_scsi_get(uaecptr);
 
 uae_u32 masoboshi_ncr9x_scsi_get(uaecptr addr, int devnum);
 void masoboshi_ncr9x_scsi_put(uaecptr addr, uae_u32 v, int devnum);
-void ncr_masoboshi_autoconfig_init(int devnum);
+void ncr_masoboshi_autoconfig_init(struct romconfig*);
 
 #define BLIZZARD_2060_SCSI_OFFSET 0x1ff00
 #define BLIZZARD_2060_DMA_OFFSET 0x1fff0
index 9ea7bb08792e86674f0d4188df4f816d0f7c8eff..c90fe19d37e7ebb3a78ba1f57cc2ac8fbe543205 100644 (file)
@@ -3,26 +3,23 @@ void ncr710_io_bput_a4000t(uaecptr, uae_u32);
 uae_u32 ncr710_io_bget_a4000t(uaecptr);
 
 extern addrbank ncr_bank_cyberstorm;
-extern addrbank ncr_bank_blizzardppc;
+extern addrbank ncr_bank_generic;
 
 extern void ncr_init(void);
 extern void ncr_free(void);
 extern void ncr_reset(void);
-
-extern void ncr710_init(void);
-extern addrbank *ncr710_a4091_autoconfig_init(int devnum);
-extern addrbank *ncr710_warpengine_autoconfig_init(int devnum);
-extern void ncr710_free(void);
-extern void ncr710_reset(void);
 extern void ncr_rethink(void);
 
+extern addrbank *ncr710_a4091_autoconfig_init(struct romconfig*);
+extern addrbank *ncr710_warpengine_autoconfig_init(struct romconfig*);
+
 void cpuboard_ncr710_io_bput(uaecptr addr, uae_u32 v);
 uae_u32 cpuboard_ncr710_io_bget(uaecptr addr);
 
-extern int a4000t_add_scsi_unit (int ch, struct uaedev_config_info *ci);
-extern int warpengine_add_scsi_unit(int ch, struct uaedev_config_info *ci);
-extern int tekmagic_add_scsi_unit(int ch, struct uaedev_config_info *ci);
-extern int cyberstorm_add_scsi_unit(int ch, struct uaedev_config_info *ci);
-extern int blizzardppc_add_scsi_unit(int ch, struct uaedev_config_info *ci);
-extern int a4091_add_scsi_unit(int ch, struct uaedev_config_info *ci);
+extern void a4000t_add_scsi_unit (int ch, struct uaedev_config_info *ci, struct romconfig *rc);
+extern void warpengine_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
+extern void tekmagic_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
+extern void cyberstorm_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
+extern void blizzardppc_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
+extern void a4091_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 
index 5d172e0e8012db3bfa2ca8bfeae8c6443a43575e..7df9e0a70045662465a6a933c7ae6806db7b3b32 100644 (file)
@@ -268,6 +268,8 @@ struct gfx_filterdata
        float gfx_filter_horiz_zoom, gfx_filter_vert_zoom;
        float gfx_filter_horiz_zoom_mult, gfx_filter_vert_zoom_mult;
        float gfx_filter_horiz_offset, gfx_filter_vert_offset;
+       int gfx_filter_left_border, gfx_filter_right_border;
+       int gfx_filter_top_border, gfx_filter_bottom_border;
        int gfx_filter_filtermode;
        int gfx_filter_bilinear;
        int gfx_filter_noise, gfx_filter_blur;
@@ -278,6 +280,7 @@ struct gfx_filterdata
        int gfx_filter_keep_autoscale_aspect;
 };
 
+#define MAX_DUPLICATE_EXPANSION_BOARDS 4
 #define MAX_EXPANSION_BOARDS 4
 struct romconfig
 {
@@ -286,6 +289,7 @@ struct romconfig
        uae_u32 board_ram_size;
        bool autoboot_disabled;
        int subtype;
+       void *unitdata;
 };
 #define MAX_BOARD_ROMS 2
 struct boardromconfig
@@ -437,6 +441,7 @@ struct uae_prefs {
        int cd_speed;
        bool tod_hack;
        uae_u32 maprom;
+       int boot_rom;
        bool rom_readwrite;
        int turbo_emulation;
        bool headless;
@@ -739,7 +744,7 @@ extern int cfgfile_configuration_change (int);
 extern void fixup_prefs_dimensions (struct uae_prefs *prefs);
 extern void fixup_prefs (struct uae_prefs *prefs);
 extern void fixup_cpu (struct uae_prefs *prefs);
-bool cfgfile_board_enabled(struct uae_prefs *p, int romtype);
+bool cfgfile_board_enabled(struct uae_prefs *p, int romtype, int devnum);
 
 extern void check_prefs_changed_custom (void);
 extern void check_prefs_changed_cpu (void);
index 9b1e4f2bec1b5174987f90ca76c7fc9423ba935b..4009333593dfc3f05491e6cf8e7f200e3cf99ae7 100644 (file)
@@ -31,6 +31,7 @@ extern int decode_cloanto_rom_do (uae_u8 *mem, int size, int real_size);
 #define ROMTYPE_CB_CSMK3       0x0004000d
 #define ROMTYPE_CB_CSPPC       0x0004000e
 #define ROMTYPE_CB_BLIZPPC     0x0004000f
+#define ROMTYPE_CB_GOLEM030    0x00040010
 
 #define ROMTYPE_FREEZER                0x00080000
 #define ROMTYPE_AR                     0x00080001
@@ -57,6 +58,12 @@ extern int decode_cloanto_rom_do (uae_u8 *mem, int size, int real_size);
 #define ROMTYPE_SUPRA          0x0010000e
 #define ROMTYPE_A2090          0x0010000f
 #define ROMTYPE_GOLEM          0x00100010
+#define ROMTYPE_STARDRIVE      0x00100011
+#define ROMTYPE_KOMMOS         0x00100012
+#define ROMTYPE_VECTOR         0x00100013
+#define ROMTYPE_ADIDE          0x00100014
+#define ROMTYPE_MTEC           0x00100015
+#define ROMTYPE_PROTAR         0x00100016
 
 #define ROMTYPE_QUAD           0x01000000
 #define ROMTYPE_EVEN           0x02000000
@@ -122,6 +129,7 @@ extern TCHAR *romlist_get (const struct romdata *rd);
 extern void romlist_clear (void);
 extern struct zfile *read_rom (struct romdata *rd);
 extern struct zfile *read_rom_name (const TCHAR *filename);
+extern struct zfile *read_device_from_romconfig(struct romconfig *rc, int *roms);
 
 extern int load_keyring (struct uae_prefs *p, const TCHAR *path);
 extern uae_u8 *target_load_keyfile (struct uae_prefs *p, const TCHAR *path, int *size, TCHAR *name);
@@ -138,13 +146,13 @@ extern void addkeyfile (const TCHAR *path);
 extern int romlist_count (void);
 extern struct romlist *romlist_getit (void);
 extern int configure_rom (struct uae_prefs *p, const int *rom, int msg);
-int is_device_rom(struct uae_prefs *p, int devnum, int romtype);
-struct zfile *read_device_rom(struct uae_prefs *p, int devnum, int romtype, int *roms);
-struct romconfig *get_device_romconfig(struct uae_prefs *p, int devnum, int romtype);
-struct boardromconfig *get_device_rom(struct uae_prefs *p, int romtype, int *index);
-void set_device_rom(struct uae_prefs *p, const TCHAR *path, int romtype);
+int is_device_rom(struct uae_prefs *p, int romtype, int devnum);
+struct zfile *read_device_rom(struct uae_prefs *p, int romtype, int devnum, int *roms);
+struct romconfig *get_device_romconfig(struct uae_prefs *p, int romtype, int devnum);
+struct boardromconfig *get_device_rom(struct uae_prefs *p, int romtype, int devnum, int *index);
+void set_device_rom(struct uae_prefs *p, const TCHAR *path, int romtype, int devnum);
 const struct expansionromtype *get_device_expansion_rom(int romtype);
 const struct expansionromtype *get_unit_expansion_rom(int hdunit);
-struct boardromconfig *get_device_rom_new(struct uae_prefs *p, int romtype, int *index);
-void clear_device_rom(struct uae_prefs *p, int romtype);
+struct boardromconfig *get_device_rom_new(struct uae_prefs *p, int romtype, int devnum, int *index);
+void clear_device_rom(struct uae_prefs *p, int romtype, int devnum);
 struct boardromconfig *get_boardromconfig(struct uae_prefs *p, int romtype, int *index);
index 3c8848a0b3953fde4c848f4398030cff3cb247fb..58ecc4abb066d7c53cb1b45e08c9bd1b42298950 100644 (file)
@@ -30,6 +30,7 @@ struct scsi_data
     int sense_len;
     uae_u8 reply[256];
     uae_u8 cmd[16];
+       uae_u8 msgout[4];
     int reply_len;
     int direction;
        uae_u8 message[1];
@@ -71,6 +72,7 @@ extern struct scsi_data_tape *tape_alloc (int unitnum, const TCHAR *tape_directo
 extern void tape_free (struct scsi_data_tape*);
 extern void tape_media_change (int unitnum, struct uaedev_config_info*);
 
+int add_scsi_device(struct scsi_data **sd, int ch, struct uaedev_config_info *ci, struct romconfig *rc, int scsi_level);
 int add_scsi_hd (struct scsi_data **sd, int ch, struct hd_hardfiledata *hfd, struct uaedev_config_info *ci, int scsi_level);
 int add_scsi_cd (struct scsi_data **sd, int ch, int unitnum);
 int add_scsi_tape (struct scsi_data **sd, int ch, const TCHAR *tape_directory, bool readonly);
@@ -150,15 +152,25 @@ void ncr80_rethink(void);
 
 void apollo_scsi_bput(uaecptr addr, uae_u8 v);
 uae_u8 apollo_scsi_bget(uaecptr addr);
-int apollo_add_scsi_unit(int ch, struct uaedev_config_info *ci);
-void apolloscsi_free(void);
-void apolloscsi_reset(void);
+void apollo_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 
-void ncr5380scsi_free(void);
-void ncr5380scsi_reset(void);
+void soft_scsi_free(void);
+void soft_scsi_reset(void);
 
-addrbank *supra_init(int devnum);
-int supra_add_scsi_unit(int ch, struct uaedev_config_info *ci);
+addrbank *supra_init(struct romconfig*);
+void supra_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 
-addrbank *golem_init(int devnum);
-int golem_add_scsi_unit(int ch, struct uaedev_config_info *ci);
+addrbank *golem_init(struct romconfig*);
+void golem_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
+
+addrbank *stardrive_init(struct romconfig*);
+void stardrive_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
+
+addrbank *kommos_init(struct romconfig*);
+void kommos_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
+
+addrbank *vector_init(struct romconfig*);
+void vector_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
+
+addrbank *protar_init(struct romconfig *rc);
+void protar_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
index e9be58c980cde60e431c83c65472ea87aca8e745..4793aa642abd78f93e2d1d8f49cfd75f82207d31 100644 (file)
@@ -1,5 +1,5 @@
 
-addrbank *sndboard_init(int);
+addrbank *sndboard_init(int devnum);
 void sndboard_free(void);
 void sndboard_hsync(void);
 void sndboard_vsync(void);
index cd3c5e94121994526b87c3d947c7abbbe5e744ae..0cdbe689dbc9ea407093a0d383d16d70276d183d 100644 (file)
@@ -20,7 +20,7 @@ extern uae_u32 p96_rgbx16[65536];
 extern int graphics_setup (void);
 extern int graphics_init (bool);
 extern void graphics_leave(void);
-extern void graphics_reset(void);
+extern void graphics_reset(bool);
 extern bool handle_events (void);
 extern int handle_msgpump (void);
 extern void setup_brkhandler (void);
index c79ecd0d45ba60e8eb2997f62e69adab5e2d7817..49b23e31771b04d8a801ad686e457d1adff2e429 100644 (file)
@@ -7,6 +7,7 @@ struct zfile {
     TCHAR *name;
     TCHAR *zipname;
     TCHAR *mode;
+       TCHAR *originalname;
     FILE *f; // real file handle if physical file
     uae_u8 *data; // unpacked data
     int dataseek; // use seek position even if real file
index e9970ba96939c25a817e05685c077d41028a290b..4f08adedee87c0782d5dbc4904045de8b225fe01 100644 (file)
@@ -71,6 +71,7 @@ extern int zfile_zuncompress (void *dst, int dstsize, struct zfile *src, int src
 extern int zfile_gettype (struct zfile *z);
 extern int zfile_zopen (const TCHAR *name, zfile_callback zc, void *user);
 extern TCHAR *zfile_getname (struct zfile *f);
+extern TCHAR *zfile_getoriginalname (struct zfile *f);
 extern TCHAR *zfile_getfilename (struct zfile *f);
 extern uae_u32 zfile_crc32 (struct zfile *f);
 extern struct zfile *zfile_dup (struct zfile *f);
index 514084fb19a55c8b779f8dcb54859dbe8b427aad..ca49f7ef2c9a44c1218df26239f3007dd16f0363 100644 (file)
@@ -1159,7 +1159,7 @@ static uaecptr get_gfxbase (void)
 int inputdevice_is_tablet (void)
 {
        int v;
-       if (!uae_boot_rom)
+       if (uae_boot_rom_type <= 0)
                return 0;
        if (currprefs.input_tablet == TABLET_OFF)
                return 0;
@@ -1194,7 +1194,7 @@ static bool mousehack_enable (void)
 {
        int mode;
 
-       if (!uae_boot_rom || currprefs.input_tablet == TABLET_OFF)
+       if (uae_boot_rom_type <= 0 || currprefs.input_tablet == TABLET_OFF)
                return false;
        if (mousehack_address && mousehack_enabled)
                return true;
@@ -1298,7 +1298,7 @@ void get_custom_mouse_limits (int *w, int *h, int *dx, int *dy, int dbl);
 void inputdevice_tablet_strobe (void)
 {
        mousehack_enable ();
-       if (!uae_boot_rom)
+       if (uae_boot_rom_type <= 0)
                return;
        if (!tablet_data)
                return;
index ed0abf8f1f5a26b0db7518ad3e1e1a584b0920e4..9a3c9530da3487304d43cce3afe8606ef55c1718 100644 (file)
--- a/main.cpp
+++ b/main.cpp
@@ -243,15 +243,12 @@ void fixup_cpu (struct uae_prefs *p)
 
        // 1 = "automatic" PPC config
        if (p->ppc_mode == 1) {
-               p->cpuboard_type = BOARD_CYBERSTORM;
-               p->cpuboard_subtype = BOARD_CYBERSTORM_SUB_PPC;
+               cpuboard_setboard(p,  BOARD_CYBERSTORM, BOARD_CYBERSTORM_SUB_PPC);
                if (p->cs_compatible == CP_A1200) {
-                       p->cpuboard_type = BOARD_BLIZZARD;
-                       p->cpuboard_subtype = BOARD_BLIZZARD_SUB_PPC;
+                       cpuboard_setboard(p,  BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_PPC);
                } else if (p->cs_compatible != CP_A4000 && p->cs_compatible != CP_A4000T && p->cs_compatible != CP_A3000 && p->cs_compatible != CP_A3000T) {
                        if ((p->cs_ide == IDE_A600A1200 || p->cs_pcmcia) && p->cs_mbdmac <= 0) {
-                               p->cpuboard_type = BOARD_BLIZZARD;
-                               p->cpuboard_subtype = BOARD_BLIZZARD_SUB_PPC;
+                               cpuboard_setboard(p,  BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_PPC);
                        }
                }
                if (p->cpuboardmem1_size < 8 * 1024 * 1024)
index 06f168516cdb3caaa3d57e3282c956e0f72391a1..a0c12e34a698c56f8be5771ddde0f56f160527a8 100644 (file)
@@ -2807,7 +2807,7 @@ void map_banks_nojitdirect (addrbank *bank, int start, int size, int realsize)
 
 uae_u8 *save_bootrom (int *len)
 {
-       if (!uae_boot_rom)
+       if (!uae_boot_rom_type)
                return 0;
        *len = uae_boot_rom_size;
        return rtarea_bank.baseaddr;
index 9682217ea709fd14338fc49a6abed05977719df8..56e6126760aef5b98449bdd1fcf59038b6bff2b5 100644 (file)
@@ -26,6 +26,7 @@
 #include "blkdev.h"
 #include "cpuboard.h"
 #include "flashrom.h"
+#include "autoconf.h"
 #include "qemuvga/qemuuaeglue.h"
 #include "qemuvga/queue.h"
 #include "qemuvga/scsi/scsi.h"
@@ -76,7 +77,6 @@
 
 struct ncr9x_state
 {
-       const TCHAR *name;
        DeviceState devobject;
        SCSIDevice *scsid[8];
        SCSIBus scsibus;
@@ -84,18 +84,23 @@ struct ncr9x_state
        uae_u8 *rom;
        uae_u8 acmemory[128];
        int configured;
+       uaecptr baseaddress;
        uae_u32 expamem_hi;
        uae_u32 expamem_lo;
        bool enabled;
        int rom_start, rom_end, rom_offset;
        int io_start, io_end;
        addrbank *bank;
-       bool chipirq, boardirq, intena;
+       bool chipirq, boardirq, boardirqlatch;
+       bool intena;
        void (*irq_func)(struct ncr9x_state*);
        int led;
        uaecptr dma_ptr;
        int dma_cnt;
+       int dma_delay;
+       int dma_delay_val;
        uae_u8 states[16];
+       struct romconfig *rc;
 
        uae_u8 data;
        bool data_valid;
@@ -145,29 +150,89 @@ struct ncr9x_state
        
 */
 
-static struct ncr9x_state ncr_blizzard_scsi;
-static struct ncr9x_state ncr_fastlane_scsi[MAX_BOARD_ROMS];
-static struct ncr9x_state ncr_oktagon2008_scsi[MAX_BOARD_ROMS];
-static struct ncr9x_state ncr_masoboshi_scsi[MAX_BOARD_ROMS];
-static struct ncr9x_state ncr_dkb1200_scsi;
-
-static struct ncr9x_state *ncrs[] =
-{
-       &ncr_blizzard_scsi,
-       &ncr_fastlane_scsi[0],
-       &ncr_fastlane_scsi[1],
-       &ncr_oktagon2008_scsi[0],
-       &ncr_oktagon2008_scsi[1],
-       &ncr_masoboshi_scsi[0],
-       &ncr_masoboshi_scsi[1],
-       &ncr_dkb1200_scsi,
-       NULL
-};
+#define MAX_NCR9X_UNITS 10
+
+static struct ncr9x_state *ncr_blizzard_scsi;
+static struct ncr9x_state *ncr_fastlane_scsi[MAX_DUPLICATE_EXPANSION_BOARDS];
+static struct ncr9x_state *ncr_oktagon2008_scsi[MAX_DUPLICATE_EXPANSION_BOARDS];
+static struct ncr9x_state *ncr_masoboshi_scsi[MAX_DUPLICATE_EXPANSION_BOARDS];
+static struct ncr9x_state *ncr_dkb1200_scsi;
+
+static struct ncr9x_state *ncr_units[MAX_NCR9X_UNITS + 1];
+
+static void freescsi(SCSIDevice *scsi)
+{
+       if (scsi) {
+               free_scsi((struct scsi_data*)scsi->handle);
+               xfree(scsi);
+       }
+}
+
+static void ncr9x_free2(struct ncr9x_state *ncr)
+{
+       if (!ncr)
+               return;
+       for (int ch = 0; ch < 8; ch++) {
+               freescsi(ncr->scsid[ch]);
+               ncr->scsid[ch] = NULL;
+       }
+}
+
+static void freencrunit(struct ncr9x_state **ncr)
+{
+       if (!ncr)
+               return;
+       for (int i = 0; i < MAX_NCR9X_UNITS; i++) {
+               if (ncr_units[i] == *ncr) {
+                       ncr_units[i] = NULL;
+               }
+       }
+       ncr9x_free2(*ncr);
+       xfree(*ncr);
+       *ncr = NULL;
+}
+
+static struct ncr9x_state *allocscsi(struct ncr9x_state **ncr, struct romconfig *rc, int ch)
+{
+       struct ncr9x_state *scsi;
+
+       if (ch < 0) {
+               freencrunit(ncr);
+       }
+       if ((*ncr) == NULL) {
+               scsi = xcalloc(struct ncr9x_state, 1);
+               for (int i = 0; i < MAX_NCR9X_UNITS; i++) {
+                       if (ncr_units[i] == NULL) {
+                               ncr_units[i] = scsi;
+                               rc->unitdata = scsi;
+                               scsi->rc = rc;
+                               if (ncr)
+                                       *ncr = scsi;
+                               return scsi;
+                       }
+               }
+       }
+       return *ncr;
+}
+
+static struct ncr9x_state *getscsi(struct romconfig *rc)
+{
+       for (int i = 0; i < MAX_NCR9X_UNITS; i++) {
+               if (ncr_units[i]) {
+                       struct ncr9x_state *ncr = ncr_units[i];
+                       if (ncr->rc == rc) {
+                               ncr->rc = NULL;
+                               return ncr;
+                       }
+               }
+       }
+       return NULL;
+}
 
 void ncr9x_rethink(void)
 {
-       for (int i = 0; ncrs[i]; i++) {
-               if (ncrs[i]->boardirq) {
+       for (int i = 0; ncr_units[i]; i++) {
+               if (ncr_units[i]->boardirq) {
                        INTREQ_0(0x8000 | 0x0008);
                        return;
                }
@@ -224,12 +289,19 @@ static void set_irq2_fastlane(struct ncr9x_state *ncr)
 
 static void set_irq2_masoboshi(struct ncr9x_state *ncr)
 {
-       if (ncr->chipirq && ncr->intena) {
-               ncr->boardirq = true;
-               ncr9x_rethink();
+       if (ncr->chipirq) {
+               ncr->boardirqlatch = true;
+               if (1 || ncr->intena) {
+                       ncr->boardirq = true;
+                       ncr9x_rethink();
 #if NCR_DEBUG > 1
-               write_log(_T("MASOBOSHI IRQ\n"));
+                       write_log(_T("MASOBOSHI IRQ\n"));
 #endif
+               } else {
+                       ncr->boardirq = false;
+               }
+       } else {
+               ncr->boardirq = false;
        }
 }
 
@@ -524,45 +596,71 @@ static uaecptr beswap(uaecptr addr)
        return (addr & ~3) | (3 - (addr & 3));
 }
 
+static bool isncr(struct ncr9x_state *ncr, struct ncr9x_state **arr)
+{
+       for (int i = 0; i < MAX_DUPLICATE_EXPANSION_BOARDS; i++) {
+               if (arr[i] == ncr)
+                       return true;
+       }
+       return false;
+}
+
 static void ncr9x_io_bput(struct ncr9x_state *ncr, uaecptr addr, uae_u32 val)
 {
        int reg_shift = 2;
        addr &= ncr->board_mask;
-       if (ncr == &ncr_masoboshi_scsi[0] || ncr == &ncr_masoboshi_scsi[1]) {
+       if (isncr(ncr, ncr_masoboshi_scsi)) {
 
                if (addr >= 0xf040 && addr < 0xf048) {
                        if (addr == 0xf040)
                                ncr->states[8] = 0;
                        if (addr == 0xf047) {
                                // dma start
-                               if (val & 0x80)
-                                       ncr->states[8] = 0x80;
+                               if (val & 0x80) {
+                                       write_log(_T("MASOBOSHI DMA start %08x, %d\n"), ncr->dma_ptr, ncr->dma_cnt);
+                                       ncr->dma_delay = (ncr->dma_cnt / maxhpos) * 2;
+                                       ncr->dma_delay_val = -1;
+                               } else {
+                                       ncr->dma_delay = 0;
+                               }
                        }
-                       //write_log(_T("MASOBOSHI DMA %08x = %02X %08x\n"), addr, val, M68K_GETPC);
                        return;
                }
        
+               // DMA LEN (words)
+               if (addr >= 0xf04a && addr < 0xf04c) {
+                       if (addr == 0xf04a) {
+                               ncr->dma_cnt &= 0x00ff;
+                               ncr->dma_cnt |= val << 8;
+                       } else {
+                               ncr->dma_cnt &= 0xff00;
+                               ncr->dma_cnt |= val;
+                       }
+                       return;
+               }
+
+               // DMA PTR
                if (addr >= 0xf04c && addr < 0xf050) {
                        int shift = (addr - 0xf04c) * 8;
                        uae_u32 mask = 0xff << shift;
                        ncr->dma_ptr &= ~mask;
                        ncr->dma_ptr |= val << shift;
                        ncr->dma_ptr &= 0xffffff;
-                       if (addr == 0xf04f)
-                               write_log(_T("MASOBOSHI DMA PTR = %08x\n"), ncr->dma_ptr, M68K_GETPC);
                        return;
                }
 
                if (addr >= 0xf000 && addr <= 0xf007) {
                        ncr->states[addr - 0xf000] = val;
                        if (addr == 0xf000) {
-                               ncr->boardirq = false;
+                               ncr->boardirqlatch = false;
                                set_irq2_masoboshi(ncr);
                        }
+#if 0
                        if (addr == 0xf007) {
-                               ncr->intena = (val & 8) != 0;
+                               ncr->intena = true;//(val & 8) == 0;
                                ncr9x_rethink();
                        }
+#endif
 #if 0
                        if (addr == 0xf047) { // dma start
                                if (val & 0x80)
@@ -572,7 +670,9 @@ static void ncr9x_io_bput(struct ncr9x_state *ncr, uaecptr addr, uae_u32 val)
                                ncr->states[2] = 0;
                        }
 #endif
+#if 0
                        write_log(_T("MASOBOSHI IO %08X PUT %02x %08x\n"), addr, val & 0xff, M68K_GETPC);
+#endif
                        return;
                }
 
@@ -602,7 +702,7 @@ static void ncr9x_io_bput(struct ncr9x_state *ncr, uaecptr addr, uae_u32 val)
                reg_shift = 1;
                addr &= 0x3f;
 
-       } else if (ncr == &ncr_oktagon2008_scsi[0] || ncr == &ncr_oktagon2008_scsi[1]) {
+       } else if (isncr(ncr, ncr_oktagon2008_scsi)) {
                if (addr == OKTAGON_EEPROM_SCL) {
                        eeprom_i2c_set(ncr->eeprom, BITBANG_I2C_SCL, (val & 0x80) != 0);
                } else if (addr == OKTAGON_EEPROM_SDA) {
@@ -621,7 +721,7 @@ static void ncr9x_io_bput(struct ncr9x_state *ncr, uaecptr addr, uae_u32 val)
                        return;
                }
                reg_shift = 1;
-       } else if (ncr == &ncr_fastlane_scsi[0] || ncr == &ncr_fastlane_scsi[1]) {
+       } else if (isncr(ncr, ncr_fastlane_scsi)) {
                if (addr >= FASTLANE_HARDBITS) {
                        if (addr == FASTLANE_HARDBITS) {
                                int oldstate = ncr->states[0];
@@ -646,7 +746,7 @@ static void ncr9x_io_bput(struct ncr9x_state *ncr, uaecptr addr, uae_u32 val)
                                esp_dma_enable(ncr->devobject.lsistate, 1);
                        return;
                }
-       } else if (currprefs.cpuboard_type == BOARD_BLIZZARD && currprefs.cpuboard_subtype == BOARD_BLIZZARD_SUB_2060) {
+       } else if (ISCPUBOARD(BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_2060)) {
                if (addr >= BLIZZARD_2060_DMA_OFFSET) {
                        //write_log (_T("Blizzard DMA PUT %08x %02X\n"), addr, (uae_u8)val);
                        addr &= 0xf;
@@ -662,8 +762,8 @@ static void ncr9x_io_bput(struct ncr9x_state *ncr, uaecptr addr, uae_u32 val)
                        ncr->led = val;
                        return;
                }
-       } else if (currprefs.cpuboard_type == BOARD_BLIZZARD && (currprefs.cpuboard_subtype == BOARD_BLIZZARD_SUB_1230IV || currprefs.cpuboard_subtype == BOARD_BLIZZARD_SUB_1260)) {
-               if (!cfgfile_board_enabled(&currprefs, ROMTYPE_CPUBOARDEXT))
+       } else if (ISCPUBOARD(BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_1230IV) || ISCPUBOARD(BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_1260)) {
+               if (!cfgfile_board_enabled(&currprefs, ROMTYPE_CPUBOARDEXT, 0))
                        return;
                if (addr >= BLIZZARD_SCSI_KIT_DMA_OFFSET) {
                        addr &= 0x18000;
@@ -680,7 +780,7 @@ static void ncr9x_io_bput(struct ncr9x_state *ncr, uaecptr addr, uae_u32 val)
                        //write_log(_T("Blizzard DMA PUT %08x %02X\n"), addr, (uae_u8)val);
                        return;
                }
-       } else if (currprefs.cpuboard_type == BOARD_CYBERSTORM && currprefs.cpuboard_subtype == BOARD_CYBERSTORM_SUB_MK1) {
+       } else if (ISCPUBOARD(BOARD_CYBERSTORM, BOARD_CYBERSTORM_SUB_MK1)) {
                if (addr >= CYBERSTORM_MK1_JUMPER_OFFSET) {
                        if (addr == CYBERSTORM_MK1_JUMPER_OFFSET)
                                esp_dma_enable(ncr->devobject.lsistate, 1);
@@ -695,7 +795,7 @@ static void ncr9x_io_bput(struct ncr9x_state *ncr, uaecptr addr, uae_u32 val)
                        ncr->led = val;
                        return;
                }
-       } else if (currprefs.cpuboard_type == BOARD_CYBERSTORM && currprefs.cpuboard_subtype == BOARD_CYBERSTORM_SUB_MK2) {
+       } else if (ISCPUBOARD(BOARD_CYBERSTORM, BOARD_CYBERSTORM_SUB_MK2)) {
                if (addr >= CYBERSTORM_MK2_DMA_OFFSET) {
                        addr &= 0xf;
                        addr >>= 2;
@@ -732,6 +832,8 @@ static void ncr9x_io_bput(struct ncr9x_state *ncr, uaecptr addr, uae_u32 val)
                        return;
                }
        }
+       if (!ncr->devobject.lsistate)
+               return;
        addr >>= reg_shift;
        addr &= IO_MASK;
 #if NCR_DEBUG > 1
@@ -745,7 +847,7 @@ uae_u32 ncr9x_io_bget(struct ncr9x_state *ncr, uaecptr addr)
        uae_u8 v = 0xff;
        int reg_shift = 2;
        addr &= ncr->board_mask;
-       if (ncr == &ncr_masoboshi_scsi[0] || ncr == &ncr_masoboshi_scsi[1]) {
+       if (isncr(ncr, ncr_masoboshi_scsi)) {
 
                if (addr == MASOBOSHI_ESP_ADDR + 3 * 2 && (ncr->states[0] & 0x80))
                        return 2;
@@ -753,6 +855,16 @@ uae_u32 ncr9x_io_bget(struct ncr9x_state *ncr, uaecptr addr)
                        ncr->states[0] &= ~0x80;
 
                if (addr == 0xf040) {
+
+                       if (ncr->dma_delay > 0) {
+                               if (vpos != ncr->dma_delay_val) {
+                                       ncr->dma_delay--;
+                                       ncr->dma_delay_val = vpos;
+                                       if (!ncr->dma_delay) {
+                                               ncr->states[8] = 0x80;
+                                       }
+                               }
+                       }
                        v = ncr->states[8];
                        return v;
                }
@@ -771,21 +883,24 @@ uae_u32 ncr9x_io_bget(struct ncr9x_state *ncr, uaecptr addr)
                if (addr >= 0xf000 && addr <= 0xf007) {
                        int idx = addr - 0xf000;
                        if (addr == 0xf000) {
-                               ncr->states[0] &= ~3;
-                               //ncr->states[0] |= 1;
-//                             if (esp_dreq(&ncr->devobject)) {
-//                                     write_log(_T("DREQ\n"));
-//                                     ncr->states[0] |= 2; // dma data waiting
-//                             }
-                               if (ncr->boardirq || ncr->chipirq) {
-                                       ncr->states[0] |= 2; // scsi interrupt
+                               ncr->states[0] |= 2;
+                               ncr->states[0] |= 1;
+                               if (esp_dreq(&ncr->devobject)) {
+                                       ncr->states[0] &= ~1; // data request
+                               }
+                               if (ncr->boardirqlatch) {
+                                       ncr->states[0] &= ~2; // scsi interrupt
                                }
+#if 0
                                if (ncr->chipirq) {
-                                       ncr->states[0] |= 1;
+                                       ncr->states[0] &= ~1;
                                }
+#endif
                        }
                        v = ncr->states[idx];
+#if 0
                        write_log(_T("MASOBOSHI IO %08X GET %02x %08x\n"), addr, v, M68K_GETPC);
+#endif
                        return v;
                }
 #if 0
@@ -811,7 +926,7 @@ uae_u32 ncr9x_io_bget(struct ncr9x_state *ncr, uaecptr addr)
                reg_shift = 1;
                addr &= 0x3f;
 
-       } else if (ncr == &ncr_oktagon2008_scsi[0] || ncr == &ncr_oktagon2008_scsi[1]) {
+       } else if (isncr(ncr, ncr_oktagon2008_scsi)) {
                if (addr == OKTAGON_EEPROM_SCL) {
                        return eeprom_i2c_set(ncr->eeprom, BITBANG_I2C_SCL, -1) ? 0x80 : 0x00;
                } else if (addr == OKTAGON_EEPROM_SDA) {
@@ -827,7 +942,7 @@ uae_u32 ncr9x_io_bget(struct ncr9x_state *ncr, uaecptr addr)
                if (addr < OKTAGON_ESP_ADDR || addr >= OKTAGON_ESP_ADDR + 0x100)
                        return 0xff;
                reg_shift = 1;
-       } else if (ncr == &ncr_fastlane_scsi[0] || ncr == &ncr_fastlane_scsi[1]) {
+       } else if (isncr(ncr, ncr_fastlane_scsi)) {
                if (addr >= FASTLANE_HARDBITS) {
                        if (addr == FASTLANE_HARDBITS) {
                                uae_u8 v = ncr->states[0];
@@ -836,19 +951,19 @@ uae_u32 ncr9x_io_bget(struct ncr9x_state *ncr, uaecptr addr)
                        }
                        return 0;
                }
-       } else if (currprefs.cpuboard_type == BOARD_BLIZZARD && currprefs.cpuboard_subtype == BOARD_BLIZZARD_SUB_2060) {
+       } else if (ISCPUBOARD(BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_2060)) {
                if (addr >= BLIZZARD_2060_DMA_OFFSET) {
                        write_log(_T("Blizzard DMA GET %08x\n"), addr);
                        return 0;
                } else if (addr >= BLIZZARD_2060_LED_OFFSET) {
                        return ncr->led;
                }
-       } else if (currprefs.cpuboard_type == BOARD_BLIZZARD && (currprefs.cpuboard_subtype == BOARD_BLIZZARD_SUB_1230IV || currprefs.cpuboard_subtype == BOARD_BLIZZARD_SUB_1260)) {
-               if (!cfgfile_board_enabled(&currprefs, ROMTYPE_CPUBOARDEXT))
+       } else if (ISCPUBOARD(BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_1230IV) || ISCPUBOARD(BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_1260)) {
+               if (!cfgfile_board_enabled(&currprefs, ROMTYPE_CPUBOARDEXT, 0))
                        return 0;
                if (addr >= BLIZZARD_SCSI_KIT_DMA_OFFSET)
                        return 0;
-       } else if (currprefs.cpuboard_type == BOARD_CYBERSTORM && currprefs.cpuboard_subtype == BOARD_CYBERSTORM_SUB_MK1) {
+       } else if (ISCPUBOARD(BOARD_CYBERSTORM, BOARD_CYBERSTORM_SUB_MK1)) {
                if (addr >= CYBERSTORM_MK1_JUMPER_OFFSET) {
                        return 0xff;
                } else if (addr >= CYBERSTORM_MK1_DMA_OFFSET) {
@@ -856,7 +971,7 @@ uae_u32 ncr9x_io_bget(struct ncr9x_state *ncr, uaecptr addr)
                } else if (addr >= CYBERSTORM_MK1_LED_OFFSET) {
                        return ncr->led;
                }
-       } else if (currprefs.cpuboard_type == BOARD_CYBERSTORM && currprefs.cpuboard_subtype == BOARD_CYBERSTORM_SUB_MK2) {
+       } else if (ISCPUBOARD(BOARD_CYBERSTORM, BOARD_CYBERSTORM_SUB_MK2)) {
                if (addr >= CYBERSTORM_MK2_DMA_OFFSET) {
                        return 0;
                } else if (addr >= CYBERSTORM_MK2_LED_OFFSET) {
@@ -888,6 +1003,8 @@ uae_u32 ncr9x_io_bget(struct ncr9x_state *ncr, uaecptr addr)
                        return 0;
                }
        }
+       if (!ncr->devobject.lsistate)
+               return v;
        addr >>= reg_shift;
        addr &= IO_MASK;
        v = esp_reg_read(ncr->devobject.lsistate, (addr));
@@ -937,7 +1054,7 @@ static uae_u32 REGPARAM2 ncr9x_lget(struct ncr9x_state *ncr, uaecptr addr)
        special_mem |= S_READ;
 #endif
        addr &= ncr->board_mask;
-       if (ncr == &ncr_oktagon2008_scsi[0] || ncr == &ncr_oktagon2008_scsi[1]) {
+       if (isncr(ncr, ncr_oktagon2008_scsi)) {
                v =  ncr9x_io_bget(ncr, addr + 0) << 24;
                v |= ncr9x_io_bget(ncr, addr + 1) << 16;
                v |= ncr9x_io_bget(ncr, addr + 2) <<  8;
@@ -958,7 +1075,7 @@ static uae_u32 REGPARAM2 ncr9x_wget(struct ncr9x_state *ncr, uaecptr addr)
        special_mem |= S_READ;
 #endif
        addr &= ncr->board_mask;
-       if (ncr == &ncr_oktagon2008_scsi[0] || ncr == &ncr_oktagon2008_scsi[1]) {
+       if (isncr(ncr, ncr_oktagon2008_scsi)) {
                v = ncr9x_io_bget(ncr, addr) << 8;
                v |= ncr9x_io_bget(ncr, addr + 1);
        } else {
@@ -991,7 +1108,7 @@ static void REGPARAM2 ncr9x_lput(struct ncr9x_state *ncr, uaecptr addr, uae_u32
        special_mem |= S_WRITE;
 #endif
        addr &= ncr->board_mask;
-       if (ncr == &ncr_oktagon2008_scsi[0] || ncr == &ncr_oktagon2008_scsi[1]) {
+       if (isncr(ncr, ncr_oktagon2008_scsi)) {
                ncr9x_io_bput(ncr, addr + 0, l >> 24);
                ncr9x_io_bput(ncr, addr + 1, l >> 16);
                ncr9x_io_bput(ncr, addr + 2, l >>  8);
@@ -1017,13 +1134,14 @@ static void REGPARAM2 ncr9x_wput(struct ncr9x_state *ncr, uaecptr addr, uae_u32
                {
                        case 0x44:
                        map_banks (ncr->bank, expamem_z3_pointer >> 16, FASTLANE_BOARD_SIZE >> 16, 0);
+                       ncr->baseaddress = expamem_z3_pointer;
                        ncr->configured = 1;
                        expamem_next (ncr->bank, NULL);
                        break;
                }
                return;
        }
-       if (ncr == &ncr_oktagon2008_scsi[0] || ncr == &ncr_oktagon2008_scsi[1]) {
+       if (isncr(ncr, ncr_oktagon2008_scsi)) {
                ncr9x_io_bput(ncr, addr, w >> 8);
                ncr9x_io_bput(ncr, addr + 1, w);
        } else {
@@ -1044,15 +1162,16 @@ static void REGPARAM2 ncr9x_bput(struct ncr9x_state *ncr, uaecptr addr, uae_u32
                switch (addr)
                {
                        case 0x48:
-                       if (ncr == &ncr_oktagon2008_scsi[0] || ncr == &ncr_oktagon2008_scsi[1]) {
+                       if (isncr(ncr, ncr_oktagon2008_scsi)) {
                                map_banks (ncr->bank, expamem_z2_pointer >> 16, OKTAGON_BOARD_SIZE >> 16, 0);
                                ncr->configured = 1;
                                expamem_next (ncr->bank, NULL);
-                       } else if (ncr == &ncr_dkb1200_scsi) {
+                       } else if (ncr == ncr_dkb1200_scsi) {
                                map_banks (ncr->bank, expamem_z2_pointer >> 16, DKB_BOARD_SIZE >> 16, 0);
                                ncr->configured = 1;
                                expamem_next (ncr->bank, NULL);
                        }
+                       ncr->baseaddress = expamem_z2_pointer;
                        break;
                        case 0x4c:
                        ncr->configured = 1;
@@ -1064,31 +1183,79 @@ static void REGPARAM2 ncr9x_bput(struct ncr9x_state *ncr, uaecptr addr, uae_u32
        ncr9x_bput2(ncr, addr, b);
 }
 
-SCSI_MEMORY_FUNCTIONS(bncr9x, ncr9x, ncr_blizzard_scsi);
+static struct ncr9x_state *getscsiboard(uaecptr addr)
+{
+       for (int i = 0; ncr_units[i]; i++) {
+               if (!ncr_units[i]->baseaddress)
+                       return ncr_units[i];
+               if ((addr & ~ncr_units[i]->board_mask) == ncr_units[i]->baseaddress)
+                       return ncr_units[i];
+       }
+       return NULL;
+}
 
-static addrbank ncr9x_bank_blizzard = {
-       bncr9x_lget, bncr9x_wget, bncr9x_bget,
-       bncr9x_lput, bncr9x_wput, bncr9x_bput,
+static void REGPARAM2 ncr9x_generic_bput (uaecptr addr, uae_u32 b)
+{
+       struct ncr9x_state *ncr = getscsiboard(addr);
+       if (ncr)
+               ncr9x_bput(ncr, addr, b);
+}
+static void REGPARAM2 ncr9x_generic_wput (uaecptr addr, uae_u32 b)
+{
+       struct ncr9x_state *ncr = getscsiboard(addr);
+       if (ncr)
+               ncr9x_wput(ncr, addr, b);
+}
+static void REGPARAM2 ncr9x_generic_lput (uaecptr addr, uae_u32 b)
+{
+       struct ncr9x_state *ncr = getscsiboard(addr);
+       if (ncr)
+               ncr9x_lput(ncr, addr, b);
+}
+static uae_u32 REGPARAM2 ncr9x_generic_bget (uaecptr addr)
+{
+       struct ncr9x_state *ncr = getscsiboard(addr);
+       if (ncr)
+               return ncr9x_bget(ncr, addr);
+       return 0;
+}
+static uae_u32 REGPARAM2 ncr9x_generic_wget (uaecptr addr)
+{
+       struct ncr9x_state *ncr = getscsiboard(addr);
+       if (ncr)
+               return ncr9x_wget(ncr, addr);
+       return 0;
+}
+static uae_u32 REGPARAM2 ncr9x_generic_lget (uaecptr addr)
+{
+       struct ncr9x_state *ncr = getscsiboard(addr);
+       if (ncr)
+               return ncr9x_lget(ncr, addr);
+       return 0;
+}
+static addrbank ncr9x_bank_generic = {
+       ncr9x_generic_lget, ncr9x_generic_wget, ncr9x_generic_bget,
+       ncr9x_generic_lput, ncr9x_generic_wput, ncr9x_generic_bput,
        default_xlate, default_check, NULL, NULL, _T("53C94/FAS216"),
        dummy_lgeti, dummy_wgeti, ABFLAG_IO
 };
 
 uae_u32 cpuboard_ncr9x_scsi_get(uaecptr addr)
 {
-       return ncr9x_io_bget(&ncr_blizzard_scsi, addr);
+       return ncr9x_io_bget(ncr_blizzard_scsi, addr);
 }
 void cpuboard_ncr9x_scsi_put(uaecptr addr, uae_u32 v)
 {
-       ncr9x_io_bput(&ncr_blizzard_scsi, addr, v);
+       ncr9x_io_bput(ncr_blizzard_scsi, addr, v);
 }
 
 uae_u32 masoboshi_ncr9x_scsi_get(uaecptr addr, int devnum)
 {
-       return ncr9x_io_bget(&ncr_masoboshi_scsi[devnum], addr);
+       return ncr9x_io_bget(ncr_masoboshi_scsi[devnum], addr);
 }
 void masoboshi_ncr9x_scsi_put(uaecptr addr, uae_u32 v, int devnum)
 {
-       ncr9x_io_bput(&ncr_masoboshi_scsi[devnum], addr, v);
+       ncr9x_io_bput(ncr_masoboshi_scsi[devnum], addr, v);
 }
 
 static void ew(struct ncr9x_state *ncr, int addr, uae_u8 value)
@@ -1102,109 +1269,32 @@ static void ew(struct ncr9x_state *ncr, int addr, uae_u8 value)
        }
 }
 
-SCSI_MEMORY_FUNCTIONS(ncr_fastlane, ncr9x, ncr_fastlane_scsi[0]);
-SCSI_MEMORY_FUNCTIONS(ncr2_fastlane, ncr9x, ncr_fastlane_scsi[1]);
-DECLARE_MEMORY_FUNCTIONS(ncr_fastlane)
-static addrbank ncr_bank_fastlane = {
-       ncr_fastlane_lget, ncr_fastlane_wget, ncr_fastlane_bget,
-       ncr_fastlane_lput, ncr_fastlane_wput, ncr_fastlane_bput,
-       default_xlate, default_check, NULL, NULL, _T("Fastlane"),
-       dummy_lgeti, dummy_wgeti, ABFLAG_IO
-};
-DECLARE_MEMORY_FUNCTIONS(ncr2_fastlane)
-static addrbank ncr_bank_fastlane_2 = {
-       ncr2_fastlane_lget, ncr2_fastlane_wget, ncr2_fastlane_bget,
-       ncr2_fastlane_lput, ncr2_fastlane_wput, ncr2_fastlane_bput,
-       default_xlate, default_check, NULL, NULL, _T("Fastlane #2"),
-       dummy_lgeti, dummy_wgeti, ABFLAG_IO
-};
-
-SCSI_MEMORY_FUNCTIONS(ncr_oktagon, ncr9x, ncr_oktagon2008_scsi[0]);
-SCSI_MEMORY_FUNCTIONS(ncr2_oktagon, ncr9x, ncr_oktagon2008_scsi[1]);
-DECLARE_MEMORY_FUNCTIONS(ncr_oktagon2008)
-static addrbank ncr_bank_oktagon = {
-       ncr_oktagon_lget, ncr_oktagon_wget, ncr_oktagon_bget,
-       ncr_oktagon_lput, ncr_oktagon_wput, ncr_oktagon_bput,
-       default_xlate, default_check, NULL, NULL, _T("Oktagon 2008"),
-       dummy_lgeti, dummy_wgeti, ABFLAG_IO | ABFLAG_SAFE
-};
-DECLARE_MEMORY_FUNCTIONS(ncr2_oktagon2008)
-static addrbank ncr_bank_oktagon_2 = {
-       ncr2_oktagon_lget, ncr2_oktagon_wget, ncr2_oktagon_bget,
-       ncr2_oktagon_lput, ncr2_oktagon_wput, ncr2_oktagon_bput,
-       default_xlate, default_check, NULL, NULL, _T("Oktagon 2008 #2"),
-       dummy_lgeti, dummy_wgeti, ABFLAG_IO
-};
-SCSI_MEMORY_FUNCTIONS(ncr_dkb, ncr9x, ncr_dkb1200_scsi);
-DECLARE_MEMORY_FUNCTIONS(ncr_dkb)
-static addrbank ncr_bank_dkb = {
-       ncr_dkb_lget, ncr_dkb_wget, ncr_dkb_bget,
-       ncr_dkb_lput, ncr_dkb_wput, ncr_dkb_bput,
-       default_xlate, default_check, NULL, NULL, _T("DKB"),
-       dummy_lgeti, dummy_wgeti, ABFLAG_IO
-};
-
 static void ncr9x_reset_board(struct ncr9x_state *ncr)
 {
+       if (!ncr)
+               return;
        ncr->configured = 0;
-       if (currprefs.cpuboard_type == BOARD_CYBERSTORM && currprefs.cpuboard_subtype == BOARD_CYBERSTORM_SUB_MK1)
-               ncr->board_mask = 0xffff;
-       else
-               ncr->board_mask = 0x1ffff;
        ncr->boardirq = false;
        ncr->chipirq = false;
-       if (ncr->devobject.lsistate)
-               esp_scsi_reset(&ncr->devobject, ncr);
-       ncr->irq_func = set_irq2;
-       if (ncr == &ncr_blizzard_scsi) {
-               ncr->bank = &ncr9x_bank_blizzard;
-       } else if (ncr == &ncr_fastlane_scsi[0]) {
-               ncr->bank = &ncr_bank_fastlane;
-               ncr->board_mask = FASTLANE_BOARD_SIZE - 1;
-               ncr->irq_func = set_irq2_fastlane;
-       } else if (ncr == &ncr_fastlane_scsi[1]) {
-               ncr->bank = &ncr_bank_fastlane_2;
-               ncr->board_mask = FASTLANE_BOARD_SIZE - 1;
-               ncr->irq_func = set_irq2_fastlane;
-       } else if (ncr == &ncr_oktagon2008_scsi[0]) {
-               ncr->bank = &ncr_bank_oktagon;
-               ncr->board_mask = OKTAGON_BOARD_SIZE - 1;
-               ncr->irq_func = set_irq2_oktagon;
-       } else if (ncr == &ncr_oktagon2008_scsi[1]) {
-               ncr->bank = &ncr_bank_oktagon_2;
-               ncr->board_mask = OKTAGON_BOARD_SIZE - 1;
-               ncr->irq_func = set_irq2_oktagon;
-       } else if (ncr == &ncr_dkb1200_scsi) {
-               ncr->bank = &ncr_bank_dkb;
-               ncr->board_mask = DKB_BOARD_SIZE - 1;
-               ncr->irq_func = set_irq2_dkb1200;
-       } else if (ncr == &ncr_masoboshi_scsi[0] || ncr == &ncr_masoboshi_scsi[1]) {
-               ncr->irq_func = set_irq2_masoboshi;
-       }
-       if (ncr->bank)
-               ncr->name = ncr->bank->name;
 }
 
 void ncr9x_reset(void)
 {
-       for (int i = 0; ncrs[i]; i++) {
-               ncr9x_reset_board(ncrs[i]);
-               ncrs[i]->configured = 0;
-               ncrs[i]->enabled = false;
+       for (int i = 0; ncr_units[i]; i++) {
+               ncr9x_reset_board(ncr_units[i]);
+               ncr_units[i]->enabled = false;
        }
-       ncr_blizzard_scsi.configured = -1;
-       ncr_blizzard_scsi.enabled = true;
 }
 
-addrbank *ncr_fastlane_autoconfig_init(int devnum)
+addrbank *ncr_fastlane_autoconfig_init(struct romconfig *rc)
 {
        int roms[2];
-       struct ncr9x_state *ncr = &ncr_fastlane_scsi[devnum];
+       struct ncr9x_state *ncr = getscsi(rc);
 
        xfree(ncr->rom);
        ncr->rom = NULL;
 
-       if (!ncr->enabled && devnum > 0)
+       if (!ncr)
                return &expamem_null;
 
        roms[0] = 102;
@@ -1217,16 +1307,15 @@ addrbank *ncr_fastlane_autoconfig_init(int devnum)
        ncr->rom_end = FASTLANE_ROM_SIZE * 4;
        ncr->io_start = 0;
        ncr->io_end = 0;
+       ncr->bank = &ncr9x_bank_generic;
 
-       ncr9x_init ();
        ncr9x_reset_board(ncr);
 
-       struct zfile *z = read_device_rom(&currprefs, devnum, ROMTYPE_FASTLANE, roms);
+       struct zfile *z = read_device_from_romconfig(rc, roms);
        ncr->rom = xcalloc (uae_u8, FASTLANE_ROM_SIZE * 4);
        if (z) {
                // memory board at offset 0x100
                int autoconfig_offset = 0;
-               write_log (_T("%s BOOT ROM '%s'\n"), ncr->name, zfile_getname (z));
                memset(ncr->rom, 0xff, FASTLANE_ROM_SIZE * 4);
                for (int i = 0; i < FASTLANE_ROM_SIZE; i++) {
                        int ia = i - autoconfig_offset;
@@ -1243,7 +1332,7 @@ addrbank *ncr_fastlane_autoconfig_init(int devnum)
                zfile_fclose(z);
        }
 
-       return ncr == &ncr_fastlane_scsi[0] ? &ncr_bank_fastlane : &ncr_bank_fastlane_2;
+       return ncr->bank;
 }
 
 static const uae_u8 oktagon_autoconfig[16] = {
@@ -1256,20 +1345,19 @@ static const uae_u8 oktagon_eeprom[16] =
        0x0b, 0xf4, 0x3f, 0x0a, 0xff, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0xaf, 0xff
 };
 
-addrbank *ncr_oktagon_autoconfig_init(int devnum)
+addrbank *ncr_oktagon_autoconfig_init(struct romconfig *rc)
 {
        int roms[2];
-       struct ncr9x_state *ncr = &ncr_oktagon2008_scsi[devnum];
-       struct romconfig *rc = NULL;
+       struct ncr9x_state *ncr = getscsi(rc);
+
+       if (!ncr)
+               return &expamem_null;
 
        xfree(ncr->rom);
        ncr->rom = NULL;
        eeprom_free(ncr->eeprom);
        ncr->eeprom = NULL;
 
-       if (!ncr->enabled && devnum > 0)
-               return &expamem_null;
-
        roms[0] = 103;
        roms[1] = -1;
 
@@ -1281,6 +1369,7 @@ addrbank *ncr_oktagon_autoconfig_init(int devnum)
        ncr->io_start = 0x2000;
        ncr->io_end = ncr->rom_end;
        ncr->romisoddonly = true;
+       ncr->bank = &ncr9x_bank_generic;
 
        memset(ncr->eeprom_data, 0xff, OKTAGON_EEPROM_SIZE);
        memcpy(ncr->eeprom_data + 0x100, oktagon_eeprom, 16);
@@ -1288,15 +1377,12 @@ addrbank *ncr_oktagon_autoconfig_init(int devnum)
        ncr->rom = xcalloc (uae_u8, OKTAGON_ROM_SIZE * 6);
        memset(ncr->rom, 0xff, OKTAGON_ROM_SIZE * 6);
 
-       ncr9x_init ();
        ncr9x_reset_board(ncr);
 
-       rc = get_device_romconfig(&currprefs, devnum, ROMTYPE_OKTAGON);
-       if (rc && !rc->autoboot_disabled) {
-               struct zfile *z = read_device_rom(&currprefs, devnum, ROMTYPE_OKTAGON, roms);
+       if (!rc->autoboot_disabled) {
+               struct zfile *z = read_device_from_romconfig(rc, roms);
                if (z) {
                        // memory board at offset 0x100
-                       write_log (_T("%s BOOT ROM '%s'\n"), ncr->name, zfile_getname (z));
                        memset(ncr->rom, 0xff, OKTAGON_ROM_SIZE * 4);
                        for (int i = 0; i < 0x1000 / 2; i++) {
                                uae_u8 b;
@@ -1320,14 +1406,17 @@ addrbank *ncr_oktagon_autoconfig_init(int devnum)
                ew(ncr, i * 4, b);
        }
 
-       return ncr == &ncr_oktagon2008_scsi[0] ? &ncr_bank_oktagon : &ncr_bank_oktagon_2;
+       return ncr->bank;
 }
 
 
-addrbank *ncr_dkb_autoconfig_init(int devnum)
+addrbank *ncr_dkb_autoconfig_init(struct romconfig *rc)
 {
        int roms[2];
-       struct ncr9x_state *ncr = &ncr_dkb1200_scsi;
+       struct ncr9x_state *ncr = getscsi(rc);
+
+       if (!ncr)
+               return &expamem_null;
 
        xfree(ncr->rom);
        ncr->rom = NULL;
@@ -1342,16 +1431,16 @@ addrbank *ncr_dkb_autoconfig_init(int devnum)
        ncr->rom_end = DKB_ROM_SIZE * 2;
        ncr->io_start = 0x10000;
        ncr->io_end = 0x20000;
+       ncr->bank = &ncr9x_bank_generic;
+       ncr->board_mask = 131071;
 
-       ncr9x_init ();
        ncr9x_reset_board(ncr);
 
-       struct zfile *z = read_device_rom(&currprefs, devnum, ROMTYPE_CPUBOARD, roms);
+       struct zfile *z = read_device_from_romconfig(rc, roms);
        ncr->rom = xcalloc (uae_u8, DKB_ROM_SIZE * 2);
        if (z) {
                // memory board at offset 0x100
                int i;
-               write_log (_T("%s BOOT ROM '%s'\n"), ncr->name, zfile_getname (z));
                memset(ncr->rom, 0xff, DKB_ROM_SIZE * 2);
 
                zfile_fseek(z, 0, SEEK_SET);
@@ -1370,160 +1459,136 @@ addrbank *ncr_dkb_autoconfig_init(int devnum)
                zfile_fclose(z);
        }
 
-       return &ncr_bank_dkb;
+       return ncr->bank;
 }
 
 
-void ncr_masoboshi_autoconfig_init(int devnum)
+void ncr_masoboshi_autoconfig_init(struct romconfig *rc)
 {
-       struct ncr9x_state *ncr = &ncr_masoboshi_scsi[devnum];
+       struct ncr9x_state *ncr = getscsi(rc);
 
-       if (!ncr->enabled && devnum > 0)
+       if (!ncr)
                return;
 
        ncr->enabled = true;
 
-       ncr9x_init ();
        ncr9x_reset_board(ncr);
 }
 
-
-static void freescsi_hdf(struct scsi_data *sd)
-{
-       if (!sd)
-               return;
-       hdf_hd_close(sd->hfd);
-       scsi_free(sd);
-}
-
-static void freescsi(SCSIDevice *scsi)
-{
-       if (scsi) {
-               freescsi_hdf((struct scsi_data*)scsi->handle);
-               xfree(scsi);
-       }
-}
-
-static void ncr9x_free2(struct ncr9x_state *ncr)
+static void ncr9x_esp_scsi_init(struct ncr9x_state *ncr, ESPDMAMemoryReadWriteFunc read, ESPDMAMemoryReadWriteFunc write, void (*irq_func)(struct ncr9x_state*))
 {
-       for (int ch = 0; ch < 8; ch++) {
-               freescsi(ncr->scsid[ch]);
-               ncr->scsid[ch] = NULL;
-       }
+       ncr->board_mask = 0xffff;
+       ncr->irq_func = irq_func ? irq_func : set_irq2;
+       if (!ncr->devobject.lsistate)
+               esp_scsi_init(&ncr->devobject, read, write);
+       esp_scsi_reset(&ncr->devobject, ncr);
 }
 
 void ncr9x_free(void)
 {
-       for (int i = 0; ncrs[i]; i++) {
-               ncr9x_free2(ncrs[i]);
+       for (int i = 0; ncr_units[i]; i++) {
+               ncr9x_free2(ncr_units[i]);
        }
 }
 
 void ncr9x_init(void)
 {
-       if (!ncr_blizzard_scsi.devobject.lsistate) {
-               if (currprefs.cpuboard_type == BOARD_CYBERSTORM && (currprefs.cpuboard_subtype == BOARD_CYBERSTORM_SUB_MK1 || currprefs.cpuboard_subtype == BOARD_CYBERSTORM_SUB_MK2)) {
-                       esp_scsi_init(&ncr_blizzard_scsi.devobject, cyberstorm_mk1_mk2_dma_read, cyberstorm_mk1_mk2_dma_write);
-               } else {
-                       esp_scsi_init(&ncr_blizzard_scsi.devobject, blizzard_dma_read, blizzard_dma_write);
-               }
-               esp_scsi_init(&ncr_fastlane_scsi[0].devobject, fastlane_dma_read, fastlane_dma_write);
-               esp_scsi_init(&ncr_fastlane_scsi[1].devobject, fastlane_dma_read, fastlane_dma_write);
-               esp_scsi_init(&ncr_oktagon2008_scsi[0].devobject, fake2_dma_read, fake2_dma_write);
-               esp_scsi_init(&ncr_oktagon2008_scsi[1].devobject, fake2_dma_read, fake2_dma_write);
-               esp_scsi_init(&ncr_dkb1200_scsi.devobject, fake_dma_read, fake_dma_write);
-               esp_scsi_init(&ncr_masoboshi_scsi[0].devobject, fake2_dma_read, fake2_dma_write);
-               esp_scsi_init(&ncr_masoboshi_scsi[1].devobject, fake2_dma_read, fake2_dma_write);
-       }
 }
 
-static int add_ncr_scsi_hd(struct ncr9x_state *ncr, int ch, struct hd_hardfiledata *hfd, struct uaedev_config_info *ci, int scsi_level)
+static void add_ncr_scsi_hd(struct ncr9x_state *ncr, int ch, struct hd_hardfiledata *hfd, struct uaedev_config_info *ci, int scsi_level)
 {
-       struct scsi_data *handle;
+       struct scsi_data *handle = NULL;
+
        freescsi(ncr->scsid[ch]);
        ncr->scsid[ch] = NULL;
-       if (!hfd) {
-               hfd = xcalloc(struct hd_hardfiledata, 1);
-               memcpy(&hfd->hfd.ci, ci, sizeof(struct uaedev_config_info));
-       }
-       if (!hdf_hd_open(hfd))
-               return 0;
-       hfd->ansi_version = scsi_level;
-       handle = scsi_alloc_hd(ch, hfd);
-       if (!handle)
-               return 0;
+       if (!add_scsi_hd(&handle, ch, hfd, ci, scsi_level))
+               return;
        handle->privdata = ncr;
        ncr->scsid[ch] = xcalloc(SCSIDevice, 1);
        ncr->scsid[ch]->handle = handle;
        ncr->enabled = true;
-       return ncr->scsid[ch] ? 1 : 0;
 }
 
-
-static int add_ncr_scsi_cd(struct ncr9x_state *ncr, int ch, int unitnum)
+static void add_ncr_scsi_cd(struct ncr9x_state *ncr, int ch, int unitnum)
 {
-       struct scsi_data *handle;
-       device_func_init(0);
+       struct scsi_data *handle = NULL;
+
        freescsi(ncr->scsid[ch]);
        ncr->scsid[ch] = NULL;
-       handle = scsi_alloc_cd(ch, unitnum, false);
-       if (!handle)
-               return 0;
+       if (!add_scsi_cd(&handle, ch, unitnum))
+               return;
        handle->privdata = ncr;
        ncr->scsid[ch] = xcalloc(SCSIDevice, 1);
        ncr->scsid[ch]->handle = handle;
        ncr->enabled = true;
-       return ncr->scsid[ch] ? 1 : 0;
 }
 
-static int add_ncr_scsi_tape(struct ncr9x_state *ncr, int ch, const TCHAR *tape_directory, bool readonly)
+static void add_ncr_scsi_tape(struct ncr9x_state *ncr, int ch, const TCHAR *tape_directory, bool readonly)
 {
-       struct scsi_data *handle;
+       struct scsi_data *handle = NULL;
+
        freescsi(ncr->scsid[ch]);
        ncr->scsid[ch] = NULL;
-       handle = scsi_alloc_tape(ch, tape_directory, readonly);
-       if (!handle)
-               return 0;
+       if (!add_scsi_tape(&handle, ch, tape_directory, readonly))
+               return;
        handle->privdata = ncr;
        ncr->scsid[ch] = xcalloc(SCSIDevice, 1);
        ncr->scsid[ch]->handle = handle;
        ncr->enabled = true;
-       return ncr->scsid[ch] ? 1 : 0;
 }
 
-static int ncr9x_add_scsi_unit(struct ncr9x_state *ncr, int ch, struct uaedev_config_info *ci)
+static void ncr9x_add_scsi_unit(struct ncr9x_state **ncrp, int ch, struct uaedev_config_info *ci, struct romconfig *rc)
 {
-       if (ci->type == UAEDEV_CD)
-               return add_ncr_scsi_cd (ncr, ch, ci->device_emu_unit);
-       else if (ci->type == UAEDEV_TAPE)
-               return add_ncr_scsi_tape (ncr, ch, ci->rootdir, ci->readonly);
-       else
-               return add_ncr_scsi_hd (ncr, ch, NULL, ci, 2);
+       struct ncr9x_state *ncr = allocscsi(ncrp, rc, ch);
+       if (ch >= 0 && ncr) {
+               if (ci->type == UAEDEV_CD)
+                       add_ncr_scsi_cd (ncr, ch, ci->device_emu_unit);
+               else if (ci->type == UAEDEV_TAPE)
+                       add_ncr_scsi_tape (ncr, ch, ci->rootdir, ci->readonly);
+               else if (ci->type == UAEDEV_HDF)
+                       add_ncr_scsi_hd (ncr, ch, NULL, ci, 2);
+       }
 }
 
-int cpuboard_ncr9x_add_scsi_unit(int ch, struct uaedev_config_info *ci)
+void cpuboard_ncr9x_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
 {
-       return ncr9x_add_scsi_unit(&ncr_blizzard_scsi, ch, ci);
+       ncr9x_add_scsi_unit(&ncr_blizzard_scsi, ch, ci, rc);
+       ncr_blizzard_scsi->configured = -1;
+       ncr_blizzard_scsi->enabled = true;
+       if (ISCPUBOARD(BOARD_CYBERSTORM, BOARD_CYBERSTORM_SUB_MK1) || ISCPUBOARD(BOARD_CYBERSTORM, BOARD_CYBERSTORM_SUB_MK2)) {
+               ncr9x_esp_scsi_init(ncr_blizzard_scsi, cyberstorm_mk1_mk2_dma_read, cyberstorm_mk1_mk2_dma_write, NULL);
+       } else {
+               ncr9x_esp_scsi_init(ncr_blizzard_scsi, blizzard_dma_read, blizzard_dma_write, NULL);
+       }
+       if (ISCPUBOARD(BOARD_CYBERSTORM, BOARD_CYBERSTORM_SUB_MK1))
+               ncr_blizzard_scsi->board_mask = 0xffff;
+       else
+               ncr_blizzard_scsi->board_mask = 0x1ffff;
 }
 
-int cpuboard_dkb_add_scsi_unit(int ch, struct uaedev_config_info *ci)
+void cpuboard_dkb_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
 {
-       return ncr9x_add_scsi_unit(&ncr_dkb1200_scsi, ch, ci);
+       ncr9x_add_scsi_unit(&ncr_dkb1200_scsi, ch, ci, rc);
+       ncr9x_esp_scsi_init(ncr_dkb1200_scsi, fake_dma_read, fake_dma_write, set_irq2_dkb1200);
 }
 
-int fastlane_add_scsi_unit (int ch, struct uaedev_config_info *ci)
+void fastlane_add_scsi_unit (int ch, struct uaedev_config_info *ci, struct romconfig *rc)
 {
-       return ncr9x_add_scsi_unit(&ncr_fastlane_scsi[ci->controller_type_unit], ch, ci);
+       ncr9x_add_scsi_unit(&ncr_fastlane_scsi[ci->controller_type_unit], ch, ci, rc);
+       ncr9x_esp_scsi_init(ncr_fastlane_scsi[ci->controller_type_unit], fastlane_dma_read, fastlane_dma_write, set_irq2_fastlane);
+       ncr_fastlane_scsi[ci->controller_type_unit]->board_mask = 32 * 1024 * 1024 - 1;
 }
 
-int oktagon_add_scsi_unit (int ch, struct uaedev_config_info *ci)
+void oktagon_add_scsi_unit (int ch, struct uaedev_config_info *ci, struct romconfig *rc)
 {
-       return ncr9x_add_scsi_unit(&ncr_oktagon2008_scsi[ci->controller_type_unit], ch, ci);
+       ncr9x_add_scsi_unit(&ncr_oktagon2008_scsi[ci->controller_type_unit], ch, ci, rc);
+       ncr9x_esp_scsi_init(ncr_oktagon2008_scsi[ci->controller_type_unit], fake2_dma_read, fake2_dma_write, set_irq2_oktagon);
 }
 
-int masoboshi_add_scsi_unit (int ch, struct uaedev_config_info *ci)
+void masoboshi_add_scsi_unit (int ch, struct uaedev_config_info *ci, struct romconfig *rc)
 {
-       return ncr9x_add_scsi_unit(&ncr_masoboshi_scsi[ci->controller_type_unit], ch, ci);
+       ncr9x_add_scsi_unit(&ncr_masoboshi_scsi[ci->controller_type_unit], ch, ci, rc);
+       ncr9x_esp_scsi_init(ncr_masoboshi_scsi[ci->controller_type_unit], fake2_dma_read, fake2_dma_write, set_irq2_masoboshi);
 }
 
 
index 5f9ef46c6f861366db45db22151d128ac5dc39f2..970986786cab4950de24bb19808d4995e952d001 100644 (file)
@@ -11,7 +11,7 @@
 
 #ifdef NCR
 
-#define NCR_DEBUG 0
+#define NCR_DEBUG 2
 
 #include "options.h"
 #include "uae.h"
@@ -28,6 +28,7 @@
 #include "qemuvga/qemuuaeglue.h"
 #include "qemuvga/queue.h"
 #include "qemuvga/scsi/scsi.h"
+#include "autoconf.h"
 #include "gui.h"
 
 #define BOARD_SIZE 16777216
@@ -54,7 +55,6 @@
 struct ncr_state
 {
        bool newncr;
-       const TCHAR *name;
        DeviceState devobject;
        SCSIDevice *scsid[8];
        SCSIBus scsibus;
@@ -64,6 +64,7 @@ struct ncr_state
        uae_u8 acmemory[128];
        uae_u32 expamem_hi;
        uae_u32 expamem_lo;
+       uaecptr baseaddress;
        int configured;
        bool enabled;
        int rom_start, rom_end, rom_offset;
@@ -71,35 +72,101 @@ struct ncr_state
        addrbank *bank;
        bool irq;
        void (*irq_func)(int);
+       struct romconfig *rc;
 };
 
-static struct ncr_state ncr_a4091;
-static struct ncr_state ncr_a4091_2;
-static struct ncr_state ncr_a4000t;
-static struct ncr_state ncr_we;
-static struct ncr_state ncr_cpuboard;
+#define MAX_NCR_UNITS 10
+static struct ncr_state *ncr_units[MAX_NCR_UNITS + 1];
 
-static struct ncr_state ncr_cs;
-static struct ncr_state ncr_bppc;
+static void freescsi (SCSIDevice *scsi)
+{
+       if (scsi) {
+               free_scsi((struct scsi_data*)scsi->handle);
+               xfree (scsi);
+       }
+}
 
-static struct ncr_state *ncrs[] =
+static void ncr_free2(struct ncr_state **ncr)
 {
-       &ncr_a4091,
-       &ncr_a4091_2,
-       &ncr_a4000t,
-       &ncr_we,
-       &ncr_cpuboard,
-       &ncr_bppc,
-       NULL
-};
+       if (*ncr) {
+               for (int ch = 0; ch < 8; ch++) {
+                       freescsi ((*ncr)->scsid[ch]);
+                       (*ncr)->scsid[ch] = NULL;
+               }
+       }
+       xfree(*ncr);
+       *ncr = NULL;
+}
 
-static struct ncr_state *ncra4091[] =
+static void freencrunit(struct ncr_state **ncr)
 {
-       &ncr_a4091,
-       &ncr_a4091_2
-};
+       if (!ncr)
+               return;
+       for (int i = 0; i < MAX_NCR_UNITS; i++) {
+               if (ncr_units[i] == *ncr) {
+                       ncr_units[i] = NULL;
+               }
+       }
+       ncr_free2(ncr);
+}
+
+static struct ncr_state *allocscsi(struct ncr_state **ncr, struct romconfig *rc, int ch)
+{
+       struct ncr_state *scsi;
+
+       if (ch < 0) {
+               freencrunit(ncr);
+       }
+       if ((*ncr) == NULL) {
+               scsi = xcalloc(struct ncr_state, 1);
+               for (int i = 0; i < MAX_NCR_UNITS; i++) {
+                       if (ncr_units[i] == NULL) {
+                               ncr_units[i] = scsi;
+                               if (rc)
+                                       rc->unitdata = scsi;
+                               scsi->rc = rc;
+                               if (ncr)
+                                       *ncr = scsi;
+                               return scsi;
+                       }
+               }
+       }
+       return *ncr;
+}
+
+static struct ncr_state *getscsi(struct romconfig *rc)
+{
+       for (int i = 0; i < MAX_NCR_UNITS; i++) {
+               if (ncr_units[i]) {
+                       struct ncr_state *ncr = ncr_units[i];
+                       if (ncr->rc == rc) {
+                               ncr->rc = NULL;
+                               return ncr;
+                       }
+               }
+       }
+       return NULL;
+}
+
+static struct ncr_state *getscsiboard(uaecptr addr)
+{
+       for (int i = 0; ncr_units[i]; i++) {
+               if (!ncr_units[i]->baseaddress && !ncr_units[i]->configured)
+                       return ncr_units[i];
+               if ((addr & ~ncr_units[i]->board_mask) == ncr_units[i]->baseaddress)
+                       return ncr_units[i];
+       }
+       return NULL;
+}
 
-extern void cyberstorm_irq(int);
+static struct ncr_state *ncr_cs;
+static struct ncr_state *ncr_bppc;
+static struct ncr_state *ncr_cpuboard;
+static struct ncr_state *ncr_we;
+static struct ncr_state *ncr_a4000t;
+static struct ncr_state *ncra4091[MAX_DUPLICATE_EXPANSION_BOARDS];
+
+extern void cyberstorm_mk3_ppc_irq(int);
 extern void blizzardppc_irq(int);
 
 static void set_irq2(int level)
@@ -110,12 +177,12 @@ static void set_irq2(int level)
 
 void ncr_rethink(void)
 {
-       for (int i = 0; ncrs[i]; i++) {
-               if (ncrs[i]->irq)
+       for (int i = 0; ncr_units[i]; i++) {
+               if (ncr_units[i] != ncr_cs && ncr_units[i]->irq)
                        INTREQ_0(0x8000 | 0x0008);
        }
-       if (ncr_cs.irq)
-               cyberstorm_irq(1);
+       if (ncr_cs && ncr_cs->irq)
+               cyberstorm_mk3_ppc_irq(1);
 }
 
 /* 720+ */
@@ -334,7 +401,7 @@ static void ncr710_io_bput(struct ncr_state *ncr, uaecptr addr, uae_u32 val)
 }
 void cpuboard_ncr710_io_bput(uaecptr addr, uae_u32 v)
 {
-       ncr710_io_bput(&ncr_cpuboard, addr, v);
+       ncr710_io_bput(ncr_cpuboard, addr, v);
 }
 
 static void ncr_bput2 (struct ncr_state *ncr, uaecptr addr, uae_u32 val)
@@ -363,7 +430,7 @@ static uae_u32 ncr710_io_bget(struct ncr_state *ncr, uaecptr addr)
 }
 uae_u32 cpuboard_ncr710_io_bget(uaecptr addr)
 {
-       return ncr710_io_bget(&ncr_cpuboard, addr);
+       return ncr710_io_bget(ncr_cpuboard, addr);
 }
 
 static uae_u32 ncr_bget2 (struct ncr_state *ncr, uaecptr addr)
@@ -390,7 +457,7 @@ static uae_u32 REGPARAM2 ncr_lget (struct ncr_state *ncr, uaecptr addr)
        special_mem |= S_READ;
 #endif
        addr &= ncr->board_mask;
-       if (ncr == &ncr_we) {
+       if (ncr == ncr_we) {
                addr &= ~0x80;
                v = (ncr_bget2(ncr, addr + 3) << 0) | (ncr_bget2(ncr, addr + 2) << 8) |
                        (ncr_bget2(ncr, addr + 1) << 16) | (ncr_bget2(ncr, addr + 0) << 24);
@@ -439,7 +506,7 @@ static void REGPARAM2 ncr_lput (struct ncr_state *ncr, uaecptr addr, uae_u32 l)
        special_mem |= S_WRITE;
 #endif
        addr &= ncr->board_mask;
-       if (ncr == &ncr_we) {
+       if (ncr == ncr_we) {
                addr &= ~0x80;
                ncr_bput2(ncr, addr + 3, l >> 0);
                ncr_bput2(ncr, addr + 2, l >> 8);
@@ -460,24 +527,6 @@ static void REGPARAM2 ncr_lput (struct ncr_state *ncr, uaecptr addr, uae_u32 l)
        }
 }
 
-DECLARE_MEMORY_FUNCTIONS(ncr4)
-
-static addrbank ncr_bank_a4091 = {
-       ncr4_lget, ncr4_wget, ncr4_bget,
-       ncr4_lput, ncr4_wput, ncr4_bput,
-       default_xlate, default_check, NULL, NULL, _T("A4091"),
-       dummy_lgeti, dummy_wgeti, ABFLAG_IO | ABFLAG_SAFE | ABFLAG_THREADSAFE
-};
-
-DECLARE_MEMORY_FUNCTIONS(ncr42)
-
-static addrbank ncr_bank_a4091_2 = {
-       ncr42_lget, ncr42_wget, ncr42_bget,
-       ncr42_lput, ncr42_wput, ncr42_bput,
-       default_xlate, default_check, NULL, NULL, _T("A4091 #2"),
-       dummy_lgeti, dummy_wgeti, ABFLAG_IO | ABFLAG_SAFE | ABFLAG_THREADSAFE
-};
-
 static void REGPARAM2 ncr_wput (struct ncr_state *ncr, uaecptr addr, uae_u32 w)
 {
 #ifdef JIT
@@ -492,6 +541,7 @@ static void REGPARAM2 ncr_wput (struct ncr_state *ncr, uaecptr addr, uae_u32 w)
                        case 0x44:
                        map_banks (ncr->bank, expamem_z3_pointer >> 16, BOARD_SIZE >> 16, 0);
                        ncr->board_mask = 0x00ffffff;
+                       ncr->baseaddress = expamem_z3_pointer;
                        ncr->configured = 1;
                        expamem_next (ncr->bank, NULL);
                        break;
@@ -528,145 +578,77 @@ static void REGPARAM2 ncr_bput (struct ncr_state *ncr, uaecptr addr, uae_u32 b)
 
 void ncr710_io_bput_a4000t(uaecptr addr, uae_u32 v)
 {
-       ncr710_io_bput(&ncr_a4000t, addr, v);
+       ncr710_io_bput(ncr_a4000t, addr, v);
 }
 uae_u32 ncr710_io_bget_a4000t(uaecptr addr)
 {
-       return ncr710_io_bget(&ncr_a4000t, addr);
+       return ncr710_io_bget(ncr_a4000t, addr);
 }
 
-static void REGPARAM2 ncr4_bput (uaecptr addr, uae_u32 b)
+static void REGPARAM2 ncr_generic_bput (uaecptr addr, uae_u32 b)
 {
-       ncr_bput(&ncr_a4091, addr, b);
+       struct ncr_state *ncr = getscsiboard(addr);
+       if (ncr)
+               ncr_bput(ncr, addr, b);
 }
-static void REGPARAM2 ncr4_wput (uaecptr addr, uae_u32 b)
+static void REGPARAM2 ncr_generic_wput (uaecptr addr, uae_u32 b)
 {
-       ncr_wput(&ncr_a4091, addr, b);
+       struct ncr_state *ncr = getscsiboard(addr);
+       if (ncr)
+               ncr_wput(ncr, addr, b);
 }
-static void REGPARAM2 ncr4_lput (uaecptr addr, uae_u32 b)
+static void REGPARAM2 ncr_generic_lput (uaecptr addr, uae_u32 b)
 {
-       ncr_lput(&ncr_a4091, addr, b);
+       struct ncr_state *ncr = getscsiboard(addr);
+       if (ncr)
+               ncr_lput(ncr, addr, b);
 }
-static uae_u32 REGPARAM2 ncr4_bget (uaecptr addr)
+static uae_u32 REGPARAM2 ncr_generic_bget (uaecptr addr)
 {
-       return ncr_bget(&ncr_a4091, addr);
-}
-static uae_u32 REGPARAM2 ncr4_wget (uaecptr addr)
-{
-       return ncr_wget(&ncr_a4091, addr);
-}
-static uae_u32 REGPARAM2 ncr4_lget (uaecptr addr)
-{
-       return ncr_lget(&ncr_a4091, addr);
-}
-
-static void REGPARAM2 ncr42_bput (uaecptr addr, uae_u32 b)
-{
-       ncr_bput(&ncr_a4091_2, addr, b);
-}
-static void REGPARAM2 ncr42_wput (uaecptr addr, uae_u32 b)
-{
-       ncr_wput(&ncr_a4091_2, addr, b);
-}
-static void REGPARAM2 ncr42_lput (uaecptr addr, uae_u32 b)
-{
-       ncr_lput(&ncr_a4091_2, addr, b);
-}
-static uae_u32 REGPARAM2 ncr42_bget (uaecptr addr)
-{
-       return ncr_bget(&ncr_a4091_2, addr);
-}
-static uae_u32 REGPARAM2 ncr42_wget (uaecptr addr)
-{
-       return ncr_wget(&ncr_a4091_2, addr);
-}
-static uae_u32 REGPARAM2 ncr42_lget (uaecptr addr)
-{
-       return ncr_lget(&ncr_a4091_2, addr);
-}
-
-static void REGPARAM2 we_bput (uaecptr addr, uae_u32 b)
-{
-       ncr_bput(&ncr_we, addr, b);
-}
-static void REGPARAM2 we_wput (uaecptr addr, uae_u32 b)
-{
-       ncr_wput(&ncr_we, addr, b);
-}
-static void REGPARAM2 we_lput (uaecptr addr, uae_u32 b)
-{
-       ncr_lput(&ncr_we, addr, b);
-}
-static uae_u32 REGPARAM2 we_bget (uaecptr addr)
-{
-       return ncr_bget(&ncr_we, addr);
+       struct ncr_state *ncr = getscsiboard(addr);
+       if (ncr)
+               return ncr_bget(ncr, addr);
+       return 0;
 }
-static uae_u32 REGPARAM2 we_wget (uaecptr addr)
+static uae_u32 REGPARAM2 ncr_generic_wget (uaecptr addr)
 {
-       return ncr_wget(&ncr_we, addr);
+       struct ncr_state *ncr = getscsiboard(addr);
+       if (ncr)
+               return ncr_wget(ncr, addr);
+       return 0;
 }
-static uae_u32 REGPARAM2 we_lget (uaecptr addr)
+static uae_u32 REGPARAM2 ncr_generic_lget (uaecptr addr)
 {
-       return ncr_lget(&ncr_we, addr);
+       struct ncr_state *ncr = getscsiboard(addr);
+       if (ncr)
+               return ncr_lget(ncr, addr);
+       return 0;
 }
 
 static void REGPARAM2 cs_bput(uaecptr addr, uae_u32 b)
 {
-       ncr_bput(&ncr_cs, addr, b);
+       ncr_bput(ncr_cs, addr, b);
 }
 static void REGPARAM2 cs_wput(uaecptr addr, uae_u32 b)
 {
-       ncr_wput(&ncr_cs, addr, b);
+       ncr_wput(ncr_cs, addr, b);
 }
 static void REGPARAM2 cs_lput(uaecptr addr, uae_u32 b)
 {
-       ncr_lput(&ncr_cs, addr, b);
+       ncr_lput(ncr_cs, addr, b);
 }
 static uae_u32 REGPARAM2 cs_bget(uaecptr addr)
 {
-       return ncr_bget(&ncr_cs, addr);
+       return ncr_bget(ncr_cs, addr);
 }
 static uae_u32 REGPARAM2 cs_wget(uaecptr addr)
 {
-       return ncr_wget(&ncr_cs, addr);
+       return ncr_wget(ncr_cs, addr);
 }
 static uae_u32 REGPARAM2 cs_lget(uaecptr addr)
 {
-       return ncr_lget(&ncr_cs, addr);
-}
-
-
-static void REGPARAM2 bppc_bput(uaecptr addr, uae_u32 b)
-{
-       ncr_bput(&ncr_bppc, addr, b);
-}
-static void REGPARAM2 bppc_wput(uaecptr addr, uae_u32 b)
-{
-       ncr_wput(&ncr_bppc, addr, b);
-}
-static void REGPARAM2 bppc_lput(uaecptr addr, uae_u32 b)
-{
-       ncr_lput(&ncr_bppc, addr, b);
-}
-static uae_u32 REGPARAM2 bppc_bget(uaecptr addr)
-{
-       return ncr_bget(&ncr_bppc, addr);
+       return ncr_lget(ncr_cs, addr);
 }
-static uae_u32 REGPARAM2 bppc_wget(uaecptr addr)
-{
-       return ncr_wget(&ncr_bppc, addr);
-}
-static uae_u32 REGPARAM2 bppc_lget(uaecptr addr)
-{
-       return ncr_lget(&ncr_bppc, addr);
-}
-
-static addrbank ncr_bank_warpengine = {
-       we_lget, we_wget, we_bget,
-       we_lput, we_wput, we_bput,
-       default_xlate, default_check, NULL, NULL, _T("Warp Engine SCSI"),
-       dummy_lgeti, dummy_wgeti, ABFLAG_IO | ABFLAG_THREADSAFE
-};
 
 static addrbank ncr_bank_cs_scsi_ram = {
        cs_lget, cs_wget, cs_bget,
@@ -701,15 +683,13 @@ addrbank ncr_bank_cyberstorm = {
        sub_bank_lgeti, sub_bank_wgeti, ABFLAG_IO | ABFLAG_THREADSAFE, ncr_sub_bank_cs
 };
 
-addrbank ncr_bank_blizzardppc = {
-       bppc_lget, bppc_wget, bppc_bget,
-       bppc_lput, bppc_wput, bppc_bput,
-       default_xlate, default_check, NULL, NULL, _T("Blizzard PPC SCSI"),
+addrbank ncr_bank_generic = {
+       ncr_generic_lget, ncr_generic_wget, ncr_generic_bget,
+       ncr_generic_lput, ncr_generic_wput, ncr_generic_bput,
+       default_xlate, default_check, NULL, NULL, _T("NCR53C700/800"),
        dummy_lgeti, dummy_wgeti, ABFLAG_IO | ABFLAG_THREADSAFE
 };
 
-
-
 static void ew (struct ncr_state *ncr, int addr, uae_u8 value)
 {
        if (addr == 00 || addr == 02 || addr == 0x40 || addr == 0x42) {
@@ -721,63 +701,31 @@ static void ew (struct ncr_state *ncr, int addr, uae_u8 value)
        }
 }
 
-void ncr_init(void)
-{
-       ncr_cs.newncr = true;
-       if (!ncr_cs.devobject.lsistate)
-               lsi_scsi_init(&ncr_cs.devobject);
-       ncr_cs.ramsize = CYBERSTORM_SCSI_RAM_SIZE;
-}
-
-void ncr710_init (void)
+static void ncr_init_board(struct ncr_state *ncr)
 {
-       for (int i = 0; ncrs[i]; i++) {
-               ncrs[i]->newncr = false;
-               if (!ncrs[i]->devobject.lsistate)
-                       lsi710_scsi_init (&ncrs[i]->devobject);
+       if (!ncr)
+               return;
+       if (!ncr->devobject.lsistate) {
+               if (ncr->newncr)
+                       lsi_scsi_init(&ncr->devobject);
+               else
+                       lsi710_scsi_init (&ncr->devobject);
        }
-}
-
-static void ncr_reset_board(struct ncr_state *ncr)
-{
-       ncr->configured = 0;
-       ncr->board_mask = 0xffff;
-       ncr->irq = false;
-       if (ncr->devobject.lsistate)
+       if (ncr->newncr)
                lsi_scsi_reset(&ncr->devobject, ncr);
-       ncr->bank = &ncr_bank_cyberstorm;
-       ncr->irq_func = cyberstorm_irq;
+       else
+               lsi710_scsi_reset (&ncr->devobject, ncr);
+       ncr->board_mask = 0xffff;
+       ncr->irq_func = set_irq2;
+       ncr->bank = &ncr_bank_generic;
+       ncr->configured = 0;
 }
 
-static void ncr710_reset_board (struct ncr_state *ncr)
+static void ncr_reset_board (struct ncr_state *ncr)
 {
-       ncr->configured = 0;
-       ncr->board_mask = 0xffff;
+       if (!ncr)
+               return;
        ncr->irq = false;
-       ncr->irq_func = set_irq2;
-       if (ncr->devobject.lsistate)
-               lsi710_scsi_reset (&ncr->devobject, ncr);
-       if (ncr == &ncr_a4000t) {
-               ncr->name = _T("A4000T NCR SCSI");
-               ncr->bank = NULL;
-       }
-       if (ncr == &ncr_a4091) {
-               ncr->name = _T("A4091 SCSI");
-               ncr->bank = &ncr_bank_a4091;
-       }
-       if (ncr == &ncr_a4091_2) {
-               ncr->name = _T("A4091 SCSI #2");
-               ncr->bank = &ncr_bank_a4091_2;
-       }
-       if (ncr == &ncr_we) {
-               ncr->name = _T("Warp Engine SCSI");
-               ncr->bank = &ncr_bank_warpengine;
-       }
-       if (ncr == &ncr_bppc) {
-               ncr->name = _T("Blizzard PPC SCSI");
-               ncr->bank = &ncr_bank_blizzardppc;
-               ncr->irq_func = blizzardppc_irq;
-       }
 }
 
 static const uae_u8 warpengine_a4000_autoconfig[16] = {
@@ -785,12 +733,15 @@ static const uae_u8 warpengine_a4000_autoconfig[16] = {
 };
 #define WARP_ENGINE_ROM_SIZE 32768
 
-addrbank *ncr710_warpengine_autoconfig_init(int devnum)
+addrbank *ncr710_warpengine_autoconfig_init(struct romconfig *rc)
 {
        int roms[2];
-       struct ncr_state *ncr = &ncr_we;
-       struct zfile *z = NULL;
+       struct ncr_state *ncr = getscsi(rc);
+
+       if (!ncr)
+               return &expamem_null;
 
+       ncr_we = ncr;
        xfree(ncr->rom);
        ncr->rom = NULL;
 
@@ -805,16 +756,12 @@ addrbank *ncr710_warpengine_autoconfig_init(int devnum)
        ncr->io_start = WARP_ENGINE_IO_OFFSET;
        ncr->io_end = WARP_ENGINE_IO_END;
 
-       struct romlist *rl = getromlistbyids(roms, NULL);
-       if (rl) {
-               struct romdata *rd = rl->rd;
-               z = read_rom (rd);
-       }
        for (int i = 0; i < 16; i++) {
                uae_u8 b = warpengine_a4000_autoconfig[i];
                ew(ncr, i * 4, b);
        }
        ncr->rom = xcalloc (uae_u8, WARP_ENGINE_ROM_SIZE * 4);
+       struct zfile *z = read_device_from_romconfig(rc, roms);
        if (z) {
                for (int i = 0; i < WARP_ENGINE_ROM_SIZE; i++) {
                        uae_u8 b = 0xff;
@@ -825,28 +772,24 @@ addrbank *ncr710_warpengine_autoconfig_init(int devnum)
                        ncr->rom[i * 4 + 3] = 0xff;
                }
                zfile_fclose(z);
-       } else {
-               romwarning (roms);
        }
 
-       ncr710_init ();
-       ncr710_reset_board(ncr);
+       ncr_reset_board(ncr);
 
-       return &ncr_bank_warpengine;
+       return &ncr_bank_generic;
 }
 
-addrbank *ncr710_a4091_autoconfig_init (int devnum)
+addrbank *ncr710_a4091_autoconfig_init (struct romconfig *rc)
 {
-       struct ncr_state *ncr = ncra4091[devnum];
+       struct ncr_state *ncr = getscsi(rc);
        int roms[3];
-       struct romconfig *rc = NULL;
+
+       if (!ncr)
+               return &expamem_null;
 
        xfree(ncr->rom);
        ncr->rom = NULL;
 
-       if (!ncr->enabled && devnum > 0)
-               return &expamem_null;
-
        roms[0] = 58;
        roms[1] = 57;
        roms[2] = -1;
@@ -859,12 +802,10 @@ addrbank *ncr710_a4091_autoconfig_init (int devnum)
        ncr->io_start = A4091_IO_OFFSET;
        ncr->io_end = A4091_IO_END;
 
-       ncr710_init ();
-       ncr710_reset_board(ncr);
+       ncr_reset_board(ncr);
 
-       struct zfile *z = read_device_rom(&currprefs, devnum, ROMTYPE_A4091, roms);
+       struct zfile *z = read_device_from_romconfig(rc, roms);
        if (z) {
-               write_log (_T("%s BOOT ROM '%s'\n"), ncr->name, zfile_getname (z));
                ncr->rom = xmalloc (uae_u8, A4091_ROM_SIZE * 4);
                for (int i = 0; i < A4091_ROM_SIZE; i++) {
                        uae_u8 b;
@@ -878,163 +819,129 @@ addrbank *ncr710_a4091_autoconfig_init (int devnum)
                        }
                }
                zfile_fclose(z);
-       } else {
-               romwarning (roms);
-       }
-
-       return ncr == &ncr_a4091 ? &ncr_bank_a4091 : &ncr_bank_a4091_2;
-}
-
-static void freescsi_hdf (struct scsi_data *sd)
-{
-       if (!sd)
-               return;
-       hdf_hd_close (sd->hfd);
-       scsi_free (sd);
-}
-
-static void freescsi (SCSIDevice *scsi)
-{
-       if (scsi) {
-               freescsi_hdf ((struct scsi_data*)scsi->handle);
-               xfree (scsi);
        }
-}
 
-static void ncr_free2(struct ncr_state *ncr)
-{
-       for (int ch = 0; ch < 8; ch++) {
-               freescsi (ncr->scsid[ch]);
-               ncr->scsid[ch] = NULL;
-       }
+       return &ncr_bank_generic;
 }
 
-void ncr710_free(void)
+void ncr_free(void)
 {
-       for (int i = 0; ncrs[i]; i++) {
-               ncr_free2(ncrs[i]);
+       for (int i = 0; i < MAX_NCR_UNITS; i++) {
+               ncr_free2(&ncr_units[i]);
        }
 }
 
-void ncr_free(void)
+void ncr_init(void)
 {
-       ncr_free2(&ncr_cs);
 }
 
-void ncr710_reset(void)
+void ncr_reset(void)
 {
-       for (int i = 0; ncrs[i]; i++) {
-               ncr710_reset_board(ncrs[i]);
-       }
-       if (currprefs.cs_mbdmac & 2) {
-               ncr_a4000t.configured = -1;
-               ncr_a4000t.enabled = true;
-       }
-       if (ISCPUBOARD(BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_PPC)) {
-               ncr_bppc.configured = -1;
-               ncr_bppc.enabled = true;
+       for (int i = 0; i < MAX_NCR_UNITS; i++) {
+               ncr_reset_board(ncr_units[i]);
        }
 }
 
-void ncr_reset(void)
+static void add_ncr_scsi_hd (struct ncr_state *ncr, int ch, struct hd_hardfiledata *hfd, struct uaedev_config_info *ci, int scsi_level)
 {
-       ncr_reset_board(&ncr_cs);
-       ncr_cs.configured = -1;
-       ncr_cs.enabled = true;
-}
+       struct scsi_data *handle = NULL;
 
-static int add_ncr_scsi_hd (struct ncr_state *ncr, int ch, struct hd_hardfiledata *hfd, struct uaedev_config_info *ci, int scsi_level)
-{
-       struct scsi_data *handle;
        freescsi (ncr->scsid[ch]);
        ncr->scsid[ch] = NULL;
-       if (!hfd) {
-               hfd = xcalloc (struct hd_hardfiledata, 1);
-               memcpy (&hfd->hfd.ci, ci, sizeof (struct uaedev_config_info));
-       }
-       if (!hdf_hd_open (hfd))
-               return 0;
-       hfd->ansi_version = scsi_level;
-       handle = scsi_alloc_hd (ch, hfd);
-       if (!handle)
-               return 0;
+       if (!add_scsi_hd(&handle, ch, hfd, ci, scsi_level))
+               return;
        handle->privdata = ncr;
        ncr->scsid[ch] = xcalloc (SCSIDevice, 1);
        ncr->scsid[ch]->handle = handle;
        ncr->enabled = true;
-       return ncr->scsid[ch] ? 1 : 0;
 }
 
-
-static int add_ncr_scsi_cd (struct ncr_state *ncr, int ch, int unitnum)
+static void add_ncr_scsi_cd (struct ncr_state *ncr, int ch, int unitnum)
 {
-       struct scsi_data *handle;
-       device_func_init (0);
+       struct scsi_data *handle = NULL;
+
        freescsi (ncr->scsid[ch]);
        ncr->scsid[ch] = NULL;
-       handle = scsi_alloc_cd (ch, unitnum, false);
-       if (!handle)
-               return 0;
+       if (!add_scsi_cd(&handle, ch, unitnum))
+               return;
        handle->privdata = ncr;
        ncr->scsid[ch] = xcalloc (SCSIDevice, 1);
        ncr->scsid[ch]->handle = handle;
        ncr->enabled = true;
-       return ncr->scsid[ch] ? 1 : 0;
 }
 
-static int add_ncr_scsi_tape (struct ncr_state *ncr, int ch, const TCHAR *tape_directory, bool readonly)
+static void add_ncr_scsi_tape (struct ncr_state *ncr, int ch, const TCHAR *tape_directory, bool readonly)
 {
-       struct scsi_data *handle;
+       struct scsi_data *handle = NULL;
+
        freescsi (ncr->scsid[ch]);
        ncr->scsid[ch] = NULL;
-       handle = scsi_alloc_tape (ch, tape_directory, readonly);
-       if (!handle)
-               return 0;
+       if (!add_scsi_tape(&handle, ch, tape_directory, readonly))
+               return;
        handle->privdata = ncr;
        ncr->scsid[ch] = xcalloc (SCSIDevice, 1);
        ncr->scsid[ch]->handle = handle;
        ncr->enabled = true;
-       return ncr->scsid[ch] ? 1 : 0;
 }
 
-static int ncr_add_scsi_unit(struct ncr_state *ncr, int ch, struct uaedev_config_info *ci)
+static void ncr_add_scsi_unit(struct ncr_state **ncrp, int ch, struct uaedev_config_info *ci, struct romconfig *rc, bool newncr)
 {
-       if (ci->type == UAEDEV_CD)
-               return add_ncr_scsi_cd (ncr, ch, ci->device_emu_unit);
-       else if (ci->type == UAEDEV_TAPE)
-               return add_ncr_scsi_tape (ncr, ch, ci->rootdir, ci->readonly);
-       else
-               return add_ncr_scsi_hd (ncr, ch, NULL, ci, 2);
+       struct ncr_state *ncr = allocscsi(ncrp, rc, ch);
+       if (!ncr)
+               return;
+       ncr->newncr = newncr;
+       ncr_init_board(ncr);
+       if (ch >= 0 && ncr) {
+               if (ci->type == UAEDEV_CD)
+                       add_ncr_scsi_cd (ncr, ch, ci->device_emu_unit);
+               else if (ci->type == UAEDEV_TAPE)
+                       add_ncr_scsi_tape (ncr, ch, ci->rootdir, ci->readonly);
+               else if (ci->type == UAEDEV_HDF)
+                       add_ncr_scsi_hd (ncr, ch, NULL, ci, 2);
+       }
 }
 
-int a4000t_add_scsi_unit (int ch, struct uaedev_config_info *ci)
+void a4000t_add_scsi_unit (int ch, struct uaedev_config_info *ci, struct romconfig *rc)
 {
-       return ncr_add_scsi_unit(&ncr_a4000t, ch, ci);
+       ncr_add_scsi_unit(&ncr_a4000t, ch, ci, rc, false);
+       ncr_a4000t->configured = -1;
+       ncr_a4000t->enabled = true;
 }
 
-int warpengine_add_scsi_unit (int ch, struct uaedev_config_info *ci)
+void warpengine_add_scsi_unit (int ch, struct uaedev_config_info *ci, struct romconfig *rc)
 {
-       return ncr_add_scsi_unit(&ncr_we, ch, ci);
+       ncr_add_scsi_unit(&ncr_we, ch, ci, rc, false);
 }
 
-int tekmagic_add_scsi_unit (int ch, struct uaedev_config_info *ci)
+void tekmagic_add_scsi_unit (int ch, struct uaedev_config_info *ci, struct romconfig *rc)
 {
-       return ncr_add_scsi_unit(&ncr_cpuboard, ch, ci);
+       ncr_add_scsi_unit(&ncr_cpuboard, ch, ci, rc, false);
 }
 
-int a4091_add_scsi_unit (int ch, struct uaedev_config_info *ci)
+void a4091_add_scsi_unit (int ch, struct uaedev_config_info *ci, struct romconfig *rc)
 {
-       return ncr_add_scsi_unit(ncra4091[ci->controller_type_unit], ch, ci);
+       ncr_add_scsi_unit(&ncra4091[ci->controller_type_unit], ch, ci, rc, false);
 }
 
-int cyberstorm_add_scsi_unit(int ch, struct uaedev_config_info *ci)
+void cyberstorm_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
 {
-       return ncr_add_scsi_unit(&ncr_cs, ch, ci);
+       ncr_add_scsi_unit(&ncr_cs, ch, ci, rc, true);
+       ncr_cs->configured = -1;
+       ncr_cs->enabled = true;
+       ncr_cs->ramsize = CYBERSTORM_SCSI_RAM_SIZE;
+       ncr_cs->irq_func = cyberstorm_mk3_ppc_irq;
+       ncr_cs->bank = &ncr_bank_cyberstorm;
+       ncr_cs->baseaddress = 0xf40000;
 }
 
-int blizzardppc_add_scsi_unit(int ch, struct uaedev_config_info *ci)
+void blizzardppc_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
 {
-       return ncr_add_scsi_unit(&ncr_bppc, ch, ci);
+       ncr_add_scsi_unit(&ncr_bppc, ch, ci, rc, false);
+       ncr_bppc->configured = -1;
+       ncr_bppc->enabled = true;
+       ncr_bppc->irq_func = blizzardppc_irq;
+       ncr_bppc->bank = &ncr_bank_cyberstorm;
+       ncr_bppc->baseaddress = 0xf40000;
 }
 
 #endif
index 17c74d37101c43b96a7aa611ee31eaa7236b2e55..0e05cc09e0a8ffabe13610de35c24faec0125508 100644 (file)
@@ -1858,7 +1858,7 @@ STATIC_INLINE int in_rom (uaecptr pc)
 
 STATIC_INLINE int in_rtarea (uaecptr pc)
 {
-       return (munge24 (pc) & 0xFFFF0000) == rtarea_base && uae_boot_rom;
+       return (munge24 (pc) & 0xFFFF0000) == rtarea_base && uae_boot_rom_type;
 }
 
 STATIC_INLINE void wait_memory_cycles (void)
@@ -2751,7 +2751,7 @@ kludge_me_do:
                if (nr == 2 || nr == 3)
                        cpu_halt (2);
                else
-                       exception3_read(regs.ir, newpc);
+                       exception3_notinstruction(regs.ir, newpc);
                return;
        }
        m68k_setpc (newpc);
@@ -4127,7 +4127,6 @@ void cpu_halt (int id)
 /* MMU 68060  */
 static void m68k_run_mmu060 (void)
 {
-       uaecptr pc;
        struct flag_struct f;
        int halt = 0;
 
@@ -4136,7 +4135,7 @@ static void m68k_run_mmu060 (void)
                        for (;;) {
                                f.cznv = regflags.cznv;
                                f.x = regflags.x;
-                               pc = regs.instruction_pc = m68k_getpc ();
+                               regs.instruction_pc = m68k_getpc ();
 
                                do_cycles (cpu_cycles);
 
@@ -4187,7 +4186,6 @@ static void m68k_run_mmu060 (void)
 static void m68k_run_mmu040 (void)
 {
        flag_struct f;
-       uaecptr pc;
        int halt = 0;
 
        while (!halt) {
@@ -4196,7 +4194,7 @@ static void m68k_run_mmu040 (void)
                                f.cznv = regflags.cznv;
                                f.x = regflags.x;
                                mmu_restart = true;
-                               pc = regs.instruction_pc = m68k_getpc ();
+                               regs.instruction_pc = m68k_getpc ();
 
                                do_cycles (cpu_cycles);
 
@@ -4242,7 +4240,6 @@ static void m68k_run_mmu040 (void)
 // Previous MMU 68030
 static void m68k_run_mmu030 (void)
 {
-       uaecptr pc;
        struct flag_struct f;
        int halt = 0;
 
@@ -4253,7 +4250,7 @@ static void m68k_run_mmu030 (void)
                        for (;;) {
                                int cnt;
 insretry:
-                               pc = regs.instruction_pc = m68k_getpc ();
+                               regs.instruction_pc = m68k_getpc ();
                                f.cznv = regflags.cznv;
                                f.x = regflags.x;
 
@@ -6738,7 +6735,7 @@ uae_u32 read_dcache030 (uaecptr addr, int size)
        if (!c1->valid[lws1] || c1->tag != tag1) {
                v1 = currprefs.cpu_cycle_exact ? mem_access_delay_long_read_ce020 (addr) : get_long (addr);
                update_cache030 (c1, v1, tag1, lws1);
-       } else if (uae_boot_rom) {
+       } else if (uae_boot_rom_type > 0) {
                // this check and fix is needed for UAE filesystem handler because it runs in host side and in
                // separate thread. No way to access via cache without locking that would cause major slowdown
                // and unneeded complexity
@@ -6774,7 +6771,7 @@ uae_u32 read_dcache030 (uaecptr addr, int size)
        if (!c2->valid[lws2] || c2->tag != tag2) {
                v2 = currprefs.cpu_cycle_exact ? mem_access_delay_long_read_ce020 (addr) : get_long (addr);
                update_cache030 (c2, v2, tag2, lws2);
-       } else if (uae_boot_rom) {
+       } else if (uae_boot_rom_type > 0) {
                v2 = c2->data[lws2];
                if (get_long (addr) != v2) {
                        write_log (_T("data cache mismatch %d %d %08x %08x != %08x %08x %d PC=%08x\n"),
index e63e19f1dc42edcf37107b27177a33e7994dfd35..2bb991c8b1e217f89588d2b4cb39502b760e6525 100644 (file)
@@ -318,9 +318,9 @@ static int doinit_shm (void)
                if (changed_prefs.cpu_model >= 68020)
                        size = 0x10000000;
                z3size = ((changed_prefs.z3fastmem_size + align) & ~align) + ((changed_prefs.z3fastmem2_size + align) & ~align) + ((changed_prefs.z3chipmem_size + align) & ~align);
-               if (cfgfile_board_enabled(&currprefs, ROMTYPE_A4091))
+               if (cfgfile_board_enabled(&currprefs, ROMTYPE_A4091, 0))
                        othersize += 2 * 16 * 1024 * 1024;
-               if (cfgfile_board_enabled(&currprefs, ROMTYPE_FASTLANE))
+               if (cfgfile_board_enabled(&currprefs, ROMTYPE_FASTLANE, 0))
                        othersize += 2 * 32 * 1024 * 1024;
                totalsize = size + z3size + z3rtgmem_size + othersize;
                while (totalsize > size64) {
index dedf27540a3b8eaa5b14af875317730441ae9cd1..20f76e8596d26466198f8adcdbdff841f5c70fdd 100644 (file)
@@ -1311,7 +1311,7 @@ int setbaud (long baud)
 
 void initparallel (void)
 {
-       if (uae_boot_rom) {
+       if (uae_boot_rom_type) {
                uaecptr a = here (); //this install the ahisound
                org (rtarea_base + 0xFFC0);
                calltrap (deftrapres (ahi_demux, 0, _T("ahi_winuae")));
index 8118bb848ca97b2374b036b0e3c407cdbadd76de..55b0c46625b640ada0f5b4d531697a2f0661cc70 100644 (file)
 #define IDC_DELETE                      1403
 #define IDC_CPUBOARDROMCHOOSER          1403
 #define IDC_CONFIGLIST                  1404
+#define IDC_SCSIROMSELECTNUM            1404
 #define IDC_EDITNAME                    1405
 #define IDC_EDITDESCRIPTION             1406
 #define IDC_QUICKSAVE                   1408
index a37102b5b668ce31d31383898f190e9312880efd..70377b88f9508fd26d9271ccea469b47d59a0913 100644 (file)
@@ -76,41 +76,43 @@ END
 // Dialog
 //
 
-IDD_KICKSTART DIALOGEX 0, 0, 396, 289
+IDD_KICKSTART DIALOGEX 0, 0, 396, 304
 STYLE DS_LOCALEDIT | DS_SETFONT | DS_3DLOOK | DS_CONTROL | WS_CHILD
 EXSTYLE WS_EX_CONTEXTHELP
 FONT 8, "MS Sans Serif", 0, 0, 0x1
 BEGIN
-    GROUPBOX        "System ROM Settings",IDC_STATIC,1,0,394,93
+    GROUPBOX        "System ROM Settings",IDC_STATIC,1,0,394,91
     LTEXT           "Main ROM file:",IDC_ROMTEXT,14,13,263,10
-    COMBOBOX        IDC_ROMFILE,12,26,361,75,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP
+    COMBOBOX        IDC_ROMFILE,12,25,361,75,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP
     PUSHBUTTON      "...",IDC_KICKCHOOSER,376,25,10,15
-    LTEXT           "Extended ROM file:",IDC_ROMFILE2TEXT,14,43,263,10
-    COMBOBOX        IDC_ROMFILE2,12,56,361,75,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP
+    LTEXT           "Extended ROM file:",IDC_ROMFILE2TEXT,14,42,263,10
+    COMBOBOX        IDC_ROMFILE2,12,54,361,75,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP
     PUSHBUTTON      "...",IDC_ROMCHOOSER2,376,55,10,15
     CONTROL         "MapROM emulation [] Creates a BlizKick-compatible memory area.",IDC_MAPROM,
-                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,87,77,104,12
+                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,87,73,104,12
     CONTROL         "ShapeShifter support [] Patches the system ROM for ShapeShifter compatibility.",IDC_KICKSHIFTER,
-                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,195,77,106,13
-    GROUPBOX        "Miscellaneous",IDC_STATIC,1,100,394,188
+                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,195,73,106,13
+    GROUPBOX        "Expansion ROM Settings",IDC_STATIC,1,206,394,66
     LTEXT           "Cartridge ROM file:",IDC_FLASHTEXT2,12,112,265,10
-    COMBOBOX        IDC_CARTFILE,12,125,361,75,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP
-    PUSHBUTTON      "...",IDC_CARTCHOOSER,376,124,10,15
-    LTEXT           "Flash RAM file:",IDC_FLASHTEXT,12,144,265,10
-    EDITTEXT        IDC_FLASHFILE,12,157,361,12,ES_AUTOHSCROLL
-    PUSHBUTTON      "...",IDC_FLASHCHOOSER,376,156,10,15
-    LTEXT           "Real Time Clock file",IDC_STATIC,12,174,313,15,SS_CENTERIMAGE
-    EDITTEXT        IDC_RTCFILE,12,191,361,12,ES_AUTOHSCROLL
-    PUSHBUTTON      "...",IDC_RTCCHOOSER,376,189,10,15
-    COMBOBOX        IDC_SCSIROMSELECT,12,228,171,75,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
-    LTEXT           "SCSI/Boot ROM file:",IDC_STATIC,12,212,170,15,SS_CENTERIMAGE
-    COMBOBOX        IDC_SCSIROMFILE,202,228,171,75,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
-    PUSHBUTTON      "...",IDC_SCSIROMCHOOSER,376,226,10,15
-    LTEXT           "Accelerator board ROM file:",IDC_STATIC,12,250,170,15,SS_CENTERIMAGE
-    COMBOBOX        IDC_CPUBOARDROMFILE,12,266,171,75,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
-    PUSHBUTTON      "...",IDC_CPUBOARDROMCHOOSER,187,265,10,15
-    CONTROL         "Autoboot disabled",IDC_SCSIROMFILEAUTOBOOT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,202,213,84,12
-    COMBOBOX        IDC_SCSIROMSUBSELECT,202,246,171,75,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
+    COMBOBOX        IDC_CARTFILE,12,124,361,75,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP
+    PUSHBUTTON      "...",IDC_CARTCHOOSER,376,123,10,15
+    LTEXT           "Flash RAM file:",IDC_FLASHTEXT,12,141,265,10
+    EDITTEXT        IDC_FLASHFILE,12,153,361,12,ES_AUTOHSCROLL
+    PUSHBUTTON      "...",IDC_FLASHCHOOSER,376,151,10,15
+    LTEXT           "Real Time Clock file",IDC_STATIC,12,167,313,15,SS_CENTERIMAGE
+    EDITTEXT        IDC_RTCFILE,12,183,361,12,ES_AUTOHSCROLL
+    PUSHBUTTON      "...",IDC_RTCCHOOSER,376,181,10,15
+    COMBOBOX        IDC_SCSIROMSELECT,12,235,157,75,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
+    LTEXT           "SCSI/IDE/Boot ROM file:",IDC_STATIC,12,219,170,15,SS_CENTERIMAGE
+    COMBOBOX        IDC_SCSIROMFILE,202,235,171,75,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
+    PUSHBUTTON      "...",IDC_SCSIROMCHOOSER,376,235,10,15
+    LTEXT           "Accelerator board ROM file:",IDC_STATIC,12,273,170,15,SS_CENTERIMAGE
+    COMBOBOX        IDC_CPUBOARDROMFILE,12,289,171,75,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
+    PUSHBUTTON      "...",IDC_CPUBOARDROMCHOOSER,187,288,10,15
+    CONTROL         "Autoboot disabled",IDC_SCSIROMFILEAUTOBOOT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,202,216,84,12
+    COMBOBOX        IDC_SCSIROMSUBSELECT,202,253,171,75,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
+    COMBOBOX        IDC_SCSIROMSELECTNUM,175,235,22,75,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
+    GROUPBOX        "Miscellaneous",IDC_STATIC,0,96,395,106
 END
 
 IDD_DISPLAY DIALOGEX 0, 0, 396, 298
@@ -1188,11 +1190,11 @@ CAPTION "CD Settings"
 FONT 8, "MS Sans Serif", 0, 0, 0x0
 BEGIN
     RTEXT           "HD Controller:",IDC_STATIC,7,90,65,10,SS_CENTERIMAGE
-    COMBOBOX        IDC_HDF_CONTROLLER,83,89,100,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
-    DEFPUSHBUTTON   "Add CD Drive",IDOK,236,89,73,14
-    PUSHBUTTON      "Cancel",IDCANCEL,316,89,73,14
+    COMBOBOX        IDC_HDF_CONTROLLER,80,89,122,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
+    DEFPUSHBUTTON   "Add CD Drive",IDOK,238,89,73,14
+    PUSHBUTTON      "Cancel",IDCANCEL,318,89,73,14
     CONTROL         "",IDC_CDLIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,4,4,387,77
-    COMBOBOX        IDC_HDF_CONTROLLER_UNIT,189,89,25,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
+    COMBOBOX        IDC_HDF_CONTROLLER_UNIT,208,89,25,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP
 END
 
 IDD_TAPEDRIVE DIALOGEX 0, 0, 395, 97
@@ -1536,7 +1538,6 @@ BEGIN
 
     IDD_TAPEDRIVE, DIALOG
     BEGIN
-        BOTTOMMARGIN, 80
     END
 
     IDD_DISKINFO, DIALOG
@@ -1841,7 +1842,7 @@ BEGIN
     IDS_QS_MODEL_A500       "1.3 ROM, OCS, 512 KB Chip + 512 KB Slow RAM (most common)\nThis configuration is capable of running most games and demos produced for first-generation hardware. Only few exceptions need a different configuration (e.g. the oldest games tend to be incompatible with this configuration).\n1.3 ROM, ECS Agnus, 512 KB Chip RAM + 512 KB Slow RAM\nLater hardware revision of the A500. Nearly 100% compatible with the previous configuration.\n1.3 ROM, ECS Agnus, 1 MB Chip RAM\nFew newer games and demos require this configuration.\n1.3 ROM, OCS Agnus, 512 KB Chip RAM\nVery old (e.g. pre-1988) games and demos may require this configuration.\n1.2 ROM, OCS Agnus, 512 KB Chip RAM\nAs available for the A1000, and installed on the first A500 and A2000 series. Some very old programs only work correctly with this configuration. Note: This system ROM version can only boot from floppy disk (no hard disk boot support).\n1.2 ROM, OCS Agnus, 512 KB Chip RAM + 512 KB Slow RAM\nThis configuration adds expansion memory to the first A500 produced. Try this if your game does not work with newer configurations, but works with the previous one. It could add some features to the game, including faster loading times. Note: This system ROM version can only boot from floppy disk (no hard disk boot support)."
     IDS_QS_MODEL_A500P      "Basic non-expanded configuration\nThe A500+ adds an ECS Agnus chip, 1 MB of Chip RAM and a 2.0 ROM to the A500. Many A500 games and demos don't work properly on an A500+.\n2 MB Chip RAM expanded configuration\n\n4 MB Fast RAM expanded configuration\n"
     IDS_QS_MODEL_A600       "Basic non-expanded configuration\nThe A600 is smaller than the A500+ and has an updated 2.0 ROM.\n2 MB Chip RAM expanded configuration\n\n4 MB Fast RAM expanded configuration\n"
-    IDS_QS_MODEL_A1000      "512 KB Chip RAM\nThe A1000 was the first model produced, with a configuration equivalent to that of an A500 with OCS chipset. You normally don't need to use this configuration, unless you are nostalgic and would like to hear the short A1000 boot tune\n""ICS"" Denise without EHB support\nVery first A1000 models had Denise without EHB capability.\n256 KB Chip RAM\n Unexpanded A1000. All later A1000 models were sold with a 256 KB RAM expansion built-in."
+    IDS_QS_MODEL_A1000      "512 KB Chip RAM\nThe A1000 was the first model produced, with a configuration equivalent to that of an A500 with OCS chipset. You normally don't need to use this configuration, unless you are nostalgic and would like to hear the short A1000 boot tune\n""ICS"" Denise without EHB support\nVery first A1000 models had Denise without EHB capability.\n256 KB Chip RAM\n Unexpanded A1000. All later A1000 models were sold with a 256 KB RAM expansion built-in.\nA1000 ""Velvet"" Prototype\n"
     IDS_QS_MODEL_A1200      "Basic non-expanded configuration\nUse this configuration to run most AGA demos and games\n4 MB Fast RAM expanded configuration\nSome newer AGA games and demos need an expanded A1200 to run.\nBlizzard 1230 IV\n\nBlizzard 1240\n\nBlizzard 1260\n\nBlizzard PPC\n"
     IDS_QS_MODEL_CD32       "CD32\nThe CD32 was one the first 32-bit consoles on the market. It is basically an A1200 with a built-in CD-ROM drive. Insert your CD32 or CDTV CD-ROM into a free CD-ROM drive before starting the emulation.\nCD32 with Full Motion Video cartridge\n"
     IDS_QS_MODEL_CDTV       "CDTV\nThe CDTV was the first model with a built-in CD-ROM drive. Looking like a black CD player, it featured a configuration equivalent to that of an A500 with 1 MB RAM and an ECS chipset.\nFloppy drive and 64KB SRAM card expanded CDTV\n\nCDTV-CR\n"
index 18ca242647b23d1e355b68d21c8917aa4ec79ee9..3a64cafe81764e084cdf3d5495e9a8a47b76b714 100644 (file)
@@ -316,24 +316,31 @@ static void serdatcopy(void);
 
 static void checksend(void)
 {
+       bool sent = true;
+
        if (data_in_sershift != 1)
                return;
 
        if (sermap_data && sermap_enabled)
                shmem_serial_send(serdatshift);
 #ifdef SERIAL_ENET
-       if (serial_enet)
+       if (serial_enet) {
                enet_writeser(serdatshift);
+       }
 #endif
 #ifdef SERIAL_PORT
        if (checkserwrite()) {
                if (ninebit)
                        writeser(((serdatshift >> 8) & 1) | 0xa8);
                writeser(serdatshift);
+       } else {
+               // buffer full, try again later
+               sent = false;
        }
 #endif
-       data_in_sershift = 2;
-
+       if (sent) {
+               data_in_sershift = 2;
+       }
 #if SERIALDEBUG > 2
                write_log(_T("SERIAL: send %04X (%c)\n"), serdatshift, dochar(serdatshift));
 #endif
@@ -342,10 +349,14 @@ static void checksend(void)
 static void sersend_ce(uae_u32 v)
 {
        checksend();
-       data_in_sershift = 0;
-       serdatcopy();
-       lastbitcycle = get_cycles() + ((serper & 0x7fff) + 1) * CYCLE_UNIT;
-       lastbitcycle_active_hsyncs = ((serper & 0x7fff) + 1) / maxhpos + 2;
+       if (data_in_sershift == 2) {
+               data_in_sershift = 0;
+               serdatcopy();
+               lastbitcycle = get_cycles() + ((serper & 0x7fff) + 1) * CYCLE_UNIT;
+               lastbitcycle_active_hsyncs = ((serper & 0x7fff) + 1) / maxhpos + 2;
+       } else if (data_in_sershift == 1) {
+               event2_newevent_x(-1, maxhpos, 0, sersend_ce);
+       }
 }
 
 static void serdatcopy(void)
index 41551d96b4c87b726b7ae1f3b9a63bcd56dec470..b068e5b87dd36fe23385a934d1cc4cf4f2ef1498 100644 (file)
 #define LANG_DLL_FULL_VERSION_MATCH 1
 
 #if WINUAEPUBLICBETA
-#define WINUAEBETA _T("11")
+#define WINUAEBETA _T("12")
 #else
 #define WINUAEBETA _T("")
 #endif
 
-#define WINUAEDATE MAKEBD(2015, 2, 27)
+#define WINUAEDATE MAKEBD(2015, 3, 14)
 
 //#define WINUAEEXTRA _T("AmiKit Preview")
 //#define WINUAEEXTRA _T("Amiga Forever Edition")
index ce21e17b087424791b3b653528785c1bed427808..4ee26a99504bc8c17bf5d91fce02541d8f68360b 100644 (file)
@@ -1792,9 +1792,18 @@ static int getstatuswindowheight (void)
        return wi.rcWindow.bottom - wi.rcWindow.top;
 }
 
-void graphics_reset(void)
+void graphics_reset(bool forced)
 {
-       display_change_requested = 2;
+       if (forced) {
+               display_change_requested = 2;
+       } else {
+               // full reset if display size can't changed.
+               if (currprefs.gfx_api) {
+                       display_change_requested = 1;
+               } else {
+                       display_change_requested = 2;
+               }
+       }
 }
 
 void WIN32GFX_DisplayChangeRequested (int mode)
index ef7c3548f992caca0aa1d5450981adf55efbd443..3d74a4ca55447e8645ea6a5fdb5e455a89751c90 100644 (file)
@@ -181,6 +181,7 @@ static void addaspectratios (HWND hDlg, int id)
 }
 
 static int scsiromselected = -1;
+static int scsiromselectednum = 0;
 
 #define Error(x) MessageBox (NULL, (x), _T("WinUAE Error"), MB_OK)
 
@@ -1683,7 +1684,8 @@ static void show_rom_list (void)
                117, -1, -1, // alf
                118, -1, -1, // alf+
                120, -1, -1, // masoboshi
-               121, -1, -2, // supradrive
+               121, -1, -1, // supradrive
+               124, -1, -2, // kupke golem
 
                18, -1, 19, -1, 74, 23, -1, -1,  // CD32 FMV
                91, -1, -2, // Picasso IV
@@ -1693,6 +1695,7 @@ static void show_rom_list (void)
                110, -1, -1, // GVP A530
                110, -1, -1, // GVP G-Force 030
                114, -1, -1, // A3001
+               126, -1, -1, // Golem 030
                89, -1, -1, // 1230-IV
                89, -1, 94, -1, -1, // 1230-IV SCSI
                90, -1, -1, // 1260
@@ -1724,7 +1727,8 @@ static void show_rom_list (void)
                _T("CD32\0CDTV\0CDTV-CR\0Arcadia Multi Select\0")
 
                _T("A590/A2091 SCSI/XT\0GVP Series I SCSI\0GVP Series II SCSI\0A4091 SCSI\0Fastlane SCSI\0Oktagon 2008 SCSI\0")
-               _T("AlfaPower/AT-BUS 508/2008 SCSI\0AlfaPower Plus SCSI\0Masoboshi MC-702 IDE/SCSI\0SupraDrive 500XP SCSI\0")
+               _T("AlfaPower/AT-BUS 508/2008 SCSI\0AlfaPower Plus SCSI\0Masoboshi MC-302/MC-702 IDE/SCSI\0SupraDrive SCSI\0")
+               _T("Golem SCSI\0")
 
                _T("CD32 Full Motion Video\0")
                _T("Picasso IV\0")
@@ -1734,6 +1738,7 @@ static void show_rom_list (void)
                _T("GVP A530\0")
                _T("GVP G-FORCE 030\0")
                _T("GVP A3001 Series I\0")
+               _T("Kupke Golem 030\0")
                _T("Blizzard 1230-IV\0Blizzard 1260\0")
                _T("Blizzard 1230-IV/SCSI\0Blizzard 1260/SCSI\0")
                _T("Blizzard 2060\0Warp Engine\0TekMagic 2040/2060\0")
@@ -2775,7 +2780,7 @@ int DiskSelection_2 (HWND hDlg, WPARAM wParam, int flag, struct uae_prefs *prefs
                        if (val != CB_ERR) {
                                int index;
                                struct boardromconfig *brc;
-                               brc = get_device_rom_new(&workprefs, expansionroms[scsiromselected].romtype, &index);
+                               brc = get_device_rom_new(&workprefs, expansionroms[scsiromselected].romtype, scsiromselectednum, &index);
                                _tcscpy (brc->roms[index].romfile, full_path);
                                fullpath (brc->roms[index].romfile, MAX_DPATH);
                        }
@@ -2784,7 +2789,7 @@ int DiskSelection_2 (HWND hDlg, WPARAM wParam, int flag, struct uae_prefs *prefs
                case IDC_CPUBOARDROMFILE:
                {
                        int index;
-                       struct boardromconfig *brc = get_device_rom_new(&workprefs, ROMTYPE_CPUBOARD, &index);
+                       struct boardromconfig *brc = get_device_rom_new(&workprefs, ROMTYPE_CPUBOARD, 0, &index);
                        _tcscpy(brc->roms[index].romfile, full_path);
                        fullpath(brc->roms[index].romfile, MAX_DPATH);
                        break;
@@ -4346,7 +4351,10 @@ void InitializeListView (HWND hDlg)
                                };
                                _stprintf (blocksize_str, _T("%d"), ci->blocksize);
                                if (ert) {
-                                       _stprintf (devname_str, _T("%s:%d"), ert->friendlyname, ci->controller_unit);
+                                       if (ci->controller_type_unit == 0)
+                                               _stprintf (devname_str, _T("%s:%d"), ert->friendlyname, ci->controller_unit);
+                                       else
+                                               _stprintf (devname_str, _T("%s:%d/%d"), ert->friendlyname, ci->controller_unit, ci->controller_type_unit + 1);
                                } else {
                                        _stprintf (devname_str, idedevs[ctype - HD_CONTROLLER_TYPE_IDE_FIRST], ci->controller_unit);
                                }
@@ -4367,7 +4375,10 @@ void InitializeListView (HWND hDlg)
                                        _stprintf(sid, _T("%d"), ci->controller_unit);
                                _stprintf (blocksize_str, _T("%d"), ci->blocksize);
                                if (ert) {
-                                       _stprintf (devname_str, _T("%s:%s"), ert->friendlyname, sid);
+                                       if (ci->controller_type_unit == 0)
+                                               _stprintf (devname_str, _T("%s:%s"), ert->friendlyname, sid);
+                                       else
+                                               _stprintf (devname_str, _T("%s:%s/%d"), ert->friendlyname, sid, ci->controller_type_unit + 1);
                                } else {
                                        _stprintf (devname_str, scsidevs[ctype - HD_CONTROLLER_TYPE_SCSI_FIRST], sid);
                                }
@@ -7296,7 +7307,7 @@ static INT_PTR CALLBACK ChipsetDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPAR
                SendDlgItemMessage (hDlg, IDC_CS_EXT, CB_ADDSTRING, 0, (LPARAM)_T("A3000T"));
                SendDlgItemMessage (hDlg, IDC_CS_EXT, CB_ADDSTRING, 0, (LPARAM)_T("A4000"));
                SendDlgItemMessage (hDlg, IDC_CS_EXT, CB_ADDSTRING, 0, (LPARAM)_T("A4000T"));
-               //SendDlgItemMessage (hDlg, IDC_CS_EXT, CB_ADDSTRING, 0, (LPARAM)_T("Velvet"));
+               SendDlgItemMessage (hDlg, IDC_CS_EXT, CB_ADDSTRING, 0, (LPARAM)_T("Velvet"));
 
                SendDlgItemMessage (hDlg, IDC_MONITOREMU, CB_RESETCONTENT, 0, 0);
                SendDlgItemMessage (hDlg, IDC_MONITOREMU, CB_ADDSTRING, 0, (LPARAM)_T("-"));
@@ -7636,7 +7647,7 @@ static void setmax32bitram (HWND hDlg)
        rtgz3size = gfxboard_is_z3 (workprefs.rtgmem_type) ? workprefs.rtgmem_size : 0;
        size = ((workprefs.z3fastmem_size + sizealign) & ~sizealign) + ((workprefs.z3fastmem2_size + sizealign) & ~sizealign) +
                ((rtgz3size + sizealign) & ~sizealign);
-       if (cfgfile_board_enabled(&currprefs, ROMTYPE_A4091))
+       if (cfgfile_board_enabled(&currprefs, ROMTYPE_A4091, 0))
                size += 2 * 16 * 1024 * 1024;
        if (changed_prefs.mbresmem_high_size >= 128 * 1024 * 1024 && (size || workprefs.z3chipmem_size))
                size += (changed_prefs.mbresmem_high_size - 128 * 1024 * 1024) + 16 * 1024 * 1024;
@@ -8677,12 +8688,17 @@ static void values_to_kickstartdlg_sub(HWND hDlg)
                srt++;
        }
        int index;
-       struct boardromconfig *brc = get_device_rom(&workprefs, expansionroms[scsiromselected].romtype, &index);
+       struct boardromconfig *brc = get_device_rom(&workprefs, expansionroms[scsiromselected].romtype, scsiromselectednum, &index);
        if (brc) {
                SendDlgItemMessage (hDlg, IDC_SCSIROMSUBSELECT, CB_SETCURSEL, brc->roms[index].subtype, 0);
        } else if (srt) {
                SendDlgItemMessage (hDlg, IDC_SCSIROMSUBSELECT, CB_SETCURSEL, 0, 0);
        }
+       if (er->zorro < 2 || er->singleonly) {
+               scsiromselectednum = 0;
+               SendDlgItemMessage (hDlg, IDC_SCSIROMSELECTNUM, CB_SETCURSEL, 0, 0);
+       }
+       ew(hDlg, IDC_SCSIROMSELECTNUM, er->zorro >= 2 && !er->singleonly);
 }
 
 static void values_from_kickstartdlg (HWND hDlg)
@@ -8697,7 +8713,7 @@ static void values_from_kickstartdlg (HWND hDlg)
 
        getromfile(hDlg, IDC_SCSIROMFILE, tmp, MAX_DPATH / sizeof (TCHAR));
        if (tmp[0]) {
-               brc = get_device_rom_new(&workprefs, expansionroms[scsiromselected].romtype, &index);
+               brc = get_device_rom_new(&workprefs, expansionroms[scsiromselected].romtype, scsiromselectednum, &index);
                bool changed = _tcscmp(tmp, brc->roms[index].romfile) != 0;
                getromfile(hDlg, IDC_SCSIROMFILE, brc->roms[index].romfile, MAX_DPATH / sizeof (TCHAR));
                brc->roms[index].autoboot_disabled = ischecked(hDlg, IDC_SCSIROMFILEAUTOBOOT);
@@ -8707,17 +8723,17 @@ static void values_from_kickstartdlg (HWND hDlg)
                if (changed)
                        values_to_kickstartdlg_sub(hDlg);
        } else {
-               brc = get_device_rom(&workprefs, expansionroms[scsiromselected].romtype, &index);
-               clear_device_rom(&workprefs, expansionroms[scsiromselected].romtype);
+               brc = get_device_rom(&workprefs, expansionroms[scsiromselected].romtype, scsiromselectednum, &index);
+               clear_device_rom(&workprefs, expansionroms[scsiromselected].romtype, scsiromselectednum);
                if (brc && brc->roms[index].romfile[0])
                        values_to_kickstartdlg_sub(hDlg);
        }
        getromfile(hDlg, IDC_CPUBOARDROMFILE, tmp, sizeof(brc->roms[index].romfile) / sizeof(TCHAR));
        if (tmp[0]) {
-               brc = get_device_rom_new(&workprefs, ROMTYPE_CPUBOARD, &index);
+               brc = get_device_rom_new(&workprefs, ROMTYPE_CPUBOARD, 0, &index);
                getromfile(hDlg, IDC_CPUBOARDROMFILE, brc->roms[index].romfile, sizeof(brc->roms[index].romfile) / sizeof(TCHAR));
        } else {
-               clear_device_rom(&workprefs, ROMTYPE_CPUBOARD);
+               clear_device_rom(&workprefs, ROMTYPE_CPUBOARD, 0);
        }
 }
 
@@ -8725,7 +8741,7 @@ static void values_to_kickstartdlg_autoboot(HWND hDlg)
 {
        int index;
        struct boardromconfig *brc;
-       brc = get_device_rom(&workprefs, expansionroms[scsiromselected].romtype, &index);
+       brc = get_device_rom(&workprefs, expansionroms[scsiromselected].romtype, scsiromselectednum, &index);
        if (brc && brc->roms[index].romfile[0]) {
                ew(hDlg, IDC_SCSIROMFILEAUTOBOOT, expansionroms[scsiromselected].autoboot_jumper);
        } else {
@@ -8753,7 +8769,7 @@ static void values_to_kickstartdlg (HWND hDlg)
        addromfiles (fkey, hDlg, IDC_CARTFILE, workprefs.cartfile,
                ROMTYPE_FREEZER | ROMTYPE_ARCADIAGAME | ROMTYPE_CD32CART, 0);
 
-       brc = get_device_rom(&workprefs, expansionroms[scsiromselected].romtype, &index);
+       brc = get_device_rom(&workprefs, expansionroms[scsiromselected].romtype, scsiromselectednum, &index);
        addromfiles (fkey, hDlg, IDC_SCSIROMFILE, brc ? brc->roms[index].romfile : NULL,
                expansionroms[scsiromselected].romtype, expansionroms[scsiromselected].romtype_extra);
        CheckDlgButton(hDlg, IDC_SCSIROMFILEAUTOBOOT, brc && brc->roms[index].autoboot_disabled);
@@ -8761,7 +8777,7 @@ static void values_to_kickstartdlg (HWND hDlg)
 
        if (workprefs.cpuboard_type) {
                const struct cpuboardsubtype *cst = &cpuboards[workprefs.cpuboard_type].subtypes[workprefs.cpuboard_subtype];
-               brc = get_device_rom(&workprefs, ROMTYPE_CPUBOARD, &index);
+               brc = get_device_rom(&workprefs, ROMTYPE_CPUBOARD, 0, &index);
                addromfiles(fkey, hDlg, IDC_CPUBOARDROMFILE, brc ? brc->roms[index].romfile : NULL,
                        cst->romtype, cst->romtype_extra);
        } else {
@@ -8802,11 +8818,23 @@ static void init_kickstart (HWND hDlg)
        SendDlgItemMessage(hDlg, IDC_SCSIROMSELECT, CB_RESETCONTENT, 0, 0);
        scsiromselect_table[0] = -1;
        for (int i = 0; expansionroms[i].name; i++) {
+               TCHAR name[256];
                if (expansionroms[i].romtype & ROMTYPE_CPUBOARD)
                        continue;
                if (first < 0)
                        first = i;
-               gui_add_string(scsiromselect_table, hDlg, IDC_SCSIROMSELECT, i, expansionroms[i].friendlyname);
+               if (expansionroms[i].friendlymanufacturer) {
+                       _tcscpy(name, expansionroms[i].friendlymanufacturer);
+                       _tcscat(name, _T(" "));
+               }
+               _tcscat(name, expansionroms[i].friendlyname);
+               gui_add_string(scsiromselect_table, hDlg, IDC_SCSIROMSELECT, i, name);
+       }
+       SendDlgItemMessage(hDlg, IDC_SCSIROMSELECTNUM, CB_RESETCONTENT, 0, 0);
+       for (int i = 0; i < MAX_DUPLICATE_EXPANSION_BOARDS; i++) {
+               TCHAR tmp[10];
+               _stprintf(tmp, _T("%d"), i + 1);
+               SendDlgItemMessage(hDlg, IDC_SCSIROMSELECTNUM, CB_ADDSTRING, 0, (LPARAM)tmp);
        }
 
        int found = -1;
@@ -8814,7 +8842,7 @@ static void init_kickstart (HWND hDlg)
                int romtype = expansionroms[i].romtype;
                if (romtype & ROMTYPE_CPUBOARD)
                        continue;
-               if (cfgfile_board_enabled(&workprefs, romtype)) {
+               if (cfgfile_board_enabled(&workprefs, romtype, 0)) {
                        if (found == -1)
                                found = i;
                        else
@@ -8827,6 +8855,7 @@ static void init_kickstart (HWND hDlg)
                scsiromselected = found;
                gui_set_string_cursor(scsiromselect_table, hDlg, IDC_SCSIROMSELECT, scsiromselected);
        }
+       SendDlgItemMessage(hDlg, IDC_SCSIROMSELECTNUM, CB_SETCURSEL, scsiromselectednum, 0);
 
        if (!regexiststree(NULL, _T("DetectedROMs")))
                scan_roms (NULL, rp_isactive () ? 0 : 1);
@@ -8923,14 +8952,18 @@ static INT_PTR CALLBACK KickstartDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LP
                                values_from_kickstartdlg (hDlg);
                                values_to_kickstartdlg_autoboot(hDlg);
                                break;
+                       case IDC_SCSIROMSELECTNUM:
                        case IDC_SCSIROMSELECT:
-                       val = gui_get_string_cursor(scsiromselect_table, hDlg, IDC_SCSIROMSELECT);      
+                               val = SendDlgItemMessage (hDlg, IDC_SCSIROMSELECTNUM, CB_GETCURSEL, 0, 0);
+                               if (val != CB_ERR)
+                                       scsiromselectednum = val;
+                               val = gui_get_string_cursor(scsiromselect_table, hDlg, IDC_SCSIROMSELECT);      
                                if (val != CB_ERR) {
                                        int index;
                                        struct boardromconfig *brc;
                                        UAEREG *fkey = regcreatetree (NULL, _T("DetectedROMs"));
                                        scsiromselected = val;
-                                       brc = get_device_rom(&workprefs, expansionroms[scsiromselected].romtype, &index);
+                                       brc = get_device_rom(&workprefs, expansionroms[scsiromselected].romtype, scsiromselectednum, &index);
                                        addromfiles (fkey, hDlg, IDC_SCSIROMFILE, brc ? brc->roms[index].romfile : NULL,
                                                expansionroms[scsiromselected].romtype, 0);
                                        values_to_kickstartdlg_autoboot(hDlg);
@@ -10655,11 +10688,34 @@ static void sethardfile (HWND hDlg)
        hide (hDlg, IDC_HDF_AUTOBOOT, !disables);
        hide (hDlg, IDC_HDF_DONOTMOUNT, !disables);
        ew (hDlg, IDC_HARDFILE_BOOTPRI, disables);
-       gui_set_string_cursor(hdmenutable, hDlg, IDC_HDF_CONTROLLER, current_hfdlg.ci.controller_type);
+       gui_set_string_cursor(hdmenutable, hDlg, IDC_HDF_CONTROLLER, current_hfdlg.ci.controller_type +  current_hfdlg.ci.controller_type_unit * HD_CONTROLLER_NEXT_UNIT);
        SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER_UNIT, CB_SETCURSEL, current_hfdlg.ci.controller_unit, 0);
 }
 
-static void inithdcontroller (HWND hDlg, int ctype, int devtype)
+static void addhdcontroller(HWND hDlg, const struct expansionromtype *erc, int *hdmenutable, int firstid)
+{
+       TCHAR name[MAX_DPATH];
+       _tcscpy(name, erc->friendlymanufacturer);
+       _tcscat(name, _T(" "));
+       _tcscat(name, erc->friendlyname);
+       if (workprefs.cpuboard_type && erc->romtype == ROMTYPE_CPUBOARD) {
+               _tcscat(name, _T(" ("));
+               _tcscat(name, cpuboards[workprefs.cpuboard_type].subtypes[workprefs.cpuboard_subtype].name);
+               _tcscat(name, _T(")"));
+       }
+       if (get_boardromconfig(&workprefs, erc->romtype, NULL) || get_boardromconfig(&workprefs, erc->romtype_extra, NULL)) {
+               gui_add_string(hdmenutable, hDlg, IDC_HDF_CONTROLLER, firstid, name);
+               for (int j = 1; j < MAX_DUPLICATE_EXPANSION_BOARDS; j++) {
+                       if (cfgfile_board_enabled(&workprefs, erc->romtype, j)) {
+                               TCHAR tmp[MAX_DPATH];
+                               _stprintf(tmp, _T("%s [%d]"), name, j + 1);
+                               gui_add_string(hdmenutable, hDlg, IDC_HDF_CONTROLLER, firstid + j * HD_CONTROLLER_NEXT_UNIT, tmp);
+                       }
+               }
+       }
+}
+
+static void inithdcontroller (HWND hDlg, int ctype, int ctype_unit, int devtype)
 {
        hdmenutable[0] = -1;
        
@@ -10674,16 +10730,7 @@ static void inithdcontroller (HWND hDlg, int ctype, int devtype)
        for (int i = 0; expansionroms[i].name; i++) {
                const struct expansionromtype *erc = &expansionroms[i];
                if (erc->deviceflags & EXPANSIONTYPE_IDE) {
-                       TCHAR tmp[MAX_DPATH];
-                       _tcscpy(tmp, erc->friendlyname);
-                       if (workprefs.cpuboard_type && erc->romtype == ROMTYPE_CPUBOARD) {
-                               _tcscat(tmp, _T(" ("));
-                               _tcscat(tmp, cpuboards[workprefs.cpuboard_type].subtypes[workprefs.cpuboard_subtype].name);
-                               _tcscat(tmp, _T(")"));
-                       }
-//                     if (get_boardromconfig(&workprefs, erc->romtype, NULL) || get_boardromconfig(&workprefs, erc->romtype_extra, NULL)) {
-                               gui_add_string(hdmenutable, hDlg, IDC_HDF_CONTROLLER, HD_CONTROLLER_TYPE_IDE_EXPANSION_FIRST + i, tmp);
-//                     }
+                       addhdcontroller(hDlg, erc, hdmenutable, HD_CONTROLLER_TYPE_IDE_EXPANSION_FIRST + i);
                }
        }
 
@@ -10696,16 +10743,7 @@ static void inithdcontroller (HWND hDlg, int ctype, int devtype)
        for (int i = 0; expansionroms[i].name; i++) {
                const struct expansionromtype *erc = &expansionroms[i];
                if (erc->deviceflags & EXPANSIONTYPE_SCSI) {
-                       TCHAR tmp[MAX_DPATH];
-                       _tcscpy(tmp, erc->friendlyname);
-                       if (workprefs.cpuboard_type && erc->romtype == ROMTYPE_CPUBOARD) {
-                               _tcscat(tmp, _T(" ("));
-                               _tcscat(tmp, cpuboards[workprefs.cpuboard_type].subtypes[workprefs.cpuboard_subtype].name);
-                               _tcscat(tmp, _T(")"));
-                       }
-//                     if (get_boardromconfig(&workprefs, erc->romtype, NULL) || get_boardromconfig(&workprefs, erc->romtype_extra, NULL)) {
-                               gui_add_string(hdmenutable, hDlg, IDC_HDF_CONTROLLER, HD_CONTROLLER_TYPE_SCSI_EXPANSION_FIRST + i, tmp);
-//                     }
+                       addhdcontroller(hDlg, erc, hdmenutable, HD_CONTROLLER_TYPE_SCSI_EXPANSION_FIRST + i);
                }
        }
 
@@ -10713,7 +10751,7 @@ static void inithdcontroller (HWND hDlg, int ctype, int devtype)
        gui_add_string(hdmenutable, hDlg, IDC_HDF_CONTROLLER, HD_CONTROLLER_TYPE_PCMCIA_SRAM, _T("PCMCIA SRAM"));
        gui_add_string(hdmenutable, hDlg, IDC_HDF_CONTROLLER, HD_CONTROLLER_TYPE_PCMCIA_IDE, _T("PCMCIA IDE"));
 
-       gui_set_string_cursor(hdmenutable, hDlg, IDC_HDF_CONTROLLER, ctype);
+       gui_set_string_cursor(hdmenutable, hDlg, IDC_HDF_CONTROLLER, ctype + ctype_unit * HD_CONTROLLER_NEXT_UNIT);
 
        SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER_UNIT, CB_RESETCONTENT, 0, 0);
        if (ctype >= HD_CONTROLLER_TYPE_IDE_FIRST && ctype <= HD_CONTROLLER_TYPE_SCSI_LAST) {
@@ -10741,7 +10779,7 @@ static void inithardfile (HWND hDlg)
 
        ew (hDlg, IDC_HF_DOSTYPE, FALSE);
        ew (hDlg, IDC_HF_CREATE, FALSE);
-       inithdcontroller (hDlg, current_hfdlg.ci.controller_type, UAEDEV_HDF);
+       inithdcontroller (hDlg, current_hfdlg.ci.controller_type, current_hfdlg.ci.controller_type_unit, UAEDEV_HDF);
        SendDlgItemMessage (hDlg, IDC_HF_TYPE, CB_RESETCONTENT, 0, 0);
        WIN32GUI_LoadUIString (IDS_HF_FS_CUSTOM, tmp, sizeof (tmp) / sizeof (TCHAR));
        SendDlgItemMessage (hDlg, IDC_HF_TYPE, CB_ADDSTRING, 0, (LPARAM)_T("RDB/OFS/FFS"));
@@ -10920,7 +10958,7 @@ static INT_PTR CALLBACK TapeDriveSettingsProc (HWND hDlg, UINT msg, WPARAM wPara
                recursive++;
                if (current_tapedlg.ci.controller_type < HD_CONTROLLER_TYPE_SCSI_AUTO)
                        current_tapedlg.ci.controller_type = HD_CONTROLLER_TYPE_SCSI_AUTO;
-               inithdcontroller(hDlg, current_tapedlg.ci.controller_type, UAEDEV_TAPE);
+               inithdcontroller(hDlg, current_tapedlg.ci.controller_type, current_tapedlg.ci.controller_type_unit, UAEDEV_TAPE);
                SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER_UNIT, CB_SETCURSEL, current_tapedlg.ci.controller_unit, 0);
                setautocomplete (hDlg, IDC_PATH_NAME);
                addhistorymenu(hDlg, current_tapedlg.ci.rootdir, IDC_PATH_NAME, HISTORY_TAPE, false);
@@ -10951,8 +10989,9 @@ static INT_PTR CALLBACK TapeDriveSettingsProc (HWND hDlg, UINT msg, WPARAM wPara
                        case IDC_HDF_CONTROLLER:
                                posn = gui_get_string_cursor(hdmenutable, hDlg, IDC_HDF_CONTROLLER);
                                if (posn != CB_ERR) {
-                                       current_tapedlg.ci.controller_type = posn;
-                                       inithdcontroller(hDlg, current_tapedlg.ci.controller_type, UAEDEV_TAPE);
+                                       current_tapedlg.ci.controller_type = posn % HD_CONTROLLER_NEXT_UNIT;
+                                       current_tapedlg.ci.controller_type_unit = posn / HD_CONTROLLER_NEXT_UNIT;
+                                       inithdcontroller(hDlg, current_tapedlg.ci.controller_type, current_tapedlg.ci.controller_type_unit, UAEDEV_TAPE);
                                        SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER_UNIT, CB_SETCURSEL, current_tapedlg.ci.controller_unit, 0);
                                }
                                break;
@@ -11024,11 +11063,11 @@ static INT_PTR CALLBACK CDDriveSettingsProc (HWND hDlg, UINT msg, WPARAM wParam,
        case WM_INITDIALOG:
                recursive++;
                if (current_cddlg.ci.controller_type == HD_CONTROLLER_TYPE_UAE)
-                       current_cddlg.ci.controller_type = (cfgfile_board_enabled(&workprefs, ROMTYPE_A2091) ||
-                       cfgfile_board_enabled(&workprefs, ROMTYPE_GVPS2) || cfgfile_board_enabled(&workprefs, ROMTYPE_A4091) ||
+                       current_cddlg.ci.controller_type = (cfgfile_board_enabled(&workprefs, ROMTYPE_A2091, 0) ||
+                       cfgfile_board_enabled(&workprefs, ROMTYPE_GVPS2, 0) || cfgfile_board_enabled(&workprefs, ROMTYPE_A4091, 0) ||
                        workprefs.cs_cdtvscsi ||
                        (workprefs.cs_mbdmac & 3)) ? HD_CONTROLLER_TYPE_SCSI_AUTO : HD_CONTROLLER_TYPE_IDE_AUTO;
-               inithdcontroller(hDlg, current_cddlg.ci.controller_type, UAEDEV_CD);
+               inithdcontroller(hDlg, current_cddlg.ci.controller_type, current_cddlg.ci.controller_type_unit, UAEDEV_CD);
                SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER_UNIT, CB_SETCURSEL, current_cddlg.ci.controller_unit, 0);
                InitializeListView (hDlg);
                recursive--;
@@ -11057,8 +11096,9 @@ static INT_PTR CALLBACK CDDriveSettingsProc (HWND hDlg, UINT msg, WPARAM wParam,
                case IDC_HDF_CONTROLLER:
                        posn = gui_get_string_cursor(hdmenutable, hDlg, IDC_HDF_CONTROLLER);
                        if (posn != CB_ERR) {
-                               current_cddlg.ci.controller_type = posn;
-                               inithdcontroller(hDlg, current_cddlg.ci.controller_type, UAEDEV_CD);
+                               current_cddlg.ci.controller_type = posn % HD_CONTROLLER_NEXT_UNIT;
+                               current_cddlg.ci.controller_type_unit = posn / HD_CONTROLLER_NEXT_UNIT;
+                               inithdcontroller(hDlg, current_cddlg.ci.controller_type, current_cddlg.ci.controller_type_unit, UAEDEV_CD);
                                SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER_UNIT, CB_SETCURSEL, current_cddlg.ci.controller_unit, 0);
                        }
                        break;
@@ -11144,8 +11184,9 @@ static INT_PTR CALLBACK HardfileSettingsProc (HWND hDlg, UINT msg, WPARAM wParam
                        case IDC_HDF_CONTROLLER:
                                posn = gui_get_string_cursor(hdmenutable, hDlg, IDC_HDF_CONTROLLER);
                                if (posn != CB_ERR) {
-                                       current_hfdlg.ci.controller_type = posn;
-                                       inithdcontroller(hDlg, current_hfdlg.ci.controller_type, UAEDEV_HDF);
+                                       current_hfdlg.ci.controller_type = posn % HD_CONTROLLER_NEXT_UNIT;
+                                       current_hfdlg.ci.controller_type_unit = posn / HD_CONTROLLER_NEXT_UNIT;
+                                       inithdcontroller(hDlg, current_hfdlg.ci.controller_type, current_hfdlg.ci.controller_type_unit, UAEDEV_HDF);
                                        sethardfile(hDlg);
                                }
                                break;
@@ -11300,7 +11341,7 @@ static INT_PTR CALLBACK HarddriveSettingsProc (HWND hDlg, UINT msg, WPARAM wPara
                        oposn = -1;
                        hdf_init_target ();
                        recursive++;
-                       inithdcontroller(hDlg, current_hfdlg.ci.controller_type, UAEDEV_HDF);
+                       inithdcontroller(hDlg, current_hfdlg.ci.controller_type, current_hfdlg.ci.controller_type_unit, UAEDEV_HDF);
                        CheckDlgButton (hDlg, IDC_HDF_RW, !current_hfdlg.ci.readonly);
                        SendDlgItemMessage (hDlg, IDC_HARDDRIVE, CB_RESETCONTENT, 0, 0);
                        ew (hDlg, IDC_HARDDRIVE_IMAGE, FALSE);
@@ -11317,7 +11358,7 @@ static INT_PTR CALLBACK HarddriveSettingsProc (HWND hDlg, UINT msg, WPARAM wPara
                        }
                        if (index >= 0) {
                                SendDlgItemMessage (hDlg, IDC_HARDDRIVE, CB_SETCURSEL, index, 0);
-                               gui_set_string_cursor(hdmenutable, hDlg, IDC_HDF_CONTROLLER, current_hfdlg.ci.controller_type);
+                               gui_set_string_cursor(hdmenutable, hDlg, IDC_HDF_CONTROLLER, current_hfdlg.ci.controller_type + current_hfdlg.ci.controller_type_unit * HD_CONTROLLER_NEXT_UNIT);
                                SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER_UNIT, CB_SETCURSEL, current_hfdlg.ci.controller_unit, 0);
                        }
                        recursive--;
@@ -11373,7 +11414,7 @@ static INT_PTR CALLBACK HarddriveSettingsProc (HWND hDlg, UINT msg, WPARAM wPara
                                        SetDlgItemText (hDlg, IDC_HDFINFO, _T(""));
                                        SetDlgItemText (hDlg, IDC_HDFINFO2, _T(""));
                                        updatehdfinfo (hDlg, true, true);
-                                       gui_set_string_cursor(hdmenutable, hDlg, IDC_HDF_CONTROLLER, current_hfdlg.ci.controller_type);
+                                       gui_set_string_cursor(hdmenutable, hDlg, IDC_HDF_CONTROLLER, current_hfdlg.ci.controller_type + current_hfdlg.ci.controller_type_unit * MAX_DUPLICATE_EXPANSION_BOARDS);
                                        SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER_UNIT, CB_SETCURSEL, current_hfdlg.ci.controller_unit, 0);
                                        CheckDlgButton(hDlg, IDC_HDF_RW, !current_hfdlg.ci.readonly);
                                        _tcscpy (current_hfdlg.ci.rootdir, hdf_getnameharddrive ((int)posn, 4, &current_hfdlg.ci.blocksize, NULL));
@@ -11382,13 +11423,14 @@ static INT_PTR CALLBACK HarddriveSettingsProc (HWND hDlg, UINT msg, WPARAM wPara
                } else if (LOWORD (wParam) == IDC_HDF_CONTROLLER) {
                        posn = gui_get_string_cursor(hdmenutable, hDlg, IDC_HDF_CONTROLLER);
                        if (posn != CB_ERR && current_hfdlg.ci.controller_type != posn) {
-                               current_hfdlg.ci.controller_type = posn;
+                               current_hfdlg.ci.controller_type = posn % HD_CONTROLLER_NEXT_UNIT;
+                               current_hfdlg.ci.controller_type_unit = posn / HD_CONTROLLER_NEXT_UNIT;
                                current_hfdlg.forcedcylinders = 0;
                                current_hfdlg.ci.cyls = current_hfdlg.ci.highcyl = current_hfdlg.ci.sectors = current_hfdlg.ci.surfaces = 0;
                                SetDlgItemText (hDlg, IDC_HDFINFO, _T(""));
                                SetDlgItemText (hDlg, IDC_HDFINFO2, _T(""));
                                updatehdfinfo (hDlg, true, true);
-                               inithdcontroller(hDlg, current_hfdlg.ci.controller_type, UAEDEV_HDF);
+                               inithdcontroller(hDlg, current_hfdlg.ci.controller_type, current_hfdlg.ci.controller_type_unit, UAEDEV_HDF);
                                SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER_UNIT, CB_SETCURSEL, current_hfdlg.ci.controller_unit, 0);
                        }
                } else if (LOWORD(wParam) == IDC_HDF_CONTROLLER_UNIT) {
index 9bdab0e7d1358b76570810ebcda686b69a9620c7..7ccbaea1f411d557bdd1fa1c3f18e74303e0318b 100644 (file)
@@ -1,4 +1,113 @@
 
+Beta 12:
+
+- Do not force full display reset when switching to/from programmed mode and autoresolution is active
+  and mode is D3D. (D3D can switch display buffer size without closing existing window)
+- Added config file option to force UAE boot ROM active even if current configuration does not need it.
+  boot_rom_uae=automatic/disabled/min/full. automatic (or line not included)=normal default, disabled=always
+  disabled (all features that require uae boot rom stop working), min=only add old-style $F0FFxx traps).
+- Serial port emulation (if connected to real serial port) lost characters if transmit speed was fast enough.
+  Broken since 2810b4.
+- Raw SCSI emulation improvements and updates.
+- WD33C93 emulation didn't allow use of select and transfer to split single transfer in multiple pieces.
+- Kupke Golem SCSI emulation.
+- Microbotics A1000 StarBoard 2 StarDrive SCSI expansion board emulation.
+- J.Kommos A500 SCSI emulation, 1.8 rom added. 
+- Vector Falcon 8000 emulation. ROM created from disk based driver.
+- M-Tec AT 500 emulation.
+- Protar A500 HD emulation.
+- Added AdIDE 40/44 emulation.
+- Masoboshi SCSI read access works again, writes are still broken. (Driver is strange, it uses code path
+  that simply can't work, writes 16 extra bytes. There is another code path that looks correct but there
+  are lots of unknown variables that are set here and there..)
+- Kupke Golem 030 A500 accelerator and boot rom added ("68030 Autoconfig (17-FEB-91) V1.0 ET")
+- Added manufacturer names to HD controller selection.
+- Reorganized internal accelerator board handling.
+- GVP Series I ROM and buffer RAM mirrors now 100% match real hardware.
+- Memwatch points didn't work with autoconfig address bank.
+- Refactored expansion board handling yet again, multiple identical boards are supported again.
+- Added GUI support for multiple identical HD controller boards. Current max is 4 boards.
+- Selecting some accelerator ROM file (for example CS MK I and II) also added it to cart rom file.
+- Show only mainboard HD controllers and enabled (ROM selected) expansion controllers in HD controller
+  selection list. (CDTV and some others are not yet hidden, much more work to do, later..)
+- Added "Velvet" A1000 prototype to chipset selection. Floppy IO lines are not hooked to CIA chips
+  correctly, probably lots of other minor changes that are not known yet are not emulated.
+- Show floppy image's original file name in status bar even if file needed decompression or converting.
+
+Microbotics StarDrive SCSI:
+- A1000 StarBoard 2 RAM expansion optional HD controller module.
+- Text based partitioning software.
+- 5380 based, no autoboot ROM, no RDB support.
+- Clock not emulated.
+
+M-Tec AT 500:
+- 1.33 ROM added. "mtec-at500.device mtec-at500 1.33w (08 July 1993)"
+  "(c) Hardware Design Udo Neuroth, Bottrop, Dieter Niewerth, 1992 1993"
+
+AdIDE:
+- 68000 socket.
+- Uses custom data bit swapping (drive partitioned with AdIDE won't work in any other IDE controller and
+  vice versa), emulation will automatically read/write non-swapped data.
+- Uses RDB but does not seem to be fully compatible, other controller partitioned drives don't mount.
+- ROM was software dumped, real chip probably has swapped address or data lines similar to IDE data lines.
+
+Kupke Golem SCSI:
+- Fake dma interface.
+- Tested with 3.8 and 3.9 drivers. 3.9 rom added.
+
+Protar A500 HD:
+- ROM only has small loader code, loads driver from HD. (If drive is unformatted, press mouse button
+  to boot from floppy)
+- 8490 chip (improved version of 5380). 8490 extra features not emulated, at least Protar driver does
+  not use them.
+- ROM added, unknown version. There probably is later version because only 1.4 (1.x?) boot disks
+  detect the hardware.
+
+J.Kommos A500 SCSI:
+- Strange non-autoconfig autobooting HD controller, uses cartridge ROM space.
+- Byte-based fake dma.
+- Boot HD detection screen.
+- Not RDB compatible.
+- ROM includes 36.3 FastFileSystem handler.
+- jkscsi.device, "Autoboot SCSI-HardDisk By J.Kommos Date: 25.07.1990".
+
+Vector Falcon 8000:
+- Improved version of Kommos SCSI.
+- More or less functionally same as Kommos but most glue TTL chips and GALs put in single FPGA-like chip.
+- Long word/word based fake DMA.
+- More colorful boot HD detection screen.
+- vector.device. "Autoconfig 16 Bit SCSI + CD-ROM Driver (©) by J.Kommos V7.1 - 11.08.1993"
+- ROM includes CD ROM filesystem.
+- Bad filesystem loader: must be single hunk, only loads filesystems if KS 1.3, ignores all relocation
+  hunks.
+
+Beta 11:
+
+- Supra HD autoconfig state was not reset when system was reset.
+- 68000 bus/address error stack frame I/N bit emulated, added better check for odd stack in exception stack frame
+  writes. Also added helpers for bus error checks for platforms that need it (UAE 68k emulator is also used by
+  Hatari) I don't know any program (or protection) that uses it but crashing/buggy programs may trigger it.
+- Show also currently selected accelerator board in harddrive controller selection.
+- Toccata capture support, not tested. Uses WASAPI (=Vista or newer only) and uses Windows default
+  recording device, not configurable yet. First tries to allocate exclusive mode, if it fails, retries with
+  shared mode. Note that only exclusive mode allows configurable sampling frequency, shared uses value set in
+  Windows recording sound control panel.
+- Tweaked A590/A2091 DMAC interrupt handling and DMAC-01 DMA transfer counter emulation.
+- Added Kupke Golem v3.9 ROM image, not emulated, Golem does not use any SCSI chips, it is very
+  difficult to guess function of each IO address.
+- CDTV SCSI works again, broke when A2090 support was added.
+- A26x0 J304 jumper emulation fixed. It should not be active anymore after autoconfig io gets enabled.
+- Added rare SupraDrive 2000 DMA emulation. Boot ROM are not available, some supra install disks have on-disk
+  loadable driver which has bug in 2000 DMA model specific code that causes it to hang (uses wrong address
+  register, overwrites one inportant byte in interrupt handler code..) Perfect.
+  AMAB6 ROM is selectable in rom select box but it is not compatible with 2000 DMA.
+  (Thanks to mark_k for HD driver disassembling and examination)
+- Non-image CD last available block number calculation changed, do not trust geometry Windows returns.
+  (Fixes OS41FE install error)
+- Fixed OS41FE RTG graphics mode switch crash. (Check Cirrus Logic VRAM bounds before calling redraw routines,
+  apparently driver first switches mode, then sets new display offset, this can cause temporary out of bounds
+  access in emulation)
+
 Beta 10:
 
 - Added hd controller subtype selection.
index 25dd9fd1c4f191e51bc27ef1cf70034902f66ea0..85984eaeabe8396fbb392424c07cbe7a5088117f 100644 (file)
@@ -10,6 +10,7 @@
 #include "custom.h"
 #include "uae.h"
 #include "gui.h"
+#include "autoconf.h"
 #include "uae/dlopen.h"
 
 #include "uae/ppc.h"
index 5172368bc3d15945cfd00a1cfb66c47f935baf18..5a22311f9ac0484e1d1583c8aaf91804fac86728 100644 (file)
@@ -95,7 +95,7 @@ struct romdata *getromdatabypath (const TCHAR *path)
        return NULL;
 }
 
-#define NEXT_ROM_ID 126
+#define NEXT_ROM_ID 132
 
 static struct romheader romheaders[] = {
        { _T("Freezer Cartridges"), 1 },
@@ -295,91 +295,105 @@ static struct romdata roms[] = {
        { _T("Freezer: HRTMon v2.33 (built-in)"), 0, 0, 0, 0, _T("HRTMON\0"), 0, 63, 0, 0, ROMTYPE_HRTMON, 0, 1, NULL,
        0xffffffff, 0, 0, 0, 0, 0, _T("HRTMon") },
 
-       { _T("A2090a ROM"), 0, 0, 0, 0, _T("A2090A\0"), 16384, 122, 0, 0, ROMTYPE_A2090, 0, 0, NULL,
+       { _T("A2090a"), 0, 0, 0, 0, _T("A2090A\0"), 16384, 122, 0, 0, ROMTYPE_A2090, 0, 0, NULL,
        0x73fe45a7, 0x77ce9091,0x4be5a3bf,0x6f26b343,0x062b5bd8,0xc63c3754 },
        ALTROMPN(122, 1, 1, 8192, ROMTYPE_ODD  | ROMTYPE_8BIT, _T("315097-01"), 0x150b116c,0x8011d873,0x3be53db0,0x79dfe319,0x7ffb8634,0x1baa6dbd)
        ALTROMPN(122, 1, 2, 8192, ROMTYPE_EVEN | ROMTYPE_8BIT, _T("315098-01"), 0xbe422e3b,0x64ad1646,0x030db10f,0x54f13f64,0x7d449e4d,0x17f9ab5c)
-       { _T("A590/A2091 ROM 6.0"), 6, 0, 6, 0, _T("A590\0A2091\0"), 16384, 53, 0, 0, ROMTYPE_A2091, 0, 0, NULL,
+       { _T("A590/A2091 6.0"), 6, 0, 6, 0, _T("A590\0A2091\0"), 16384, 53, 0, 0, ROMTYPE_A2091, 0, 0, NULL,
        0x8396cf4e, 0x5E03BC61,0x8C862ABE,0x7BF79723,0xB4EEF4D2,0x1859A0F2 },
        ALTROMPN(53, 1, 1, 8192, ROMTYPE_ODD  | ROMTYPE_8BIT, _T("390389-03"), 0xb0b8cf24,0xfcf40175,0x05f4d441,0x814b45d5,0x59c19eab,0x43816b30)
        ALTROMPN(53, 1, 2, 8192, ROMTYPE_EVEN | ROMTYPE_8BIT, _T("390388-03"), 0x2e77bbff,0x8a098845,0x068f32cf,0xa4d34a27,0x8cd290f6,0x1d35a52c)
-       { _T("A590/A2091 ROM 6.6"), 6, 6, 6, 6, _T("A590\0A2091\0"), 16384, 54, 0, 0, ROMTYPE_A2091, 0, 0, NULL,
+       { _T("A590/A2091 6.6"), 6, 6, 6, 6, _T("A590\0A2091\0"), 16384, 54, 0, 0, ROMTYPE_A2091, 0, 0, NULL,
        0x33e00a7a, 0x739BB828,0xE874F064,0x9360F59D,0x26B5ED3F,0xBC99BB66 },
        ALTROMPN(54, 1, 1, 8192, ROMTYPE_ODD  | ROMTYPE_8BIT, _T("390722-02"), 0xe536bbb2,0xfd7f8a6d,0xa18c1b02,0xd07eb990,0xc2467a24,0x183ede12)
        ALTROMPN(54, 1, 2, 8192, ROMTYPE_EVEN | ROMTYPE_8BIT, _T("390721-02"), 0xc0871d25,0xe155f18a,0xbb90cf82,0x0589c15e,0x70559d3b,0x6b391af8)
-       { _T("A590/A2091 ROM 7.0"), 7, 0, 7, 0, _T("A590\0A2091\0"), 16384, 55, 0, 0, ROMTYPE_A2091, 0, 0, NULL,
+       { _T("A590/A2091 7.0"), 7, 0, 7, 0, _T("A590\0A2091\0"), 16384, 55, 0, 0, ROMTYPE_A2091, 0, 0, NULL,
        0x714a97a2, 0xE50F01BA,0xF2899892,0x85547863,0x72A82C33,0x3C91276E },
        ALTROMPN(55, 1, 1, 8192, ROMTYPE_ODD  | ROMTYPE_8BIT, _T("390722-03"), 0xa9ccffed,0x149f5bd5,0x2e2d2990,0x4e3de483,0xb9ad7724,0x48e9278e)
        ALTROMPN(55, 1, 2, 8192, ROMTYPE_EVEN | ROMTYPE_8BIT, _T("390721-03"), 0x2942747a,0xdbd7648e,0x79c75333,0x7ff3e4f4,0x91de224b,0xf05e6bb6)
        { _T("A590/A2091 Guru ROM 6.14"), 6, 14, 6, 14, _T("A590\0A2091\0"), 32768, 56, 0, 0, ROMTYPE_A2091, 0, 0, NULL,
        0x04e52f93, 0x6DA21B6F,0x5E8F8837,0xD64507CD,0x8A4D5CDC,0xAC4F426B },
-       { _T("A4091 ROM 40.9"), 40, 9, 40, 9, _T("A4091\0"), 32768, 57, 0, 0, ROMTYPE_A4091, 0, 0, NULL,
+       { _T("A4091 40.9"), 40, 9, 40, 9, _T("A4091\0"), 32768, 57, 0, 0, ROMTYPE_A4091, 0, 0, NULL,
        0x00000000, 0, 0, 0, 0, 0 },
-       { _T("A4091 ROM 40.13"), 40, 13, 40, 13, _T("A4091\0"), 32768, 58, 0, 0, ROMTYPE_A4091, 0, 0, _T("391592-02"),
+       { _T("A4091 40.13"), 40, 13, 40, 13, _T("A4091\0"), 32768, 58, 0, 0, ROMTYPE_A4091, 0, 0, _T("391592-02"),
        0x54cb9e85, 0x3CE66919,0xF6FD6797,0x4923A12D,0x91B730F1,0xFFB4A7BA },
        { _T("SupraDrive AMAB6"), 3, 8, 3, 8, _T("SUPRA\0"), 16384, 121, 0, 0, ROMTYPE_SUPRA, 0, 0, _T("AMAB6"),
        0xf40bd349, 0x82168556,0x07525067,0xe9263431,0x1fb9c347,0xe737f247 },
 
-       { _T("Blizzard 1230-IV ROM"), 0, 0, 0, 0, _T("B1230\0"), 32768, 89, 0, 0, ROMTYPE_CB_BLIZ1230, 0, 0, NULL,
+       { _T("Blizzard 1230-IV"), 0, 0, 0, 0, _T("B1230\0"), 32768, 89, 0, 0, ROMTYPE_CB_BLIZ1230, 0, 0, NULL,
        0x3078dbdc, 0x4d3e7fd0,0xa1a4c3ae,0xe17c5de3,0xcbe1af03,0x447aff92 },
-       { _T("Blizzard 1240/1260 ROM"), 0, 0, 0, 0, _T("B1240\0B1260\0"), 32768, 90, 0, 0, ROMTYPE_CB_BLIZ1260, 0, 0, NULL,
+       { _T("Blizzard 1240/1260"), 0, 0, 0, 0, _T("B1240\0B1260\0"), 32768, 90, 0, 0, ROMTYPE_CB_BLIZ1260, 0, 0, NULL,
        0xf88ae0f1, 0xf69aca4b,0xb13e3389,0x04676f0c,0x8616f8db,0x074c313d },
-       { _T("Blizzard 2060 ROM"), 8, 5, 8, 5, _T("B2060\0"), 65536, 92, 0, 0, ROMTYPE_CB_BLIZ2060, 0, 0, NULL,
+       { _T("Blizzard 2060"), 8, 5, 8, 5, _T("B2060\0"), 65536, 92, 0, 0, ROMTYPE_CB_BLIZ2060, 0, 0, NULL,
        0xce270bc0, 0xe043c1aa,0x3bb06e06,0xd4dabff3,0x0a8c6317,0xabfef2bb },
        ALTROMPN(92, 1, 1, 32768, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0xa6023f20, 0xdfb048d6, 0xbdc03587, 0x241e8121, 0x26aba603, 0xd69b0238)
        ALTROMPN(92, 1, 2, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x9635a9cd, 0x47578b27, 0xc4ba6e54, 0x891930dd, 0xcb4b6a45, 0x5d6b31b2)
-       { _T("Blizzard SCSI Kit IV ROM"), 8, 5, 8, 5, _T("BSCSIIV\0"), 32768, 94, 0, 0, ROMTYPE_CPUBOARDEXT, 0, 0, NULL,
+       { _T("Blizzard SCSI Kit IV"), 8, 5, 8, 5, _T("BSCSIIV\0"), 32768, 94, 0, 0, ROMTYPE_CPUBOARDEXT, 0, 0, NULL,
        0xf53a0fca, 0xefe17ca5,0x88c44a7f,0x0f8c62be,0x20f23278,0xcfe06727, NULL, _T("blizzard_scsi_kit_iv.rom") },
-       { _T("Fastlane ROM"), 8, 5, 8, 5, _T("FASTLANE\0"), 20788, 102, 0, 0, ROMTYPE_FASTLANE, 0, 0, NULL,
+       { _T("Fastlane"), 8, 5, 8, 5, _T("FASTLANE\0"), 20788, 102, 0, 0, ROMTYPE_FASTLANE, 0, 0, NULL,
        0xe4f485a5, 0x20bf7de5,0x05e45d0a,0xc411cfd2,0x806d0fd8,0xe46276de, NULL, _T("fastlanez3.rom") },
-       { _T("Oktagon 2008 ROM"), 6, 12, 6, 12, _T("OKTAGON\0"), 32768, 103, 0, 0, ROMTYPE_OKTAGON, 0, 0, NULL,
+       { _T("Oktagon 2008"), 6, 12, 6, 12, _T("OKTAGON\0"), 32768, 103, 0, 0, ROMTYPE_OKTAGON, 0, 0, NULL,
        0xbb0d2f6a, 0x56c441fa,0x37d19339,0x3081b2e8,0xceae823b,0xc7e97e49, NULL, _T("oktagon2008.rom") },
-       { _T("Warp Engine A4000 ROM"), 0, 0, 0, 0, _T("WARPENGINE\0WARPENGINEA4000\0"), 32768, 93, 0, 0, ROMTYPE_CB_WENGINE, 0, 0, NULL,
+       { _T("Warp Engine A4000"), 0, 0, 0, 0, _T("WARPENGINE\0WARPENGINEA4000\0"), 32768, 93, 0, 0, ROMTYPE_CB_WENGINE, 0, 0, NULL,
        0x4deb574a, 0x6e6c95ff,0xe8448391,0xd36c5b68,0xc9065cb0,0x702a7d27 },
-       { _T("TekMagic 2040/2060 ROM"), 1, 0, 1, 0, _T("TEKMAGIC\0TEKMAGIC2040\0TEKMAGIC2060\0"), 65536, 104, 0, 0, ROMTYPE_CB_TEKMAGIC, 0, 0, NULL,
+       { _T("TekMagic 2040/2060"), 1, 0, 1, 0, _T("TEKMAGIC\0TEKMAGIC2040\0TEKMAGIC2060\0"), 65536, 104, 0, 0, ROMTYPE_CB_TEKMAGIC, 0, 0, NULL,
        0x9e9781d5, 0xf65b60d1,0x4300c50f,0x2ed17cf4,0x4dcfdef9,0x16697bc9, NULL,  _T("tekmagic2060.rom") },
        ALTROMPN(104, 1, 1, 32768, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0x888da4cf, 0x6ae85f3a, 0x65331ba4, 0xaaba67ae, 0x34763d70, 0x2bde0495)
        ALTROMPN(104, 1, 2, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0xaf1f47db, 0x28d5bed0, 0xbc517d46, 0x500e8159, 0x723e0b64, 0x4733c26a)
-       { _T("A2620/A2630 -07 ROM"), 0, 0, 0, 0, _T("A2620\0A2630\0"), 65536, 105, 0, 0, ROMTYPE_CB_A26x0, 0, 0, _T("390282-07/390283-07"),
+       { _T("A2620/A2630 -07"), 0, 0, 0, 0, _T("A2620\0A2630\0"), 65536, 105, 0, 0, ROMTYPE_CB_A26x0, 0, 0, _T("390282-07/390283-07"),
        0x169d80e9, 0x41f518cb,0x41c1dc1f,0xcc636383,0x20676af5,0x4969010c, NULL, NULL },
        ALTROMPN(105, 1, 1, 32768, ROMTYPE_ODD  | ROMTYPE_8BIT, _T("390282-07"), 0xf2904058, 0x33695119, 0x5fdf5d56, 0x095a696b, 0x0ba2641d, 0x334845df)
        ALTROMPN(105, 1, 2, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, _T("390283-07"), 0xf697d458, 0x09fe260b, 0x03784e87, 0x3351dbec, 0x5146a455, 0x814383d1)
-       { _T("A2620/A2630 -06 ROM"), 0, 0, 0, 0, _T("A2620\0A2630\0"), 65536, 106, 0, 0, ROMTYPE_CB_A26x0, 0, 0, _T("390282-06/390283-06"),
+       { _T("A2620/A2630 -06"), 0, 0, 0, 0, _T("A2620\0A2630\0"), 65536, 106, 0, 0, ROMTYPE_CB_A26x0, 0, 0, _T("390282-06/390283-06"),
        0xeb31fd9e, 0x2d6a5c68,0x1040f98d,0x7e63ad08,0x90da9e83,0x2b5c704d, NULL, NULL },
        ALTROMPN(106, 1, 1, 32768, ROMTYPE_ODD  | ROMTYPE_8BIT, _T("390282-06"), 0xd6ae582c, 0x47b3dea3, 0x31db76e6, 0x1380a3d6, 0x9f191657, 0xdd1cd4b3)
        ALTROMPN(106, 1, 2, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, _T("390283-06"), 0xcd379634, 0x65e251e2, 0xf6961c8e, 0x33a86c3d, 0x01248f70, 0xa159823b)
-       { _T("DKB 12x0 ROM"), 1, 23, 1, 23, _T("DKB\0"), 32768, 112, 0, 0, ROMTYPE_CB_DKB12x0, 0, 0, NULL,
+       { _T("DKB 12x0"), 1, 23, 1, 23, _T("DKB\0"), 32768, 112, 0, 0, ROMTYPE_CB_DKB12x0, 0, 0, NULL,
        0xf3b2b0b3, 0x1d539593,0xb1d7514e,0xeb214ab3,0x433a97fc,0x8a010366, NULL, NULL },
-       { _T("Fusion Forty ROM"), 0, 0, 0, 0, _T("FUSIONFORTY\0"), 131072, 113, 0, 0, ROMTYPE_CB_FUSION, 0, 0, NULL,
+       { _T("Fusion Forty"), 0, 0, 0, 0, _T("FUSIONFORTY\0"), 131072, 113, 0, 0, ROMTYPE_CB_FUSION, 0, 0, NULL,
        0x48fcb5fd, 0x15674dac,0x90b6d8db,0xdda3a175,0x997184c2,0xa423d733, NULL, NULL },
        ALTROMPN(113, 1, 1, 32768, ROMTYPE_QUAD | ROMTYPE_EVEN | ROMTYPE_8BIT, _T("U28"), 0x434a21a8, 0x472c1623, 0x02babd00, 0x7c1a77ff, 0x40dd12ab, 0x39c97f82)
        ALTROMPN(113, 1, 2, 32768, ROMTYPE_QUAD | ROMTYPE_ODD  | ROMTYPE_8BIT, _T("U27"), 0x38373cf6, 0xfe8aa931, 0xada6b6f3, 0x6b48ca3c, 0x9b86677d, 0xbee4da59)
        ALTROMPN(113, 1, 3, 32768, ROMTYPE_QUAD | ROMTYPE_EVEN | ROMTYPE_8BIT, _T("U25"), 0xc9e990d3, 0xb251ef73, 0x1374e796, 0xa87cbc7e, 0x9263320a, 0x28a71d2b)
        ALTROMPN(113, 1, 4, 32768, ROMTYPE_QUAD | ROMTYPE_ODD  | ROMTYPE_8BIT, _T("U26"), 0x2e117fe0, 0xbb2de2da, 0x6db4e92c, 0x636fefe6, 0x13a32699, 0xcea31011)
-       { _T("Apollo 1240/1260 ROM"), 5, 60, 5, 60, _T("APOLLO12XX\0"), 131072, 119, 0, 0, ROMTYPE_CB_APOLLO, 0, 0, NULL,
+       { _T("Apollo 1240/1260"), 5, 60, 5, 60, _T("APOLLO12XX\0"), 131072, 119, 0, 0, ROMTYPE_CB_APOLLO, 0, 0, NULL,
        0xcd009ad9, 0x1c3b4851,0xc5a221e3,0xa7ca24fc,0xc1df4a5b,0x9f2343ad },
-       { _T("GVP A3001 Series I ROM"), 3, 3, 3, 3, _T("A3001SI\0"), 8192, 114, 0, 0, ROMTYPE_CB_A3001S1, 0, 0, NULL,
+       { _T("GVP A3001 Series I"), 3, 3, 3, 3, _T("A3001SI\0"), 8192, 114, 0, 0, ROMTYPE_CB_A3001S1, 0, 0, NULL,
        0xaaff7c65, 0x424cf3da,0xcc9da794,0x0ba74446,0x69dd1691,0x44ae87ee, NULL, NULL },
-
-       { _T("Kupke Golem v3.9 ROM"), 3, 9, 3, 9, _T("GOLEM\0"), 16384, 124, 0, 0, ROMTYPE_GOLEM, 0, 0, NULL,
+       { _T("Kupke Golem 030"), 0, 0, 0, 0, _T("GOLEM030\0"), 8192, 126, 0, 0, ROMTYPE_CB_GOLEM030, 0, 0, NULL,
+       0x05d473f4, 0x574ec567,0xcc67e06f,0x91dcecb9,0x8c204399,0x5fe2a09f, NULL, NULL },
+
+       { _T("Protar A500HD"), 1, 193, 1, 193, _T("PROTAR\0"), 32768, 131, 0, 0, ROMTYPE_PROTAR, 0, 0, NULL,
+       0x10c1b22c, 0x2b800cde,0x79fd559e,0xebd5e432,0xd711af3d,0x0b8ea7e9, NULL, NULL },
+       { _T("M-Tec AT500"), 1, 33, 1, 33, _T("MTECAT\0"), 32768, 130, 0, 0, ROMTYPE_MTEC, 0, 0, NULL,
+       0x38b6b6b0, 0x8bb1093a,0xd592e7df,0x99c48f83,0xb9f842b2,0xb1a6e618, NULL, NULL },
+       { _T("AdIDE 40/44"), 34, 0, 34, 0, _T("ADIDE\0"), 16384, 129, 0, 0, ROMTYPE_ADIDE, 0, 0, NULL,
+       0xedf84cbe, 0xabdbc01d,0xaa0b3aae,0xe4401ad7,0xe65525a9,0x6bfa2b27, NULL, NULL },
+       { _T("Vector Falcon 8000"), 7, 1, 7, 1, _T("VECTOR\0"), 32768, 128, 0, 0, ROMTYPE_VECTOR, 0, 0, NULL,
+       0xa8120c55, 0x248935ab,0xf4d74036,0xefdafdbb,0x7817e232,0xfc13e0fa, NULL, NULL },
+       { _T("Kommos A500/A2000 SCSI"), 1, 8, 1, 8, _T("KOMMOS\0"), 32768, 127, 0, 0, ROMTYPE_KOMMOS, 0, 0, NULL,
+       0xc1a5c848, 0x291310f1,0x25455f2d,0x8e114bcd,0xe104ca4c,0x9db51747, NULL, NULL },
+       ALTROMPN(127, 1, 1, 16384, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0x1b86d2ed, 0x969995a1, 0x2ebf8c15, 0xab87e8d0, 0xddc837a1, 0xb90fbfa8)
+       ALTROMPN(127, 1, 2, 16384, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x65b4c3a0, 0x60e904d4, 0xe45bb6ba, 0x3e253ffa, 0xda4ee2e5, 0xc8548da1)
+       { _T("Kupke Golem v3.9"), 3, 9, 3, 9, _T("GOLEM\0"), 16384, 124, 0, 0, ROMTYPE_GOLEM, 0, 0, NULL,
        0x49157dd0, 0x03b615c9,0x2befa474,0xa37303ca,0xdc3e830d,0x3c0d9a9f, NULL, NULL },
        ALTROMPN(124, 1, 1, 8192, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0x713298ad, 0x2ad7d6f3, 0xd696fd2c, 0x51a256ee, 0xea185c47, 0x52906e04)
        ALTROMPN(124, 1, 2, 8192, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x88cf2ec5, 0x59680f8d, 0xae520893, 0xff9ada35, 0xac9a1146, 0x4f87453c)
-       { _T("GVP Series I v1.0 ROM"), 1, 0, 1, 16, _T("GVPI\0"), 16384, 123, 0, 0, ROMTYPE_GVPS1, 0, 0, NULL,
+       { _T("GVP Series I v1.0"), 1, 0, 1, 16, _T("GVPI\0"), 16384, 123, 0, 0, ROMTYPE_GVPS1, 0, 0, NULL,
        0x1a4c20aa, 0xb9a3377e,0x2d9b5163,0x28693c63,0x19ffb65b,0x40ae3618, NULL, NULL },
        ALTROMPN(123, 1, 1, 8192, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0xa723193e, 0x05b4a072, 0x785c7824, 0x54e003c3, 0x6d88bd9b, 0xf5f561b9)
        ALTROMPN(123, 1, 2, 8192, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x27f15785, 0x1a71a78d, 0xdd4e9559, 0x0f133bba, 0x4a71122f, 0x44caef78)
-       { _T("GVP Series I/II v3.15 ROM"), 3, 15, 3, 15, _T("GVPII\0GVPI\0"), 16384, 111, 0, 0, ROMTYPE_GVPS12, 0, 0, NULL,
+       { _T("GVP Series I/II v3.15"), 3, 15, 3, 15, _T("GVPII\0GVPI\0"), 16384, 111, 0, 0, ROMTYPE_GVPS12, 0, 0, NULL,
        0xf99c6f11, 0x77098a9e,0x35acaef2,0x11a546f0,0xc564cdac,0xf52836c4, NULL, NULL },
-       { _T("GVP Series II v4.15 ROM"), 4, 15, 4, 15, _T("GVPII\0"), 16384, 109, 0, 0, ROMTYPE_GVPS2, 0, 0, NULL,
+       { _T("GVP Series II v4.15"), 4, 15, 4, 15, _T("GVPII\0"), 16384, 109, 0, 0, ROMTYPE_GVPS2, 0, 0, NULL,
        0xf89f44d6, 0xbf10c12c,0xc72dd040,0x549ea17c,0x24947633,0xe3773297, NULL, NULL },
        { _T("GVP Series II Guru ROM"), 6, 14, 6, 14, _T("GVPII\0"), 32768, 110, 0, 0, ROMTYPE_GVPS2, 0, 0, NULL,
        0x756103b1, 0x7f1335ea,0xf5b7ce73,0xc5231173,0x261da5aa,0xe7249645, NULL, NULL },
-       { _T("AlfaPower v6.10 ROM"), 6, 10, 6, 10, _T("ALFAPOWER\0"), 32768, 117, 0, 0, ROMTYPE_ALFA, 0, 0, NULL,
+       { _T("AlfaPower v6.10"), 6, 10, 6, 10, _T("ALFAPOWER\0"), 32768, 117, 0, 0, ROMTYPE_ALFA, 0, 0, NULL,
        0x1cfb0a0b, 0xc7275eda,0x547d6664,0x5c4eb7a0,0x3b5cef37,0xa498365a, NULL, NULL },
-       { _T("AlfaPower v8.3 ROM"), 8, 3, 8, 3, _T("ALFAPOWERPLUS\0"), 32768, 118, 0, 0, ROMTYPE_ALFAPLUS, 0, 0, NULL,
+       { _T("AlfaPower v8.3"), 8, 3, 8, 3, _T("ALFAPOWERPLUS\0"), 32768, 118, 0, 0, ROMTYPE_ALFAPLUS, 0, 0, NULL,
        0xe8201bad, 0xdefea015,0x596fce32,0x11e84397,0x23046a31,0x5a7726dc, NULL, NULL },
-       { _T("Masoboshi MC-702 ROM"), 2, 201, 2, 201, _T("MASOBOSHI\0"), 32768, 120, 0, 0, ROMTYPE_MASOBOSHI, 0, 0, NULL,
+       { _T("Masoboshi MC-702"), 2, 201, 2, 201, _T("MASOBOSHI\0"), 32768, 120, 0, 0, ROMTYPE_MASOBOSHI, 0, 0, NULL,
        0xcd99b98a, 0x3897e46a,0x66d5833f,0x849b8e81,0x30acb3cb,0x319a2fa0, NULL, NULL },
 
        { _T("CyberStorm MK I 68040"), 0, 0, 0, 0, _T("CSMKI\0"), 32768, 95, 0, 0, ROMTYPE_CB_CSMK1, 0, 0, NULL,
@@ -397,7 +411,7 @@ static struct romdata roms[] = {
        { _T("Blizzard PPC 68060"), 0, 0, 0, 0, _T("BPPC\0"), 524288, 100, 0, 0, ROMTYPE_CB_BLIZPPC, 0, 0, NULL,
          0, 0, 0, 0, 0, 0, NULL, _T("blizzardppc_060.rom") },
 
-       { _T("Picasso IV ROM"), 7, 4, 7, 4, _T("PIV\0"), 131072, 91, 0, 0, ROMTYPE_PIV, 0, 0, NULL,
+       { _T("Picasso IV"), 7, 4, 7, 4, _T("PIV\0"), 131072, 91, 0, 0, ROMTYPE_PIV, 0, 0, NULL,
        0xa8133e7e, 0xcafafb91,0x6f16b9f3,0xec9b49aa,0x4b40eb4e,0xeceb5b5b },
 
        { _T("Arcadia OnePlay 2.11"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 49, 0, 0, ROMTYPE_ARCADIABIOS, 0, 0 },
@@ -1564,27 +1578,28 @@ int configure_rom (struct uae_prefs *p, const int *rom, int msg)
                _tcscpy (p->romfile, path);
        if (rd->type & (ROMTYPE_EXTCD32 | ROMTYPE_EXTCDTV | ROMTYPE_ARCADIABIOS))
                _tcscpy (p->romextfile, path);
-       if (rd->type & (ROMTYPE_CD32CART | ROMTYPE_ARCADIAGAME | ROMTYPE_HRTMON | ROMTYPE_XPOWER | ROMTYPE_NORDIC | ROMTYPE_AR | ROMTYPE_SUPERIV))
+       if (rd->type & (ROMTYPE_CD32CART | ROMTYPE_ARCADIAGAME) ||
+               rd->type == ROMTYPE_HRTMON || rd->type == ROMTYPE_XPOWER || rd->type ==  ROMTYPE_NORDIC || rd->type == ROMTYPE_AR || rd->type ==  ROMTYPE_SUPERIV)
                _tcscpy (p->cartfile, path);
        if (rd->type & ROMTYPE_CPUBOARD)
-               set_device_rom(p, path, ROMTYPE_CPUBOARD);
+               set_device_rom(p, path, ROMTYPE_CPUBOARD, 0);
        if (rd->type & ROMTYPE_CPUBOARDEXT)
-               set_device_rom(p, path, ROMTYPE_CPUBOARDEXT);
+               set_device_rom(p, path, ROMTYPE_CPUBOARDEXT, 0);
        return 1;
 }
 
-void set_device_rom(struct uae_prefs *p, const TCHAR *path, int romtype)
+void set_device_rom(struct uae_prefs *p, const TCHAR *path, int romtype, int devnum)
 {
        int idx;
        const struct expansionromtype *ert = get_device_expansion_rom(romtype);
        if (path == NULL) {
-               struct boardromconfig *brc = get_device_rom(p, romtype, &idx);
+               struct boardromconfig *brc = get_device_rom(p, romtype, devnum, &idx);
                if (brc) {
                        brc->roms[idx].romfile[0] = 0;
                        brc->roms[idx].romident[0] = 0;
                }
        } else {
-               struct boardromconfig *brc = get_device_rom_new(p, romtype, &idx);
+               struct boardromconfig *brc = get_device_rom_new(p, romtype, devnum, &idx);
                _tcscpy(brc->roms[idx].romfile, path);
        }
 }
@@ -1594,7 +1609,7 @@ const struct expansionromtype *get_unit_expansion_rom(int hdunit)
        if (hdunit >= HD_CONTROLLER_TYPE_SCSI_EXPANSION_FIRST && hdunit <= HD_CONTROLLER_TYPE_SCSI_LAST)
                return &expansionroms[hdunit - HD_CONTROLLER_TYPE_SCSI_EXPANSION_FIRST];
        if (hdunit >= HD_CONTROLLER_TYPE_IDE_EXPANSION_FIRST && hdunit <= HD_CONTROLLER_TYPE_IDE_LAST)
-               return &expansionroms[hdunit - HD_CONTROLLER_TYPE_SCSI_EXPANSION_FIRST];
+               return &expansionroms[hdunit - HD_CONTROLLER_TYPE_IDE_EXPANSION_FIRST];
        return NULL;
 }
 
@@ -1608,7 +1623,7 @@ const struct expansionromtype *get_device_expansion_rom(int romtype)
        return NULL;
 }
 
-struct boardromconfig *get_device_rom_new(struct uae_prefs *p, int romtype, int *index)
+struct boardromconfig *get_device_rom_new(struct uae_prefs *p, int romtype, int devnum, int *index)
 {
        int idx2;
        static struct boardromconfig fake;
@@ -1618,7 +1633,7 @@ struct boardromconfig *get_device_rom_new(struct uae_prefs *p, int romtype, int
                return &fake;
        }
        *index = ert->parentromtype ? 1 : 0;
-       struct boardromconfig *brc = get_device_rom(p, ert->parentromtype ? ert->parentromtype : romtype, &idx2);
+       struct boardromconfig *brc = get_device_rom(p, ert->parentromtype ? ert->parentromtype : romtype, devnum, &idx2);
        if (!brc) {
                for (int i = 0; i < MAX_EXPANSION_BOARDS; i++) {
                        brc = &p->expansionboard[i];
@@ -1637,6 +1652,7 @@ struct boardromconfig *get_device_rom_new(struct uae_prefs *p, int romtype, int
                        if (brc->device_type == 0) {
                                memset(brc, 0, sizeof boardromconfig);
                                brc->device_type = romtype;
+                               brc->device_num = devnum;
                                return brc;
                        }
                }
@@ -1645,16 +1661,16 @@ struct boardromconfig *get_device_rom_new(struct uae_prefs *p, int romtype, int
        return brc;
 }
 
-void clear_device_rom(struct uae_prefs *p, int romtype)
+void clear_device_rom(struct uae_prefs *p, int romtype, int devnum)
 {
        int index;
-       struct boardromconfig *brc = get_device_rom(p, romtype, &index);
+       struct boardromconfig *brc = get_device_rom(p, romtype, devnum, &index);
        if (!brc)
                return;
        memset(&brc->roms[index], 0, sizeof(struct romconfig));
 }
 
-struct boardromconfig *get_device_rom(struct uae_prefs *p, int romtype, int *index)
+struct boardromconfig *get_device_rom(struct uae_prefs *p, int romtype, int devnum, int *index)
 {
        const struct expansionromtype *ert = get_device_expansion_rom(romtype);
        if (!ert) {
@@ -1665,29 +1681,43 @@ struct boardromconfig *get_device_rom(struct uae_prefs *p, int romtype, int *ind
        *index = ert->parentromtype ? 1 : 0;
        for (int i = 0; i < MAX_EXPANSION_BOARDS; i++) {
                struct boardromconfig *brc = &p->expansionboard[i];
-               if ((brc->device_type & ROMTYPE_MASK) == (parentrom & ROMTYPE_MASK))
+               if ((brc->device_type & ROMTYPE_MASK) == (parentrom & ROMTYPE_MASK) && brc->device_num == devnum)
                        return brc;
        }
        return NULL;
 }
 
-struct romconfig *get_device_romconfig(struct uae_prefs *p, int devnum, int romtype)
+struct romconfig *get_device_romconfig(struct uae_prefs *p, int romtype, int devnum)
 {
        int idx;
-       if (devnum)
-               return NULL;
-       struct boardromconfig *brc = get_device_rom(p, romtype, &idx);
+       struct boardromconfig *brc = get_device_rom(p, romtype, devnum, &idx);
        if (brc)
                return &brc->roms[idx];
        return NULL;
 }
 
-struct zfile *read_device_rom(struct uae_prefs *p, int devnum, int romtype, int *roms)
+struct zfile *read_device_from_romconfig(struct romconfig *rc, int *roms)
 {
-       int idx;
-       if (devnum)
+       if (!_tcsicmp(rc->romfile, _T(":NOROM")))
                return NULL;
-       struct boardromconfig *brc = get_device_rom(p, romtype, &idx);
+       struct zfile *z = read_rom_name (rc->romfile);
+       if (!z) {
+               struct romlist *rl = getromlistbyids(roms, rc->romfile);
+               if (rl) {
+                       struct romdata *rd = rl->rd;
+                       z = read_rom (rd);
+               }
+               if (!z) {
+                       romwarning (roms);
+               }
+       }
+       return z;
+}
+
+struct zfile *read_device_rom(struct uae_prefs *p, int romtype, int devnum, int *roms)
+{
+       int idx;
+       struct boardromconfig *brc = get_device_rom(p, romtype, devnum, &idx);
        if (brc) {
                const TCHAR *romname = brc->roms[idx].romfile;
                if (!_tcsicmp(romname, _T(":NOROM")))
@@ -1705,12 +1735,10 @@ struct zfile *read_device_rom(struct uae_prefs *p, int devnum, int romtype, int
        return NULL;
 }
 
-int is_device_rom(struct uae_prefs *p, int devnum, int romtype)
+int is_device_rom(struct uae_prefs *p, int romtype, int devnum)
 {
        int idx;
-       if (devnum)
-               return 0;
-       struct boardromconfig *brc = get_device_rom(p, romtype, &idx);
+       struct boardromconfig *brc = get_device_rom(p, romtype, devnum, &idx);
        if (brc) {
                const TCHAR *romname = brc->roms[idx].romfile;
                if (_tcslen(romname) == 0)
index b6bd33f4350cbc8c7b9d6d5a6256a5705cde8ce6..2a414b78ee509ebd6a1aab9954074405ea51b3d5 100644 (file)
@@ -675,9 +675,12 @@ void restore_state (const TCHAR *filename)
 #ifdef CDTV
                else if (!_tcscmp (name, _T("CDTV")))
                        end = restore_cdtv (chunk);
+#if 0
                else if (!_tcscmp (name, _T("DMAC")))
                        end = restore_cdtv_dmac (chunk);
 #endif
+#endif
+#if 0
                else if (!_tcscmp (name, _T("DMC2")))
                        end = restore_scsi_dmac (WDTYPE_A3000, chunk);
                else if (!_tcscmp (name, _T("DMC3")))
@@ -690,6 +693,7 @@ void restore_state (const TCHAR *filename)
                        end = restore_scsi_device (WDTYPE_A2091, chunk);
                else if (!_tcscmp (name, _T("SCS4")))
                        end = restore_scsi_device (WDTYPE_A2091_2, chunk);
+#endif
                else if (!_tcscmp (name, _T("SCSD")))
                        end = restore_scsidev (chunk);
                else if (!_tcscmp (name, _T("GAYL")))
@@ -974,10 +978,13 @@ static int save_state_internal (struct zfile *f, const TCHAR *description, int c
        dst = save_cdtv (&len, NULL);
        save_chunk (f, dst, len, _T("CDTV"), 0);
        xfree (dst);
+#if 0
        dst = save_cdtv_dmac (&len, NULL);
        save_chunk (f, dst, len, _T("DMAC"), 0);
        xfree (dst);
 #endif
+#endif
+#if 0
        dst = save_scsi_dmac (WDTYPE_A3000, &len, NULL);
        save_chunk (f, dst, len, _T("DMC2"), 0);
        xfree (dst);
@@ -996,6 +1003,7 @@ static int save_state_internal (struct zfile *f, const TCHAR *description, int c
                        xfree (dst);
                }
        }
+#endif
        for (i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) {
                dst = save_scsidev (i, &len, NULL);
                save_chunk (f, dst, len, _T("SCSD"), 0);
@@ -1315,10 +1323,12 @@ void savestate_rewind (void)
        if (restore_u32_func (&p))
                p = restore_cdtv_dmac (p);
 #endif
+#if 0
        if (restore_u32_func (&p))
                p = restore_scsi_dmac (WDTYPE_A2091, p);
        if (restore_u32_func (&p))
                p = restore_scsi_dmac (WDTYPE_A3000, p);
+#endif
        if (restore_u32_func (&p))
                p = restore_gayle (p);
        for (i = 0; i < 4; i++) {
@@ -1661,6 +1671,7 @@ retry2:
                p += len;
        }
 #endif
+#if 0
        if (bufcheck (st, p, 0))
                goto retry;
        p3 = p;
@@ -1681,6 +1692,7 @@ retry2:
                tlen += len;
                p += len;
        }
+#endif
        if (bufcheck (st, p, 0))
                goto retry;
        p3 = p;
index 76a8f295eac0d6ac3c91fcba5928fa7d8af66c00..b6115a574e29cda80f0b8399c89caa28086418a7 100644 (file)
--- a/scsi.cpp
+++ b/scsi.cpp
 
 #define NCR5380_SUPRA 1
 #define NONCR_GOLEM 2
+#define NCR5380_STARDRIVE 3
+#define NONCR_KOMMOS 4
+#define NONCR_VECTOR 5
+#define NONCR_APOLLO 6
+#define NCR5380_PROTAR 7
+#define NCR_LAST 8
 
 extern int log_scsiemu;
 
@@ -106,6 +112,10 @@ bool scsi_emulate_analyze (struct scsi_data *sd)
                        int cl = (sd->cmd[1] & 8) != 0;
                        int dlf = sd->cmd[1] & 7;
                        data_len2 = 4;
+               } else {
+                       sd->direction = 0;
+                       sd->data_len = 0;
+                       return true;
                }
        break;
        case 0x08: // READ(6)
@@ -402,7 +412,7 @@ int scsi_send_data(struct scsi_data *sd, uae_u8 b)
                if (sd->offset == sd->cmd_len)
                        return 1;
        } else {
-               write_log (_T("scsi_send_data() without direction!\n"));
+               write_log (_T("scsi_send_data() without direction! (%02X)\n"), sd->cmd[0]);
                return 0;
        }
        if (sd->offset == sd->data_len)
@@ -430,8 +440,8 @@ void free_scsi (struct scsi_data *sd)
 
 int add_scsi_hd (struct scsi_data **sd, int ch, struct hd_hardfiledata *hfd, struct uaedev_config_info *ci, int scsi_level)
 {
-       free_scsi (sd[ch]);
-       sd[ch] = NULL;
+       free_scsi (*sd);
+       *sd = NULL;
        if (!hfd) {
                hfd = xcalloc (struct hd_hardfiledata, 1);
                memcpy (&hfd->hfd.ci, ci, sizeof (struct uaedev_config_info));
@@ -439,23 +449,34 @@ int add_scsi_hd (struct scsi_data **sd, int ch, struct hd_hardfiledata *hfd, str
        if (!hdf_hd_open (hfd))
                return 0;
        hfd->ansi_version = scsi_level;
-       sd[ch] = scsi_alloc_hd (ch, hfd);
-       return sd[ch] ? 1 : 0;
+       *sd = scsi_alloc_hd (ch, hfd);
+       return *sd ? 1 : 0;
 }
 
 int add_scsi_cd (struct scsi_data **sd, int ch, int unitnum)
 {
        device_func_init (0);
-       free_scsi (sd[ch]);
-       sd[ch] = scsi_alloc_cd (ch, unitnum, false);
-       return sd[ch] ? 1 : 0;
+       free_scsi (*sd);
+       *sd = scsi_alloc_cd (ch, unitnum, false);
+       return *sd ? 1 : 0;
 }
 
 int add_scsi_tape (struct scsi_data **sd, int ch, const TCHAR *tape_directory, bool readonly)
 {
-       free_scsi (sd[ch]);
-       sd[ch] = scsi_alloc_tape (ch, tape_directory, readonly);
-       return sd[ch] ? 1 : 0;
+       free_scsi (*sd);
+       *sd = scsi_alloc_tape (ch, tape_directory, readonly);
+       return *sd ? 1 : 0;
+}
+
+int add_scsi_device(struct scsi_data **sd, int ch, struct uaedev_config_info *ci, struct romconfig *rc, int scsi_level)
+{
+       if (ci->type == UAEDEV_CD)
+               return add_scsi_cd(sd, ch, ci->device_emu_unit);
+       else if (ci->type == UAEDEV_TAPE)
+               return add_scsi_tape(sd, ch, ci->rootdir, ci->readonly);
+       else if (ci->type == UAEDEV_HDF)
+               return add_scsi_hd(sd, ch, NULL, ci, 1);
+       return 0;
 }
 
 void scsi_freenative(struct scsi_data **sd)
@@ -542,27 +563,35 @@ struct raw_scsi
        bool atn;
        bool ack;
        bool use_ack;
+       bool wait_ack;
        uae_u8 data;
+       uae_u8 status;
+       bool databusoutput;
        int initiator_id, target_id;
-       struct scsi_data *device[8];
+       struct scsi_data *device[MAX_TOTAL_SCSI_DEVICES];
        struct scsi_data *target;
 };
 
-struct ncr5380_scsi
+struct soft_scsi
 {
        uae_u8 regs[8];
        struct raw_scsi rscsi;
        bool irq;
+       bool intena;
        bool enabled;
        bool configured;
        uae_u8 acmemory[128];
+       uaecptr baseaddress;
+       uaecptr baseaddress2;
        uae_u8 *rom;
+       int rom_size;
        int board_mask;
        int board_size;
        addrbank *bank;
        int type;
        int subtype;
        int dma_direction;
+       struct romconfig *rc;
 
        int dmac_direction;
        uaecptr dmac_address;
@@ -570,6 +599,83 @@ struct ncr5380_scsi
        int dmac_active;
 };
 
+
+#define MAX_SOFT_SCSI_UNITS 10
+static struct soft_scsi *soft_scsi_devices[MAX_SOFT_SCSI_UNITS];
+static struct soft_scsi *soft_scsi_units[NCR_LAST * MAX_DUPLICATE_EXPANSION_BOARDS];
+
+static void soft_scsi_free_unit(struct soft_scsi *s)
+{
+       if (!s)
+               return;
+       struct raw_scsi *rs = &s->rscsi;
+       for (int j = 0; j < 8; j++) {
+               free_scsi (rs->device[j]);
+               rs->device[j] = NULL;
+       }
+       xfree(s);
+}
+
+static void freescsi(struct soft_scsi **ncr)
+{
+       if (!ncr)
+               return;
+       for (int i = 0; i < MAX_SOFT_SCSI_UNITS; i++) {
+               if (soft_scsi_devices[i] == *ncr) {
+                       soft_scsi_devices[i] = NULL;
+               }
+       }
+       if (*ncr) {
+               soft_scsi_free_unit(*ncr);
+       }
+       *ncr = NULL;
+}
+
+static struct soft_scsi *allocscsi(struct soft_scsi **ncr, struct romconfig *rc, int ch)
+{
+       struct soft_scsi *scsi;
+
+       if (ch < 0) {
+               freescsi(ncr);
+       }
+       if ((*ncr) == NULL) {
+               scsi = xcalloc(struct soft_scsi, 1);
+               for (int i = 0; i < MAX_SOFT_SCSI_UNITS; i++) {
+                       if (soft_scsi_devices[i] == NULL) {
+                               soft_scsi_devices[i] = scsi;
+                               rc->unitdata = scsi;
+                               scsi->rc = rc;
+                               if (ncr)
+                                       *ncr = scsi;
+                               return scsi;
+                       }
+               }
+       }
+       return *ncr;
+}
+
+static struct soft_scsi *getscsi(struct romconfig *rc)
+{
+       if (rc->unitdata)
+               return (struct soft_scsi*)rc->unitdata;
+       return NULL;
+}
+
+
+static struct soft_scsi *getscsiboard(uaecptr addr)
+{
+       for (int i = 0; soft_scsi_devices[i]; i++) {
+               struct soft_scsi *s = soft_scsi_devices[i];
+               if (!s->baseaddress && !s->configured)
+                       return s;
+               if ((addr & ~s->board_mask) == s->baseaddress)
+                       return s;
+               if (s->baseaddress2 && (addr & ~s->board_mask) == s->baseaddress2)
+                       return s;
+       }
+       return NULL;
+}
+
 void raw_scsi_reset(struct raw_scsi *rs)
 {
        rs->target = NULL;
@@ -577,6 +683,36 @@ void raw_scsi_reset(struct raw_scsi *rs)
        rs->bus_phase = SCSI_SIGNAL_PHASE_FREE;
 }
 
+extern addrbank soft_bank_generic;
+
+static void generic_soft_scsi_add(int ch, struct uaedev_config_info *ci, struct romconfig *rc, int type, int boardsize, int romsize)
+{
+       struct soft_scsi *ss = allocscsi(&soft_scsi_units[type * MAX_DUPLICATE_EXPANSION_BOARDS + ci->controller_type_unit], rc, ch);
+       ss->type = type;
+       ss->configured = 0;
+       ss->bank = &soft_bank_generic;
+       ss->subtype = rc->subtype;
+       ss->intena = false;
+       if (boardsize > 0) {
+               ss->board_size = boardsize;
+               ss->board_mask = ss->board_size - 1;
+       }
+       if (romsize >= 0) {
+               ss->rom_size = romsize;
+               xfree(ss->rom);
+               ss->rom = NULL;
+               if (romsize > 0) {
+                       ss->rom = xcalloc(uae_u8, ss->rom_size);
+                       memset(ss->rom, 0xff, ss->rom_size);
+               }
+       }
+       memset(ss->acmemory, 0xff, sizeof ss->acmemory);
+       raw_scsi_reset(&ss->rscsi);
+       if (ch < 0)
+               return;
+       add_scsi_device(&ss->rscsi.device[ch], ch, ci, rc, 1);
+}
+
 void raw_scsi_busfree(struct raw_scsi *rs)
 {
        rs->target = NULL;
@@ -598,10 +734,19 @@ static int getbit(uae_u8 v)
        }
        return -1;
 }
+static int countbits(uae_u8 v)
+{
+       int cnt = 0;
+       for (int i = 7; i >= 0; i--) {
+               if ((1 << i) & v)
+                       cnt++;
+       }
+       return cnt;
+}
 
-void raw_scsi_set_ack(struct raw_scsi *rs, bool ack)
+static void raw_scsi_set_databus(struct raw_scsi *rs, bool databusoutput)
 {
-       rs->ack = ack;
+       rs->databusoutput = databusoutput;
 }
 
 void raw_scsi_set_signal_phase(struct raw_scsi *rs, bool busy, bool select, bool atn)
@@ -609,13 +754,17 @@ void raw_scsi_set_signal_phase(struct raw_scsi *rs, bool busy, bool select, bool
        switch (rs->bus_phase)
        {
                case SCSI_SIGNAL_PHASE_FREE:
-               if (busy && !select) {
+               if (busy && !select && !rs->databusoutput) {
                        rs->bus_phase = SCSI_SIGNAL_PHASE_ARBIT;
                        rs->initiator_id = getbit(rs->data);
 #if RAW_SCSI_DEBUG
                        write_log(_T("raw_scsi: arbitration initiator id %d\n"), rs->initiator_id);
 #endif
                } else if (!busy && select) {
+                       if (countbits(rs->data) == 1) {
+                               // In SCSI-1 initiator ID is optional.
+                               rs->data |= 0x80;
+                       }
                        rs->initiator_id = getbit(rs->data);
                        rs->bus_phase = SCSI_SIGNAL_PHASE_SELECT_1;
                        raw_scsi_set_signal_phase(rs, busy, select, atn);
@@ -662,7 +811,7 @@ void raw_scsi_set_signal_phase(struct raw_scsi *rs, bool busy, bool select, bool
                case SCSI_SIGNAL_PHASE_SELECT_2:
                if (!select) {
                        scsi_start_transfer(rs->target);
-                       rs->bus_phase = rs->atn ? SCSI_SIGNAL_PHASE_MESSAGE_IN : SCSI_SIGNAL_PHASE_COMMAND;
+                       rs->bus_phase = rs->atn ? SCSI_SIGNAL_PHASE_MESSAGE_OUT : SCSI_SIGNAL_PHASE_COMMAND;
                        rs->io = SCSI_IO_BUSY | SCSI_IO_REQ;
                }
                break;
@@ -719,6 +868,7 @@ uae_u8 raw_scsi_get_data(struct raw_scsi *rs)
                write_log(_T("raw_scsi: message byte read %02x\n"), sd->status);
 #endif
                v = sd->status;
+               rs->status = v;
                bus_free(rs);
                break;
                default:
@@ -729,12 +879,26 @@ uae_u8 raw_scsi_get_data(struct raw_scsi *rs)
        return v;
 }
 
-void raw_scsi_put_data(struct raw_scsi *rs, uae_u8 data)
+static int getmsglen(uae_u8 *msgp, int len)
+{
+       uae_u8 msg = msgp[0];
+       if (msg == 0 || (msg >= 0x02 && msg <= 0x1f) ||msg >= 0x80)
+               return 1;
+       if (msg >= 0x02 && msg <= 0x1f)
+               return 2;
+       if (msg >= 0x20 && msg <= 0x2f)
+               return 3;
+       // extended message, at least 3 bytes
+       if (len < 2)
+               return 3;
+       return msgp[1];
+}
+
+static void raw_scsi_write_data(struct raw_scsi *rs, uae_u8 data)
 {
        struct scsi_data *sd = rs->target;
        int len;
 
-       rs->data = data;
        switch (rs->bus_phase)
        {
                case SCSI_SIGNAL_PHASE_SELECT_1:
@@ -743,6 +907,9 @@ void raw_scsi_put_data(struct raw_scsi *rs, uae_u8 data)
                case SCSI_SIGNAL_PHASE_COMMAND:
                sd->cmd[sd->offset++] = data;
                len = scsicmdsizes[sd->cmd[0] >> 5];
+#if RAW_SCSI_DEBUG > 1
+               write_log(_T("raw_scsi: got command byte %02x (%d/%d)\n"), data, sd->offset, len);
+#endif
                if (sd->offset >= len) {
 #if RAW_SCSI_DEBUG
                        write_log(_T("raw_scsi: got command %02x (%d bytes)\n"), sd->cmd[0], len);
@@ -784,32 +951,52 @@ void raw_scsi_put_data(struct raw_scsi *rs, uae_u8 data)
                        rs->bus_phase = SCSI_SIGNAL_PHASE_STATUS;
                }
                break;
+               case SCSI_SIGNAL_PHASE_MESSAGE_OUT:
+               sd->msgout[sd->offset++] = data;
+               len = getmsglen(sd->msgout, sd->offset);
+               write_log(_T("raw_scsi_put_data got message %02x (%d/%d)\n"), data, sd->offset, len);
+               if (sd->offset >= len) {
+                       write_log(_T("raw_scsi_put_data got message %02x (%d bytes)\n"), sd->msgout[0], len);
+                       scsi_start_transfer(sd);
+                       rs->bus_phase = SCSI_SIGNAL_PHASE_COMMAND;
+               }
+               break;
                default:
                write_log(_T("raw_scsi_put_data but bus phase is %d!\n"), rs->bus_phase);
                break;
        }
 }
 
-// APOLLO SOFTSCSI
+void raw_scsi_put_data(struct raw_scsi *rs, uae_u8 data, bool databusoutput)
+{
+       rs->data = data;
+       if ((!rs->use_ack && (rs->bus_phase >= 0 && !(rs->io & SCSI_IO_REQ))) || !databusoutput)
+               return;
+       raw_scsi_write_data(rs, data);
+}
 
-struct apollo_soft_scsi
+void raw_scsi_set_ack(struct raw_scsi *rs, bool ack)
 {
-       bool enabled;
-       int configured;
-       bool autoconfig;
-       bool irq;
-       struct raw_scsi rscsi;
-};
-static struct apollo_soft_scsi apolloscsi[2];
+       if (rs->ack != ack) {
+               rs->ack = ack;
+               if (ack && rs->use_ack && rs->bus_phase >= 0 && (rs->io & SCSI_IO_REQ) && !(rs->bus_phase & 1)) {
+                       raw_scsi_write_data(rs, rs->data);
+               }
+       }
+}
+
+// APOLLO SOFTSCSI
 
 void apollo_scsi_bput(uaecptr addr, uae_u8 v)
 {
+       struct soft_scsi *as = getscsiboard(addr);
+       if (!as)
+               return;
        int bank = addr & (0x800 | 0x400);
-       struct apollo_soft_scsi *as = &apolloscsi[0];
        struct raw_scsi *rs = &as->rscsi;
        addr &= 0x3fff;
        if (bank == 0) {
-               raw_scsi_put_data(rs, v);
+               raw_scsi_put_data(rs, v, true);
        } else if (bank == 0xc00 && !(addr & 1)) {
                as->irq = (v & 64) != 0;
                raw_scsi_set_signal_phase(rs,
@@ -817,7 +1004,7 @@ void apollo_scsi_bput(uaecptr addr, uae_u8 v)
                        (v & 32) != 0,
                        false);
        } else if (bank == 0x400 && (addr & 1)) {
-               raw_scsi_put_data(rs, v);
+               raw_scsi_put_data(rs, v, true);
                raw_scsi_set_signal_phase(rs, true, false, false);
        }
        //write_log(_T("apollo scsi put %04x = %02x\n"), addr, v);
@@ -825,8 +1012,10 @@ void apollo_scsi_bput(uaecptr addr, uae_u8 v)
 
 uae_u8 apollo_scsi_bget(uaecptr addr)
 {
+       struct soft_scsi *as = getscsiboard(addr);
+       if (!as)
+               return 0;
        int bank = addr & (0x800 | 0x400);
-       struct apollo_soft_scsi *as = &apolloscsi[0];
        struct raw_scsi *rs = &as->rscsi;
        uae_u8 v = 0xff;
        addr &= 0x3fff;
@@ -854,53 +1043,20 @@ uae_u8 apollo_scsi_bget(uaecptr addr)
        return v;
 }
 
-int apollo_add_scsi_unit(int ch, struct uaedev_config_info *ci)
-{
-       struct raw_scsi *rs = &apolloscsi[ci->controller_type_unit].rscsi;
-       raw_scsi_reset(rs);
-       if (ci->type == UAEDEV_CD)
-               return add_scsi_cd(rs->device, ch, ci->device_emu_unit);
-       else if (ci->type == UAEDEV_TAPE)
-               return add_scsi_tape(rs->device, ch, ci->rootdir, ci->readonly);
-       else
-               return add_scsi_hd(rs->device, ch, NULL, ci, 1);
-       return 0;
-}
-
-void apolloscsi_free(void)
-{
-       for (int j = 0; j < 2; j++) {
-               struct raw_scsi *rs = &apolloscsi[j].rscsi;
-               for (int i = 0; i < 8; i++) {
-                       free_scsi (rs->device[i]);
-                       rs->device[i] = NULL;
-               }
-       }
-}
+void apollo_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 
-void apolloscsi_reset(void)
+void apollo_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
 {
-       raw_scsi_reset(&apolloscsi[0].rscsi);
-       raw_scsi_reset(&apolloscsi[1].rscsi);
+       generic_soft_scsi_add(ch, ci, rc, NONCR_APOLLO, -1, -1);
+       // make sure IDE side is also initialized
+       struct uaedev_config_info ci2 = { 0 };
+       apollo_add_ide_unit(-1, &ci2, rc);
 }
 
+uae_u8 ncr5380_bget(struct soft_scsi *scsi, int reg);
+void ncr5380_bput(struct soft_scsi *scsi, int reg, uae_u8 v);
 
-static struct ncr5380_scsi suprascsi[2];
-static struct ncr5380_scsi golemscsi[2];
-
-static struct ncr5380_scsi *ncr5380devices[] =
-{
-       &suprascsi[0],
-       &suprascsi[1],
-       &golemscsi[0],
-       &golemscsi[1],
-       NULL
-};
-
-uae_u8 ncr5380_bget(struct ncr5380_scsi *scsi, int reg);
-void ncr5380_bput(struct ncr5380_scsi *scsi, int reg, uae_u8 v);
-
-static void supra_do_dma(struct ncr5380_scsi *ncr)
+static void supra_do_dma(struct soft_scsi *ncr)
 {
        int len = ncr->dmac_length;
        for (int i = 0; i < len; i++) {
@@ -914,7 +1070,7 @@ static void supra_do_dma(struct ncr5380_scsi *ncr)
        }
 }
 
-static void dma_check(struct ncr5380_scsi *ncr)
+static void dma_check(struct soft_scsi *ncr)
 {
        if (ncr->dmac_active && ncr->dma_direction) {
                if (ncr->type ==NCR5380_SUPRA && ncr->subtype == 4) {
@@ -933,21 +1089,22 @@ static void dma_check(struct ncr5380_scsi *ncr)
 
 void ncr80_rethink(void)
 {
-       for (int i = 0; ncr5380devices[i]; i++) {
-               if (ncr5380devices[i]->irq) {
+       for (int i = 0; soft_scsi_devices[i]; i++) {
+               if (soft_scsi_devices[i]->irq && soft_scsi_devices[i]->intena) {
                        INTREQ_0(0x8000 | 0x0008);
                        return;
                }
        }
 }
-static void ncr5380_set_irq(struct ncr5380_scsi *scsi)
+
+static void ncr5380_set_irq(struct soft_scsi *scsi)
 {
        scsi->irq = true;
        scsi->regs[5] |= 1 << 4;
        ncr80_rethink();
 }
 
-static void ncr5380_check_phase(struct ncr5380_scsi *scsi)
+static void ncr5380_check_phase(struct soft_scsi *scsi)
 {
        if (!(scsi->regs[2] & 2))
                return;
@@ -962,8 +1119,7 @@ static void ncr5380_check_phase(struct ncr5380_scsi *scsi)
        }
 }
 
-
-uae_u8 ncr5380_bget(struct ncr5380_scsi *scsi, int reg)
+uae_u8 ncr5380_bget(struct soft_scsi *scsi, int reg)
 {
        reg &= 7;
        uae_u8 v = scsi->regs[reg];
@@ -982,6 +1138,8 @@ uae_u8 ncr5380_bget(struct ncr5380_scsi *scsi, int reg)
                                v |= 1 << 1;
                        if (r->bus_phase >= 0)
                                v |= r->bus_phase << 2;
+                       if (scsi->regs[1] & 0x80)
+                               v |= 0x80;
                }
                break;
                case 5:
@@ -1012,7 +1170,8 @@ uae_u8 ncr5380_bget(struct ncr5380_scsi *scsi, int reg)
        ncr5380_check_phase(scsi);
        return v;
 }
-void ncr5380_bput(struct ncr5380_scsi *scsi, int reg, uae_u8 v)
+
+void ncr5380_bput(struct soft_scsi *scsi, int reg, uae_u8 v)
 {
        struct raw_scsi *r = &scsi->rscsi;
        reg &= 7;
@@ -1021,17 +1180,21 @@ void ncr5380_bput(struct ncr5380_scsi *scsi, int reg, uae_u8 v)
        switch(reg)
        {
                case 0:
-               raw_scsi_put_data(r, v);
+               raw_scsi_put_data(r, v, scsi->regs[1] & 1);
                break;
                case 1:
                scsi->regs[reg] &= ~((1 << 5) | (1 << 6));
                scsi->regs[reg] |= old & ((1 << 5) | (1 << 6)); // AIP, LA
-               if (!(v & 0x40)) {
+               if (!(v & 0x80)) {
+                       bool init = r->bus_phase < 0;
+                       raw_scsi_set_databus(r, (v & 1) != 0);
                        raw_scsi_set_signal_phase(r,
                                (v & (1 << 3)) != 0,
                                (v & (1 << 2)) != 0,
                                (v & (1 << 1)) != 0);
                        raw_scsi_set_ack(r, (v & (1 << 4)) != 0);
+//                     if ((v & 1) && !(old & 1) && !(scsi->regs[2] & 2) && !init && !r->use_ack)
+//                             raw_scsi_write_data(r, r->data);
                }
                if (v & 0x80) { // RST
                        scsi->irq = true;
@@ -1076,7 +1239,7 @@ void ncr5380_bput(struct ncr5380_scsi *scsi, int reg, uae_u8 v)
        ncr5380_check_phase(scsi);
 }
 
-static void ew(struct ncr5380_scsi *scsi, int addr, uae_u32 value)
+static void ew(struct soft_scsi *scsi, int addr, uae_u32 value)
 {
        addr &= 0xffff;
        if (addr == 00 || addr == 02 || addr == 0x40 || addr == 0x42) {
@@ -1088,10 +1251,11 @@ static void ew(struct ncr5380_scsi *scsi, int addr, uae_u32 value)
        }
 }
 
-static int suprareg(struct ncr5380_scsi *ncr, uaecptr addr, bool write)
+static int suprareg(struct soft_scsi *ncr, uaecptr addr, bool write)
 {
        int reg = (addr & 0x0f) >> 1;
        if ((addr & 0x20) && ncr->subtype == 0) {
+               // "dma" data in/out space
                if (!write)
                        reg = 6;
                else
@@ -1102,7 +1266,31 @@ static int suprareg(struct ncr5380_scsi *ncr, uaecptr addr, bool write)
        return reg;
 }
 
-static uae_u8 read_supra_dma(struct ncr5380_scsi *ncr, uaecptr addr)
+static int stardrivereg(struct soft_scsi *ncr, uaecptr addr)
+{
+       if ((addr & 0x0191) == 0x191) {
+               // "dma" data in/out register
+               return 0;
+       }
+       if ((addr & 0x0181) != 0x181)
+               return -1;
+       int reg = (addr >> 1) & 7;
+       return reg;
+}
+
+static int protarreg(struct soft_scsi *ncr, uaecptr addr)
+{
+       int reg = -1;
+       if ((addr & 0x24) == 0x20) {
+               // "fake dma" data port
+               reg = 0;
+       } else if ((addr & 0x20) == 0x00) {
+               reg = (addr >> 2) & 7;
+       }
+       return reg;
+}
+
+static uae_u8 read_supra_dma(struct soft_scsi *ncr, uaecptr addr)
 {
        uae_u8 val = 0;
 
@@ -1121,7 +1309,7 @@ static uae_u8 read_supra_dma(struct ncr5380_scsi *ncr, uaecptr addr)
        return val;
 }
 
-static void write_supra_dma(struct ncr5380_scsi *ncr, uaecptr addr, uae_u8 val)
+static void write_supra_dma(struct soft_scsi *ncr, uaecptr addr, uae_u8 val)
 {
        write_log(_T("SUPRA DMA PUT %08x %02x %08x\n"), addr, val, M68K_GETPC);
 
@@ -1159,11 +1347,21 @@ static void write_supra_dma(struct ncr5380_scsi *ncr, uaecptr addr, uae_u8 val)
        }
 }
 
-static uae_u32 ncr80_bget2(struct ncr5380_scsi *ncr, uaecptr addr)
+static void vector_scsi_status(struct raw_scsi *rs)
+{
+       // Vector Falcon 8000 FPGA seems to handle this internally
+       while (rs->bus_phase == SCSI_SIGNAL_PHASE_STATUS || rs->bus_phase == SCSI_SIGNAL_PHASE_MESSAGE_IN) {
+               raw_scsi_get_data(rs);
+       }
+}
+
+
+static uae_u32 ncr80_bget2(struct soft_scsi *ncr, uaecptr addr, int size)
 {
        int reg = -1;
        uae_u32 v = 0;
        int addresstype = -1;
+       uaecptr origddr = addr;
 
        addr &= ncr->board_mask;
 
@@ -1198,27 +1396,160 @@ static uae_u32 ncr80_bget2(struct ncr5380_scsi *ncr, uaecptr addr)
 
        } else if (ncr->type == NONCR_GOLEM) {
 
-               if (addr < 16384)
+               int bank = addr & 0x8f81;
+               struct raw_scsi *rs = &ncr->rscsi;
+               switch(bank)
+               {
+                       case 0x8000:
+                       case 0x8001:
+                       case 0x8002:
+                       case 0x8003:
+                       v = raw_scsi_get_data(rs);
+                       // message is not retrieved by driver, perhaps hardware does it?
+                       if (rs->bus_phase == SCSI_SIGNAL_PHASE_MESSAGE_IN)
+                               raw_scsi_get_data(rs);
+                       break;
+                       case 0x8200:
+                       {
+                               uae_u8 t = raw_scsi_get_signal_phase(rs);
+                               v = 0;
+                               if (!(t & SCSI_IO_BUSY))
+                                       v |= 1 << (8 - 8);
+                               if (rs->bus_phase >= 0) {
+                                       if (!(rs->bus_phase & SCSI_IO_DIRECTION))
+                                               v |= 1 << (13 - 8);
+                                       if (!(rs->bus_phase & SCSI_IO_COMMAND))
+                                               v |= 1 << (10 - 8);
+                                       if (rs->bus_phase != SCSI_SIGNAL_PHASE_STATUS)
+                                               v |= 1 << (15 - 8);
+                               }
+                       }
+                       break;
+                       case 0x8201:
+                       {
+                               uae_u8 t = raw_scsi_get_signal_phase(rs);
+                               v = 0;
+                               if (t & SCSI_IO_REQ)
+                                       v |= 1 << 6;
+                       }
+                       break;
+                       default:
+                       if ((addr & 0xc000) == 0x0000)
+                               v = ncr->rom[addr];
+                       break;
+               }
+
+       } else if (ncr->type == NCR5380_STARDRIVE) {
+
+               struct raw_scsi *rs = &ncr->rscsi;
+               if (addr < sizeof ncr->acmemory) {
+                       v = ncr->acmemory[addr];
+               } else {
+                       reg = stardrivereg(ncr, addr);
+                       if (reg >= 0) {
+                               v = ncr5380_bget(ncr, reg);
+                       } else if (addr == 0x104) {
+                               v = 0;
+                               // bit 3: dreq
+                               if (rs->bus_phase >= 0 && (rs->io & SCSI_IO_REQ) && (ncr->regs[2] & 2))
+                                       v |= 1 << 3;
+                       }
+               }
+
+       } else if (ncr->type == NONCR_KOMMOS) {
+
+               struct raw_scsi *rs = &ncr->rscsi;
+               if (addr & 0x8000) {
+                       v = ncr->rom[addr & 0x7fff];
+               } else if ((origddr & 0xf00000) != 0xf00000) {
+                       if (!(addr & 8)) {
+                               v = raw_scsi_get_data(rs);
+                       } else {
+                               uae_u8 t = raw_scsi_get_signal_phase(rs);
+                               v = 0;
+                               if (t & SCSI_IO_BUSY)
+                                       v |= 1 << 1;
+                               if (t & SCSI_IO_REQ)
+                                       v |= 1 << 0;
+                               if (t & SCSI_IO_DIRECTION)
+                                       v |= 1 << 4;
+                               if (t & SCSI_IO_COMMAND)
+                                       v |= 1 << 3;
+                               if (t & SCSI_IO_MESSAGE)
+                                       v |= 1 << 2;
+                       }
+               }
+
+       } else if (ncr->type == NONCR_VECTOR) {
+
+               struct raw_scsi *rs = &ncr->rscsi;
+               if (addr < sizeof ncr->acmemory) {
+                       v = ncr->acmemory[addr];
+               } else if (!(addr & 0x8000)) {
                        v = ncr->rom[addr];
+               } else {
+                       if ((addr & 0x201) == 0x200) {
+                               v = (1 << 0);
+                               uae_u8 t = raw_scsi_get_signal_phase(rs);
+                               if (t & SCSI_IO_BUSY)
+                                       v &= ~(1 << 0);
+                               if (t & SCSI_IO_DIRECTION)
+                                       v |= (1 << 6);
+                               if (t & SCSI_IO_COMMAND)
+                                       v |= (1 << 7);
+                       } else if ((addr & 0x201) == 0x201) {
+                               v = 0;
+                               uae_u8 t = raw_scsi_get_signal_phase(rs);
+                               if (t & SCSI_IO_REQ)
+                                       v |= 1 << 1;
+
+                       } else if ((addr & 0x300) == 0x000) {
+                               if (size > 1) {
+                                       v = raw_scsi_get_data(rs);
+                                       vector_scsi_status(rs);
+                               } else {
+                                       v = rs->status >= 2 ? 2 : 0;
+                               }
+                       } else if ((addr & 0x300) == 0x300) {
+                               raw_scsi_reset(rs);
+                       }
+               }
+
+       } else if (ncr->type == NCR5380_PROTAR) {
 
+               struct raw_scsi *rs = &ncr->rscsi;
+               if (addr < sizeof ncr->acmemory) {
+                       if (!ncr->configured) {
+                               v = ncr->acmemory[addr];
+                       } else {
+                               reg = protarreg(ncr, addr);
+                               if (reg >= 0) {
+                                       v = ncr5380_bget(ncr, reg);
+                               }
+                       }
+               } else {
+                       v = ncr->rom[addr & 65535];
+               }
        }
 
 #if NCR5380_DEBUG > 1
-       if (addr < 0x80 || addr > 0x2000)
+       if (addr < 0x1000)
                write_log(_T("GET %08x %02x %d %08x\n"), addr, v, reg, M68K_GETPC);
 #endif
 
        return v;
 }
 
-static void ncr80_bput2(struct ncr5380_scsi *ncr, uaecptr addr, uae_u32 val)
+static void ncr80_bput2(struct soft_scsi *ncr, uaecptr addr, uae_u32 val, int size)
 {
        int reg = -1;
        int addresstype = -1;
+       uaecptr origddr = addr;
 
        addr &= ncr->board_mask;
 
        if (ncr->type == NCR5380_SUPRA) {
+
                if (ncr->subtype == 4) {
                        if ((addr & 0xc000) == 0xc000) {
                                write_supra_dma(ncr, addr, val);
@@ -1239,39 +1570,107 @@ static void ncr80_bput2(struct ncr5380_scsi *ncr, uaecptr addr, uae_u32 val)
                        if (reg >= 0)
                                ncr5380_bput(ncr, reg, val);
                }
+
+       } else if (ncr->type == NONCR_GOLEM) {
+
+               int bank = addr & 0x8f81;
+               struct raw_scsi *rs = &ncr->rscsi;
+               switch(bank)
+               {
+                       case 0x8080:
+                       case 0x8081:
+                       case 0x8082:
+                       case 0x8083:
+                       raw_scsi_put_data(rs, val, true);
+                       break;
+                       case 0x8380:
+                       {
+                               raw_scsi_put_data(rs, val, true);
+                               raw_scsi_set_signal_phase(rs, false, true, false);
+                               uae_u8 t = raw_scsi_get_signal_phase(rs);
+                               if (t & SCSI_IO_BUSY)
+                                       raw_scsi_set_signal_phase(rs, true, false, false);
+                       }
+                       break;
+               }
+
+       } else if (ncr->type == NCR5380_STARDRIVE) {
+
+               reg = stardrivereg(ncr, addr);
+               if (reg >= 0)
+                       ncr5380_bput(ncr, reg, val);
+
+       } else if (ncr->type == NONCR_KOMMOS) {
+
+               struct raw_scsi *rs = &ncr->rscsi;
+               if (!(addr & 0x8000) && (origddr & 0xf00000) != 0xf00000) {
+                       if (!(addr & 8)) {
+                               raw_scsi_put_data(rs, val, true);
+                       } else {
+                               // select?
+                               if (val & 4) {
+                                       raw_scsi_set_signal_phase(rs, false, true, false);
+                                       uae_u8 t = raw_scsi_get_signal_phase(rs);
+                                       if (t & SCSI_IO_BUSY)
+                                               raw_scsi_set_signal_phase(rs, true, false, false);
+                               }
+                       }
+               }
+
+       } else if (ncr->type == NONCR_VECTOR) {
+
+               struct raw_scsi *rs = &ncr->rscsi;
+               if (addr & 0x8000) {
+                       if ((addr & 0x300) == 0x300) {
+                               raw_scsi_put_data(rs, val, false);
+                               raw_scsi_set_signal_phase(rs, false, true, false);
+                               uae_u8 t = raw_scsi_get_signal_phase(rs);
+                               if (t & SCSI_IO_BUSY)
+                                       raw_scsi_set_signal_phase(rs, true, false, false);
+                       } else if ((addr & 0x300) == 0x000) {
+                               raw_scsi_put_data(rs, val, true);
+                               vector_scsi_status(rs);
+                       }
+
+               }
+
+       } else if (ncr->type == NCR5380_PROTAR) {
+
+               reg = protarreg(ncr, addr);
+               if (reg >= 0)
+                       ncr5380_bput(ncr, reg, val);
+
        }
 #if NCR5380_DEBUG > 1
        write_log(_T("PUT %08x %02x %d %08x\n"), addr, val, reg, M68K_GETPC);
 #endif
 }
 
-static uae_u32 REGPARAM2 ncr80_lget(struct ncr5380_scsi *ncr, uaecptr addr)
+static uae_u32 REGPARAM2 ncr80_lget(struct soft_scsi *ncr, uaecptr addr)
 {
        uae_u32 v;
 #ifdef JIT
        special_mem |= S_READ;
 #endif
-       addr &= ncr->board_mask;
-       v =  ncr80_bget2(ncr, addr + 0) << 24;
-       v |= ncr80_bget2(ncr, addr + 1) << 16;
-       v |= ncr80_bget2(ncr, addr + 2) <<  8;
-       v |= ncr80_bget2(ncr, addr + 3) <<  0;
+       v =  ncr80_bget2(ncr, addr + 0, 4) << 24;
+       v |= ncr80_bget2(ncr, addr + 1, 4) << 16;
+       v |= ncr80_bget2(ncr, addr + 2, 4) <<  8;
+       v |= ncr80_bget2(ncr, addr + 3, 4) <<  0;
        return v;
 }
 
-static uae_u32 REGPARAM2 ncr80_wget(struct ncr5380_scsi *ncr, uaecptr addr)
+static uae_u32 REGPARAM2 ncr80_wget(struct soft_scsi *ncr, uaecptr addr)
 {
        uae_u32 v;
 #ifdef JIT
        special_mem |= S_READ;
 #endif
-       addr &= ncr->board_mask;
-       v = ncr80_bget2(ncr, addr) << 8;
-       v |= ncr80_bget2(ncr, addr + 1);
+       v = ncr80_bget2(ncr, addr, 2) << 8;
+       v |= ncr80_bget2(ncr, addr + 1, 2);
        return v;
 }
 
-static uae_u32 REGPARAM2 ncr80_bget(struct ncr5380_scsi *ncr, uaecptr addr)
+static uae_u32 REGPARAM2 ncr80_bget(struct soft_scsi *ncr, uaecptr addr)
 {
        uae_u32 v;
 #ifdef JIT
@@ -1284,37 +1683,35 @@ static uae_u32 REGPARAM2 ncr80_bget(struct ncr5380_scsi *ncr, uaecptr addr)
                        return 0;
                return ncr->acmemory[addr];
        }
-       v = ncr80_bget2(ncr, addr);
+       v = ncr80_bget2(ncr, addr, 1);
        return v;
 }
 
-static void REGPARAM2 ncr80_lput(struct ncr5380_scsi *ncr, uaecptr addr, uae_u32 l)
+static void REGPARAM2 ncr80_lput(struct soft_scsi *ncr, uaecptr addr, uae_u32 l)
 {
 #ifdef JIT
        special_mem |= S_WRITE;
 #endif
-       addr &= ncr->board_mask;
-       ncr80_bput2(ncr, addr + 0, l >> 24);
-       ncr80_bput2(ncr, addr + 1, l >> 16);
-       ncr80_bput2(ncr, addr + 2, l >>  8);
-       ncr80_bput2(ncr, addr + 3, l >>  0);
+       ncr80_bput2(ncr, addr + 0, l >> 24, 4);
+       ncr80_bput2(ncr, addr + 1, l >> 16, 4);
+       ncr80_bput2(ncr, addr + 2, l >>  8, 4);
+       ncr80_bput2(ncr, addr + 3, l >>  0, 4);
 }
 
-static void REGPARAM2 ncr80_wput(struct ncr5380_scsi *ncr, uaecptr addr, uae_u32 w)
+static void REGPARAM2 ncr80_wput(struct soft_scsi *ncr, uaecptr addr, uae_u32 w)
 {
 #ifdef JIT
        special_mem |= S_WRITE;
 #endif
        w &= 0xffff;
-       addr &= ncr->board_mask;
        if (!ncr->configured) {
                return;
        }
-       ncr80_bput2(ncr, addr, w >> 8);
-       ncr80_bput2(ncr, addr + 1, w);
+       ncr80_bput2(ncr, addr, w >> 8, 2);
+       ncr80_bput2(ncr, addr + 1, w, 2);
 }
 
-static void REGPARAM2 ncr80_bput(struct ncr5380_scsi *ncr, uaecptr addr, uae_u32 b)
+static void REGPARAM2 ncr80_bput(struct soft_scsi *ncr, uaecptr addr, uae_u32 b)
 {
 #ifdef JIT
        special_mem |= S_WRITE;
@@ -1327,6 +1724,7 @@ static void REGPARAM2 ncr80_bput(struct ncr5380_scsi *ncr, uaecptr addr, uae_u32
                {
                        case 0x48:
                        map_banks (ncr->bank, expamem_z2_pointer >> 16, ncr->board_size >> 16, 0);
+                       ncr->baseaddress = expamem_z2_pointer;
                        ncr->configured = 1;
                        expamem_next (ncr->bank, NULL);
                        break;
@@ -1337,87 +1735,114 @@ static void REGPARAM2 ncr80_bput(struct ncr5380_scsi *ncr, uaecptr addr, uae_u32
                }
                return;
        }
-       ncr80_bput2(ncr, addr, b);
+       ncr80_bput2(ncr, addr, b, 1);
 }
 
 
-SCSI_MEMORY_FUNCTIONS(ncr_supra, ncr80, suprascsi[0]);
-SCSI_MEMORY_FUNCTIONS(ncr2_supra, ncr80, suprascsi[1]);
-DECLARE_MEMORY_FUNCTIONS(ncr_supra)
-static addrbank ncr_bank_supra = {
-       ncr_supra_lget, ncr_supra_wget, ncr_supra_bget,
-       ncr_supra_lput, ncr_supra_wput, ncr_supra_bput,
-       default_xlate, default_check, NULL, NULL, _T("Supra"),
-       dummy_lgeti, dummy_wgeti, ABFLAG_IO
-};
-
-static uae_u8 *REGPARAM2 golem_xlate(struct ncr5380_scsi *ncr, uaecptr addr)
+static void REGPARAM2 soft_generic_bput (uaecptr addr, uae_u32 b)
 {
-       addr &= 8191;
-       return ncr->rom + addr;
+       struct soft_scsi *ncr = getscsiboard(addr);
+       if (ncr)
+               ncr80_bput(ncr, addr, b);
 }
-
-static uae_u8 *REGPARAM2 ncr_golem_xlate(uaecptr addr)
+static void REGPARAM2 soft_generic_wput (uaecptr addr, uae_u32 b)
+{
+       struct soft_scsi *ncr = getscsiboard(addr);
+       if (ncr)
+               ncr80_wput(ncr, addr, b);
+}
+static void REGPARAM2 soft_generic_lput (uaecptr addr, uae_u32 b)
+{
+       struct soft_scsi *ncr = getscsiboard(addr);
+       if (ncr)
+               ncr80_lput(ncr, addr, b);
+}
+static uae_u32 REGPARAM2 soft_generic_bget (uaecptr addr)
+{
+       struct soft_scsi *ncr = getscsiboard(addr);
+       if (ncr)
+               return ncr80_bget(ncr, addr);
+       return 0;
+}
+static uae_u32 REGPARAM2 soft_generic_wget (uaecptr addr)
 {
-       return golem_xlate(&golemscsi[0], addr);
+       struct soft_scsi *ncr = getscsiboard(addr);
+       if (ncr)
+               return ncr80_wget(ncr, addr);
+       return 0;
 }
-static int REGPARAM2 ncr_golem_check(uaecptr addr, uae_u32 size)
+static uae_u32 REGPARAM2 soft_generic_lget (uaecptr addr)
 {
-       addr &= 65535;
-       return addr < 8192;
+       struct soft_scsi *ncr = getscsiboard(addr);
+       if (ncr)
+               return ncr80_lget(ncr, addr);
+       return 0;
 }
 
+static int REGPARAM2 soft_check(uaecptr addr, uae_u32 size)
+{
+       struct soft_scsi *ncr = getscsiboard(addr);
+       if (!ncr)
+               return 0;
+       if (!ncr->rom)
+               return 0;
+       return 1;
+}
+static uae_u8 *REGPARAM2 soft_xlate(uaecptr addr)
+{
+       struct soft_scsi *ncr = getscsiboard(addr);
+       if (!ncr)
+               return 0;
+       return ncr->rom + (addr & (ncr->rom_size - 1));
+}
 
-SCSI_MEMORY_FUNCTIONS(ncr_golem, ncr80, golemscsi[0]);
-SCSI_MEMORY_FUNCTIONS(ncr2_golem, ncr80, golemscsi[1]);
-DECLARE_MEMORY_FUNCTIONS(ncr_supra)
-static addrbank ncr_bank_golem = {
-       ncr_golem_lget, ncr_golem_wget, ncr_golem_bget,
-       ncr_golem_lput, ncr_golem_wput, ncr_golem_bput,
-       ncr_golem_xlate, ncr_golem_check, NULL, NULL, _T("Golem"),
-       ncr_golem_lget, ncr_golem_wget, ABFLAG_IO | ABFLAG_SAFE
+addrbank soft_bank_generic = {
+       soft_generic_lget, soft_generic_wget, soft_generic_bget,
+       soft_generic_lput, soft_generic_wput, soft_generic_bput,
+       soft_xlate, soft_check, NULL, NULL, _T("LOWLEVEL/5380 SCSI"),
+       soft_generic_lget, soft_generic_wget, ABFLAG_IO | ABFLAG_SAFE
 };
 
-addrbank *supra_init(int devnum)
+
+
+/*
+       $8380 select unit (unit mask)
+
+       $8200 
+        6: REQ (1=active)
+        8: BSY (0=active)
+       10: C/D (1=data)
+       13: I/O (1=to target)
+       15: If not status?
+
+       $8080 write data
+       $8000 read data
+
+*/
+
+addrbank *supra_init(struct romconfig *rc)
 {
-       struct ncr5380_scsi *scsi = &suprascsi[devnum];
+       struct soft_scsi *scsi = getscsi(rc);
        int roms[2];
-       struct romconfig *rc = NULL;
        
-       scsi->configured = 0;
-
-       if (devnum > 0 && !scsi->enabled)
+       if (!scsi)
                return &expamem_null;
 
        roms[0] = 121;
        roms[1] = -1;
 
-       memset(scsi->acmemory, 0xff, sizeof scsi->acmemory);
-
-       scsi->board_size = 65536;
-       scsi->board_mask = scsi->board_size - 1;
-       scsi->bank = &ncr_bank_supra;
-       scsi->rom = xcalloc(uae_u8, 2 * 16384);
-       scsi->type = NCR5380_SUPRA;
-       scsi->subtype = 0;
-       memset(scsi->rom, 0xff, 2 * 16384);
+       scsi->intena = true;
 
-       rc = get_device_romconfig(&currprefs, devnum, ROMTYPE_SUPRA);
        const struct expansionromtype *ert = get_device_expansion_rom(ROMTYPE_SUPRA);
-       if (rc) {
-               struct zfile *z = NULL;
-               scsi->subtype = rc->subtype;
-               if (!rc->autoboot_disabled && scsi->subtype != 3) {
-                       z = read_device_rom(&currprefs, devnum, ROMTYPE_SUPRA, roms);
-                       if (!z && is_device_rom(&currprefs, devnum, ROMTYPE_SUPRA))
-                               romwarning(roms);
-               }
+       struct zfile *z = NULL;
+       scsi->subtype = rc->subtype;
+       if (!rc->autoboot_disabled && scsi->subtype != 3) {
+               struct zfile *z = read_device_from_romconfig(rc, roms);
                for (int i = 0; i < 16; i++) {
                        uae_u8 b = ert->subtypes[rc->subtype].autoconfig[i];
                        ew(scsi, i * 4, b);
                }
                if (z) {
-                       write_log(_T("SUPRA BOOT ROM '%s'\n"), zfile_getname(z));
                        for (int i = 0; i < 16384; i++) {
                                uae_u8 b;
                                zfile_fread(&b, 1, 1, z);
@@ -1429,53 +1854,28 @@ addrbank *supra_init(int devnum)
        return scsi->bank;
 }
 
-int supra_add_scsi_unit(int ch, struct uaedev_config_info *ci)
+void supra_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
 {
-       struct raw_scsi *rs = &suprascsi[ci->controller_type_unit].rscsi;
-       raw_scsi_reset(rs);
-       if (ci->type == UAEDEV_CD)
-               return add_scsi_cd(rs->device, ch, ci->device_emu_unit);
-       else if (ci->type == UAEDEV_TAPE)
-               return add_scsi_tape(rs->device, ch, ci->rootdir, ci->readonly);
-       else
-               return add_scsi_hd(rs->device, ch, NULL, ci, 1);
-       return 0;
+       generic_soft_scsi_add(ch, ci, rc, NCR5380_SUPRA, 65536, 2 * 16384);
 }
 
-addrbank *golem_init(int devnum)
+addrbank *golem_init(struct romconfig *rc)
 {
-       struct ncr5380_scsi *scsi = &golemscsi[devnum];
+       struct soft_scsi *scsi = getscsi(rc);
        int roms[2];
-       struct romconfig *rc = NULL;
        
-       scsi->configured = 0;
-
-       if (devnum > 0 && !scsi->enabled)
+       if (!scsi)
                return &expamem_null;
 
        roms[0] = 124;
        roms[1] = -1;
 
-       memset(scsi->acmemory, 0xff, sizeof scsi->acmemory);
-
-       scsi->board_size = 65536;
-       scsi->board_mask = scsi->board_size - 1;
-       scsi->bank = &ncr_bank_golem;
-       scsi->rom = xcalloc(uae_u8, 8192);
-       scsi->type = NONCR_GOLEM;
-       scsi->subtype = 0;
-       memset(scsi->rom, 0xff, 8192);
-
-       rc = get_device_romconfig(&currprefs, devnum, ROMTYPE_GOLEM);
-       if (rc) {
-               struct zfile *z = NULL;
-               if (!rc->autoboot_disabled) {
-                       z = read_device_rom(&currprefs, devnum, ROMTYPE_GOLEM, roms);
-                       if (!z && is_device_rom(&currprefs, devnum, ROMTYPE_GOLEM))
-                               romwarning(roms);
-               }
+       scsi->intena = true;
+
+       struct zfile *z = NULL;
+       if (!rc->autoboot_disabled) {
+               struct zfile *z = read_device_from_romconfig(rc, roms);
                if (z) {
-                       write_log(_T("GOLEM BOOT ROM '%s'\n"), zfile_getname(z));
                        if (rc->autoboot_disabled)
                                zfile_fseek(z, 8192, SEEK_SET);
                        for (int i = 0; i < 8192; i++) {
@@ -1491,33 +1891,141 @@ addrbank *golem_init(int devnum)
        return scsi->bank;
 }
 
-int golem_add_scsi_unit(int ch, struct uaedev_config_info *ci)
+void golem_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
 {
-       struct raw_scsi *rs = &golemscsi[ci->controller_type_unit].rscsi;
-       raw_scsi_reset(rs);
-       if (ci->type == UAEDEV_CD)
-               return add_scsi_cd(rs->device, ch, ci->device_emu_unit);
-       else if (ci->type == UAEDEV_TAPE)
-               return add_scsi_tape(rs->device, ch, ci->rootdir, ci->readonly);
-       else
-               return add_scsi_hd(rs->device, ch, NULL, ci, 1);
-       return 0;
+       generic_soft_scsi_add(ch, ci, rc, NONCR_GOLEM, 65536, 8192);
+}
+
+addrbank *stardrive_init(struct romconfig *rc)
+{
+       struct soft_scsi *scsi = getscsi(rc);
+       
+       if (!scsi)
+               return &expamem_null;
+
+       scsi->rscsi.use_ack = true;
+
+       const struct expansionromtype *ert = get_device_expansion_rom(ROMTYPE_STARDRIVE);
+       for (int i = 0; i < 16; i++) {
+               uae_u8 b = ert->autoconfig[i];
+               ew(scsi, i * 4, b);
+       }
+       return scsi->bank;
+}
+
+void stardrive_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
+{
+       generic_soft_scsi_add(ch, ci, rc, NCR5380_STARDRIVE, 65536, 0);
+}
+
+addrbank *kommos_init(struct romconfig *rc)
+{
+       struct soft_scsi *scsi = getscsi(rc);
+       int roms[2];
+       
+       if (!scsi)
+               return NULL;
+
+       scsi->configured = 1;
+
+       roms[0] = 127;
+       roms[1] = -1;
+       struct zfile *z = read_device_from_romconfig(rc, roms);
+       if (z) {
+               zfile_fread(scsi->rom, 1, 32768, z);
+               zfile_fclose(z);
+       }
+
+       map_banks(scsi->bank, 0xf10000 >> 16, 1, 0);
+       map_banks(scsi->bank, 0xeb0000 >> 16, 1, 0);
+       scsi->baseaddress = 0xeb0000;
+       scsi->baseaddress2 = 0xf10000;
+
+       return NULL;
 }
 
-void ncr5380scsi_free(void)
+void kommos_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
 {
-       for (int i = 0; ncr5380devices[i]; i++) {
-               struct raw_scsi *rs = &ncr5380devices[i]->rscsi;
-               for (int j = 0; j < 8; j++) {
-                       free_scsi (rs->device[j]);
-                       rs->device[j] = NULL;
+       generic_soft_scsi_add(ch, ci, rc, NONCR_KOMMOS, 65536, 32768);
+}
+
+addrbank *vector_init(struct romconfig *rc)
+{
+       struct soft_scsi *scsi = getscsi(rc);
+       int roms[2];
+       
+       if (!scsi)
+               return &expamem_null;
+
+       roms[0] = 128;
+       roms[1] = -1;
+
+       scsi->intena = true;
+
+       struct zfile *z = NULL;
+       if (!rc->autoboot_disabled) {
+               struct zfile *z = read_device_from_romconfig(rc, roms);
+               if (z) {
+                       for (int i = 0; i < 32768; i++) {
+                               uae_u8 b;
+                               zfile_fread(&b, 1, 1, z);
+                               if (i < sizeof scsi->acmemory)
+                                       scsi->acmemory[i] = b;
+                               scsi->rom[i] = b;
+                       }
+                       zfile_fclose(z);
                }
        }
+       return scsi->bank;
+}
+
+void vector_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
+{
+       generic_soft_scsi_add(ch, ci, rc, NONCR_VECTOR, 65536, 32768);
+}
+
+
+addrbank *protar_init(struct romconfig *rc)
+{
+       struct soft_scsi *scsi = getscsi(rc);
+       int roms[2];
+       
+       if (!scsi)
+               return &expamem_null;
+
+       roms[0] = 131;
+       roms[1] = -1;
+
+       struct zfile *z = read_device_from_romconfig(rc, roms);
+       if (z) {
+               for (int i = 0; i < 32768; i++) {
+                       uae_u8 b;
+                       zfile_fread(&b, 1, 1, z);
+                       scsi->rom[i * 2] = b;
+               }
+               zfile_fclose(z);
+               memcpy(scsi->acmemory, scsi->rom + 0x200 * 2, sizeof scsi->acmemory);
+       }
+       return scsi->bank;
+}
+
+void protar_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
+{
+       generic_soft_scsi_add(ch, ci, rc, NCR5380_PROTAR, 65536, 65536);
+}
+
+
+void soft_scsi_free(void)
+{
+       for (int i = 0; soft_scsi_devices[i]; i++) {
+               soft_scsi_free_unit(soft_scsi_devices[i]);
+               soft_scsi_devices[i] = NULL;
+       }
 }
 
-void ncr5380scsi_reset(void)
+void soft_scsi_reset(void)
 {
-       for (int i = 0; ncr5380devices[i]; i++) {
-               raw_scsi_reset(&ncr5380devices[i]->rscsi);
+       for (int i = 0; soft_scsi_devices[i]; i++) {
+               raw_scsi_reset(&soft_scsi_devices[i]->rscsi);
        }
 }
index 5f0a8cf6724b145f22b29d07714f54c5f238b98d..5244aeb948f35a6db1d9d363d3c1a7cc0b574843 100644 (file)
@@ -28,7 +28,7 @@ void uaeexe_install (void)
 {
        uaecptr loop;
 
-       if (!uae_boot_rom)
+       if (!uae_boot_rom_type)
                return;
        loop = here ();
        org (UAEEXE_ORG);
index 8ab55f7630a6783d7fc4494ede96918f4f028c15..4747de6286c55d1e1a683bf5ac0e6616e5805995 100644 (file)
@@ -457,7 +457,7 @@ static uae_u32 REGPARAM2 uaelib_demux (TrapContext *context)
 void emulib_install (void)
 {
        uaecptr a;
-       if (!uae_boot_rom)
+       if (!uae_boot_rom_type)
                return;
        a = here ();
        currprefs.mmkeyboard = 0;
index ed776398af97c4d3712dcbca5bf7d61023c2c1ca..d8fbabaa543bb00e693a12daf7bf6bf0c5b3fa3c 100644 (file)
--- a/zfile.cpp
+++ b/zfile.cpp
@@ -154,7 +154,7 @@ static void checkarchiveparent (struct zfile *z)
                archive_unpackzfile (z);
 }
 
-static struct zfile *zfile_create (struct zfile *prev)
+static struct zfile *zfile_create (struct zfile *prev, const TCHAR *originalname)
 {
        struct zfile *z;
 
@@ -165,6 +165,10 @@ static struct zfile *zfile_create (struct zfile *prev)
        z->next = zlist;
        zlist = z;
        z->opencnt = 1;
+       if (prev && prev->originalname)
+               z->originalname = my_strdup(prev->originalname);
+       else if (originalname)
+               z->originalname = my_strdup(originalname);
        if (prev) {
                z->zfdmask = prev->zfdmask;
        }
@@ -180,6 +184,7 @@ static void zfile_free (struct zfile *f)
                write_log (_T("deleted temporary file '%s'\n"), f->name);
        }
        xfree (f->name);
+       xfree (f->originalname);
        xfree (f->data);
        xfree (f->mode);
        xfree (f->userdata);
@@ -1609,7 +1614,7 @@ static struct zfile *zfile_fopen_nozip (const TCHAR *name, const TCHAR *mode)
 
        if(*name == '\0')
                return NULL;
-       l = zfile_create (NULL);
+       l = zfile_create (NULL, name);
        l->name = my_strdup (name);
        l->mode = my_strdup (mode);
        f = _tfopen (name, mode);
@@ -1684,7 +1689,7 @@ static struct zfile *zfile_fopen_2 (const TCHAR *name, const TCHAR *mode, int ma
                l->zfdmask = mask;
        } else {
                struct mystat st;
-               l = zfile_create (NULL);
+               l = zfile_create (NULL, name);
                l->mode = my_strdup (mode);
                l->name = my_strdup (name);
                l->zfdmask = mask;
@@ -1850,7 +1855,7 @@ static struct zfile *zfile_fopen_internet (const TCHAR *name, const TCHAR *mode,
        }
 
        if (mask & ZFD_CHECKONLY) {
-               zf = zfile_create (NULL);
+               zf = zfile_create (NULL, name);
                goto end;
        }
 
@@ -1877,7 +1882,7 @@ static struct zfile *zfile_fopen_internet (const TCHAR *name, const TCHAR *mode,
                }
        }
        if (datalen > 0) {
-               zf = zfile_create (NULL);
+               zf = zfile_create (NULL, name);
                if (zf) {
                        zf->size = datalen;
                        zf->data = data;
@@ -1967,9 +1972,9 @@ struct zfile *zfile_dup (struct zfile *zf)
        if (zf->userdata)
                return NULL;
        if (!zf->data && zf->dataseek) {
-               nzf = zfile_create (zf);
+               nzf = zfile_create (zf, NULL);
        } else if (zf->data) {
-               nzf = zfile_create (zf);
+               nzf = zfile_create (zf, NULL);
                nzf->data = xmalloc (uae_u8, zf->size);
                memcpy (nzf->data, zf->data, zf->size);
                nzf->size = zf->size;
@@ -1988,7 +1993,7 @@ struct zfile *zfile_dup (struct zfile *zf)
                FILE *ff = _tfopen (zf->name, zf->mode);
                if (!ff)
                        return NULL;
-               nzf = zfile_create (zf);
+               nzf = zfile_create (zf, NULL);
                nzf->f = ff;
        }
        zfile_fseek (nzf, zf->seek, SEEK_SET);
@@ -2023,7 +2028,7 @@ int zfile_iscompressed (struct zfile *z)
 struct zfile *zfile_fopen_empty (struct zfile *prev, const TCHAR *name, uae_u64 size)
 {
        struct zfile *l;
-       l = zfile_create (prev);
+       l = zfile_create (prev, NULL);
        l->name = my_strdup (name ? name : _T(""));
        if (size) {
                l->data = xcalloc (uae_u8, size);
@@ -2052,7 +2057,7 @@ struct zfile *zfile_fopen_parent (struct zfile *z, const TCHAR *name, uae_u64 of
 
        if (z == NULL)
                return NULL;
-       l = zfile_create (z);
+       l = zfile_create (z, NULL);
        if (name)
                l->name = my_strdup (name);
        else if (z->name)
@@ -2086,7 +2091,7 @@ struct zfile *zfile_fopen_data (const TCHAR *name, uae_u64 size, const uae_u8 *d
 {
        struct zfile *l;
 
-       l = zfile_create (NULL);
+       l = zfile_create (NULL, name);
        l->name = my_strdup (name ? name : _T(""));
        l->data = xmalloc (uae_u8, size);
        l->size = size;
@@ -2448,6 +2453,11 @@ TCHAR *zfile_getname (struct zfile *f)
        return f ? f->name : NULL;
 }
 
+TCHAR *zfile_getoriginalname (struct zfile *f)
+{
+       return f ? f->originalname : NULL;
+}
+
 TCHAR *zfile_getfilename (struct zfile *f)
 {
        int i;