]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
New IDE/SCSI controllers.
authorToni Wilen <twilen@winuae.net>
Sun, 1 Feb 2015 14:51:00 +0000 (16:51 +0200)
committerToni Wilen <twilen@winuae.net>
Sun, 1 Feb 2015 14:51:00 +0000 (16:51 +0200)
23 files changed:
a2091.cpp
cdtv.cpp
cfgfile.cpp
cpuboard.cpp
devices.cpp
expansion.cpp
filesys.cpp
gayle.cpp
ide.cpp
idecontrollers.cpp
include/a2091.h
include/cpuboard.h
include/filesys.h
include/ide.h
include/idecontrollers.h
include/ncr9x_scsi.h
include/options.h
include/rommgr.h
include/scsi.h
ncr9x_scsi.cpp
qemuvga/esp.cpp
rommgr.cpp
scsi.cpp

index 36ef0c51bb4ea723adcd593c090e6a6358b0d214..ef7a3874885e059ba9cc1df39042d5d71f4b4ba8 100644 (file)
--- a/a2091.cpp
+++ b/a2091.cpp
@@ -9,7 +9,8 @@
 *
 */
 
-#define GVP_DEBUG_IO 0
+#define GVP_S1_DEBUG_IO 0
+#define GVP_S2_DEBUG_IO 0
 #define A2091_DEBUG 0
 #define A2091_DEBUG_IO 0
 #define XT_DEBUG 0
 #include "autoconf.h"
 #include "cdtv.h"
 #include "savestate.h"
+#include "cpuboard.h"
 
 #define CDMAC_ROM_VECTOR 0x2000
 #define CDMAC_ROM_OFFSET 0x2000
 #define GVP_ROM_OFFSET 0x8000
+#define GVP_SERIES_I_RAM_OFFSET 0x4000
+#define GVP_SERIES_I_RAM_MASK 16383
 
 /* SuperDMAC CNTR bits. */
 #define SCNTR_TCEN     (1<<5)
@@ -278,7 +282,8 @@ static void reset_dmac(struct wd_state *wd)
 {
        switch (wd->dmac_type)
        {
-               case GVP_DMAC:
+               case GVP_DMAC_S1:
+               case GVP_DMAC_S2:
                wd->gdmac.cntr = 0;
                wd->gdmac.dma_on = 0;
                break;
@@ -297,7 +302,9 @@ static bool isirq(struct wd_state *wd)
                return false;
        switch (wd->dmac_type)
        {
-               case GVP_DMAC:
+               case GVP_DMAC_S1:
+               return wd->gdmac.cntr && (wd->wc.auxstatus & ASR_INT) != 0;
+               case GVP_DMAC_S2:
                if (wd->wc.auxstatus & ASR_INT)
                        wd->gdmac.cntr |= 2;
                if ((wd->gdmac.cntr & (2 | 8)) == 10)
@@ -325,7 +332,8 @@ static void set_dma_done(struct wd_state *wds)
 {
        switch (wds->dmac_type)
        {
-               case GVP_DMAC:
+               case GVP_DMAC_S1:
+               case GVP_DMAC_S2:
                wds->gdmac.dma_on = -1;
                break;
                case COMMODORE_SDMAC:
@@ -339,7 +347,9 @@ static bool is_dma_enabled(struct wd_state *wds)
 {
        switch (wds->dmac_type)
        {
-               case GVP_DMAC:
+               case GVP_DMAC_S1:
+               return true;
+               case GVP_DMAC_S2:
                return wds->gdmac.dma_on > 0;
                case COMMODORE_SDMAC:
                case COMMODORE_DMAC:
@@ -471,13 +481,27 @@ static bool decreasetc(struct wd_chip_state *wd)
        return tc == 0;
 }
 
-static bool canwddma(struct wd_chip_state *wd)
+static bool canwddma(struct wd_state *wds)
 {
+       struct wd_chip_state *wd = &wds->wc;
        uae_u8 mode = wd->wdregs[WD_CONTROL] >> 5;
-       if (mode != 0 && mode != 4 && mode != 1) {
-               write_log (_T("%s weird DMA mode %d!!\n"), WD33C93, mode);
+       switch(wds->dmac_type)
+       {
+               case COMMODORE_DMAC:
+               case COMMODORE_SDMAC:
+               case GVP_DMAC_S2:
+               if (mode != 0 && mode != 4 && mode != 1) {
+                       write_log (_T("%s weird DMA mode %d!!\n"), WD33C93, mode);
+               }
+               return mode == 4 || mode == 1;
+               case GVP_DMAC_S1:
+               if (mode != 0 && mode != 2) {
+                       write_log (_T("%s weird DMA mode %d!!\n"), WD33C93, mode);
+               }
+               return mode == 2;
+               default:
+               return false;
        }
-       return mode == 4 || mode == 1;
 }
 
 #if WD33C93_DEBUG > 0
@@ -565,13 +589,52 @@ static bool do_dma_commodore(struct wd_state *wd, struct scsi_data *scsi)
        return false;
 }
 
-static bool do_dma_gvp(struct wd_state *wd, struct scsi_data *scsi)
+static bool do_dma_gvp_s1(struct wd_state *wd, struct scsi_data *scsi)
+{
+       if (scsi->direction < 0) {
+               for (;;) {
+                       uae_u8 v;
+                       int status = scsi_receive_data (scsi, &v);
+                       wd->gdmac.buffer[wd->wc.wd_dataoffset++] = v;
+                       wd->wc.wd_dataoffset &= GVP_SERIES_I_RAM_MASK;
+                       if (decreasetc (&wd->wc))
+                               break;
+                       if (status)
+                               break;
+               }
+#if WD33C93_DEBUG > 0
+               write_log (_T("%s Done DMA from WD, %d/%d\n"), WD33C93, scsi->offset, scsi->data_len);
+#endif
+               return true;
+       } else if (scsi->direction > 0) {
+               for (;;) {
+                       int status;
+                       uae_u8 v = wd->gdmac.buffer[wd->wc.wd_dataoffset++];
+                       wd->wc.wd_dataoffset &= GVP_SERIES_I_RAM_MASK;
+                       status = scsi_send_data (scsi, v);
+                       wd->gdmac.addr++;
+                       if (decreasetc (&wd->wc))
+                               break;
+                       if (status)
+                               break;
+               }
+#if WD33C93_DEBUG > 0
+               write_log (_T("%s Done DMA to WD, %d/%d\n"), WD33C93, scsi->offset, scsi->data_len);
+#endif
+               return true;
+       }
+       return false;
+}
+
+
+static bool do_dma_gvp_s2(struct wd_state *wd, struct scsi_data *scsi)
 {
 #if WD33C93_DEBUG > 0
        uae_u32 dmaptr = wd->gdmac.addr;
 #endif
        if (!is_dma_enabled(wd))
                return false;
+
        if (scsi->direction < 0) {
                if (wd->gdmac.cntr & 0x10) {
                        write_log(_T("GVP DMA: mismatched direction when reading!\n"));
@@ -629,8 +692,10 @@ static bool do_dma(struct wd_state *wd)
                case COMMODORE_DMAC:
                case COMMODORE_SDMAC:
                return do_dma_commodore(wd, scsi);
-               case GVP_DMAC:
-               return do_dma_gvp(wd, scsi);
+               case GVP_DMAC_S2:
+               return do_dma_gvp_s2(wd, scsi);
+               case GVP_DMAC_S1:
+               return do_dma_gvp_s1(wd, scsi);
        }
        return false;
 }
@@ -853,7 +918,7 @@ static void wd_cmd_sel_xfer (struct wd_chip_state *wd, struct wd_state *wds, boo
                }
 
                if (wd->scsi->direction) {
-                       if (canwddma (wd)) {
+                       if (canwddma (wds)) {
                                if (scsi->direction <= 0) {
                                        do_dma(wds);
                                        if (scsi->offset < scsi->data_len) {
@@ -928,8 +993,9 @@ static void wd_cmd_sel_xfer (struct wd_chip_state *wd, struct wd_state *wds, boo
        wd->wd_selected = 0;
 }
 
-static void wd_cmd_trans_info (struct wd_chip_state *wd, struct scsi_data *scsi)
+static void wd_cmd_trans_info (struct wd_state *wds, struct scsi_data *scsi)
 {
+       struct wd_chip_state *wd = &wds->wc;
        if (wd->wdregs[WD_COMMAND_PHASE] == 0x20) {
                wd->wdregs[WD_COMMAND_PHASE] = 0x30;
                scsi->status = 0;
@@ -959,7 +1025,7 @@ static void wd_cmd_trans_info (struct wd_chip_state *wd, struct scsi_data *scsi)
                scsi->data_len = gettc (wd);
        }
 
-       if (canwddma (wd)) {
+       if (canwddma (wds)) {
                wd->wd_data_avail = -1;
        } else {
                wd->wd_data_avail = 1;
@@ -1965,7 +2031,7 @@ addrbank dmaca2091_2_bank = {
        dmac_a20912_lgeti, dmac_a20912_wgeti, ABFLAG_IO | ABFLAG_SAFE
 };
 
-/* GVP Series II */
+/* GVP Series I and II */
 
 extern addrbank gvp_bank;
 extern addrbank gvp_2_bank;
@@ -1975,42 +2041,69 @@ static uae_u32 dmac_gvp_read_byte(struct wd_state *wd, uaecptr addr)
        uae_u32 v = 0;
 
        addr &= 0xffff;
-       if (addr < 0x40) {
+       if (addr < 0x3e) {
                v = wd->dmacmemory[addr];
        } else if (addr >= GVP_ROM_OFFSET) {
-               if (addr & 1) {
-                       v = wd->gdmac.version;
+               if (wd->gdmac.series2) {
+                       if (addr & 1) {
+                               v = wd->gdmac.version;
+                       } else {
+                               if (wd->rom) {
+                                       if (wd->rombankswitcher && (addr & 0xffe0) == GVP_ROM_OFFSET)
+                                               wd->rombank = (addr & 0x02) >> 1;
+                                       v = wd->rom[(addr - GVP_ROM_OFFSET) / 2 + wd->rombank * 16384];
+                               }
+                       }
                } else {
                        if (wd->rom) {
-                               if (wd->rombankswitcher && (addr & 0xffe0) == GVP_ROM_OFFSET)
-                                       wd->rombank = (addr & 0x02) >> 1;
-                               v = wd->rom[(addr - GVP_ROM_OFFSET) / 2 + wd->rombank * 16384];
+                               v = wd->rom[addr - GVP_ROM_OFFSET];
                        }
                }
+       } else if (addr >= GVP_SERIES_I_RAM_OFFSET && !wd->gdmac.series2) {
+               v =  wd->gdmac.buffer[wd->gdmac.bufoffset++];
+               wd->gdmac.bufoffset &= GVP_SERIES_I_RAM_MASK;
        } else if (wd->configured) {
-               switch (addr)
-               {
-                       case 0x40:
-                       v = wd->gdmac.cntr >> 8;
-                       break;
-                       case 0x41:
-                       v = wd->gdmac.cntr;
-                       break;
-                       case 0x61: // SASR
-                       v = wdscsi_getauxstatus(&wd->wc);
-                       break;
-                       case 0x63: // SCMD
-                       v = wdscsi_get(&wd->wc, wd);
-                       break;
-                       default:
-                       write_log(_T("gvp_bget_unk %04X PC=%08X\n"), addr, M68K_GETPC);
-                       break;
+               if (wd->gdmac.series2) {
+                       switch (addr)
+                       {
+                               case 0x40:
+                               v = wd->gdmac.cntr >> 8;
+                               break;
+                               case 0x41:
+                               v = wd->gdmac.cntr;
+                               break;
+                               case 0x61: // SASR
+                               v = wdscsi_getauxstatus(&wd->wc);
+                               break;
+                               case 0x63: // SCMD
+                               v = wdscsi_get(&wd->wc, wd);
+                               break;
+                               default:
+                               write_log(_T("gvp_s2_bget_unk %04X PC=%08X\n"), addr, M68K_GETPC);
+                               break;
+                       }
+               } else {
+                       switch (addr)
+                       {
+                               case 0x3e:
+                               v = wd->wc.auxstatus & ASR_INT;
+                               break;
+                               case 0x60: // SASR
+                               v = wdscsi_getauxstatus(&wd->wc);
+                               break;
+                               case 0x62: // SCMD
+                               v = wdscsi_get(&wd->wc, wd);
+                               break;
+                               default:
+                               write_log(_T("gvp_s1_bget_unk %04X PC=%08X\n"), addr, M68K_GETPC);
+                               break;
+                       }
                }
        } else {
                v = 0xff;
        }
 
-#if GVP_DEBUG_IO > 0
+#if GVP_S2_DEBUG_IO > 0
        write_log(_T("gvp_bget %04X=%02X PC=%08X\n"), addr, v, M68K_GETPC);
 #endif
 
@@ -2021,43 +2114,65 @@ static uae_u32 dmac_gvp_read_word(struct wd_state *wd, uaecptr addr)
        uae_u32 v = 0;
 
        addr &= 0xffff;
-       if (addr < 0x40) {
+       if (addr < 0x3e) {
                v = (wd->dmacmemory[addr] << 8) | wd->dmacmemory[addr + 1];
        } else if (addr >= GVP_ROM_OFFSET) {
-               if (wd->rom) {
-                       if (wd->rombankswitcher && (addr & 0xffe0) == GVP_ROM_OFFSET)
-                               wd->rombank = (addr & 0x02) >> 1;
-                       v = (wd->rom[(addr - GVP_ROM_OFFSET) / 2 + wd->rombank * 16384] << 8) | wd->gdmac.version;
+               if (wd->gdmac.series2) {
+                       if (wd->rom) {
+                               if (wd->rombankswitcher && (addr & 0xffe0) == GVP_ROM_OFFSET)
+                                       wd->rombank = (addr & 0x02) >> 1;
+                               v = (wd->rom[(addr - GVP_ROM_OFFSET) / 2 + wd->rombank * 16384] << 8) | wd->gdmac.version;
+                       } else {
+                               v = wd->gdmac.version;
+                       }
                } else {
-                       v = wd->gdmac.version;
+                       if (wd->rom) {
+                               v = (wd->rom[addr - GVP_ROM_OFFSET] << 8) | (wd->rom[addr - GVP_ROM_OFFSET + 1]);
+                       }
                }
+       } else if (addr >= GVP_SERIES_I_RAM_OFFSET && !wd->gdmac.series2) {
+#if GVP_S1_DEBUG_IO > 1
+               int off = wd->gdmac.bufoffset;
+#endif
+               v =  wd->gdmac.buffer[wd->gdmac.bufoffset++] << 8;
+               wd->gdmac.bufoffset &= GVP_SERIES_I_RAM_MASK;
+               v |= wd->gdmac.buffer[wd->gdmac.bufoffset++] << 0;
+               wd->gdmac.bufoffset &= GVP_SERIES_I_RAM_MASK;
+#if GVP_S1_DEBUG_IO > 1
+               write_log(_T("gvp_s1_wget sram %d %04x\n"), off, v);
+#endif
        } else if (wd->configured) {
-               switch (addr)
-               {
-                       case 0x40:
-                       v = wd->gdmac.cntr;
-                       break;
-                       case 0x68:
-                       v = wd->gdmac.bank;
-                       break;
-                       case 0x70:
-                       v = wd->gdmac.addr >> 16;
-                       break;
-                       case 0x72:
-                       v = wd->gdmac.addr;
-                       break;
-                       default:
-                       write_log(_T("gvp_wget_unk %04X PC=%08X\n"), addr, M68K_GETPC);
-                       break;
+               if (wd->gdmac.series2) {
+                       switch (addr)
+                       {
+                               case 0x40:
+                               v = wd->gdmac.cntr;
+                               break;
+                               case 0x68:
+                               v = wd->gdmac.bank;
+                               break;
+                               case 0x70:
+                               v = wd->gdmac.addr >> 16;
+                               break;
+                               case 0x72:
+                               v = wd->gdmac.addr;
+                               break;
+                               default:
+                               write_log(_T("gvp_s2_wget_unk %04X PC=%08X\n"), addr, M68K_GETPC);
+                               break;
+                       }
+#if GVP_S2_DEBUG_IO > 0
+                       write_log(_T("gvp_s2_wget %04X=%04X PC=%08X\n"), addr, v, M68K_GETPC);
+#endif
+               } else {
+#if GVP_S1_DEBUG_IO > 0
+                       write_log(_T("gvp_s1_wget %04X=%04X PC=%08X\n"), addr, v, M68K_GETPC);
+#endif
                }
        } else {
                v = 0xffff;
        }
 
-#if GVP_DEBUG_IO > 0
-       write_log(_T("gvp_wget %04X=%04X PC=%08X\n"), addr, v, M68K_GETPC);
-#endif
-
        return v;
 }
 
@@ -2068,39 +2183,59 @@ static void dmac_gvp_write_word(struct wd_state *wd, uaecptr addr, uae_u32 b)
        if (addr >= GVP_ROM_OFFSET)
                return;
 
-#if GVP_DEBUG_IO > 0
-       write_log(_T("gvp_wput %04X=%04X PC=%08X\n"), addr, b & 65535, M68K_GETPC);
+       if (addr >= GVP_SERIES_I_RAM_OFFSET && !wd->gdmac.series2) {
+#if GVP_S1_DEBUG_IO > 1
+               int off = wd->gdmac.bufoffset;
+#endif
+               wd->gdmac.buffer[wd->gdmac.bufoffset++] = b >> 8;
+               wd->gdmac.bufoffset &= GVP_SERIES_I_RAM_MASK;
+               wd->gdmac.buffer[wd->gdmac.bufoffset++] = b;
+               wd->gdmac.bufoffset &= GVP_SERIES_I_RAM_MASK;
+#if GVP_S1_DEBUG_IO > 1
+               write_log(_T("gvp_s1_wput sram %d %04x\n"), off, b);
+#endif
+               return;
+       }
+
+       if (wd->gdmac.series2) {
+#if GVP_S2_DEBUG_IO > 0
+               write_log(_T("gvp_s2_wput %04X=%04X PC=%08X\n"), addr, b & 65535, M68K_GETPC);
+#endif
+               switch (addr)
+               {
+                       case 0x40:
+                       b &= ~(1 | 2);
+                       wd->gdmac.cntr = b;
+                       break;
+                       case 0x70: // ACR
+                       wd->gdmac.addr &= 0x0000ffff;
+                       wd->gdmac.addr |= (b & 0xff) << 16;
+                       wd->gdmac.addr &= wd->gdmac.addr_mask;
+                       break;
+                       case 0x72: // ACR
+                       wd->gdmac.addr &= 0xffff0000;
+                       wd->gdmac.addr |= b;
+                       wd->gdmac.addr &= wd->gdmac.addr_mask;
+                       break;
+                       case 0x76: // START DMA
+                       wd->gdmac.dma_on = 1;
+                       break;
+                       case 0x78: // STOP DMA
+                       wd->gdmac.dma_on = 0;
+                       break;
+                       case 0x74: // "secret1"
+                       case 0x7a: // "secret2"
+                       case 0x7c: // "secret3"
+                       write_log(_T("gvp_s2_wput_config %04X=%04X PC=%08X\n"), addr, b & 65535, M68K_GETPC);
+                       break;
+                       default:
+                       write_log(_T("gvp_s2_wput_unk %04X=%04X PC=%08X\n"), addr, b & 65535, M68K_GETPC);
+                       break;
+               }
+       } else {
+#if GVP_S1_DEBUG_IO > 0
+               write_log(_T("gvp_s1_wput %04X=%04X PC=%08X\n"), addr, b & 65535, M68K_GETPC);
 #endif
-       switch (addr)
-       {
-               case 0x40:
-               b &= ~(1 | 2);
-               wd->gdmac.cntr = b;
-               break;
-               case 0x70: // ACR
-               wd->gdmac.addr &= 0x0000ffff;
-               wd->gdmac.addr |= (b & 0xff) << 16;
-               wd->gdmac.addr &= wd->gdmac.addr_mask;
-               break;
-               case 0x72: // ACR
-               wd->gdmac.addr &= 0xffff0000;
-               wd->gdmac.addr |= b;
-               wd->gdmac.addr &= wd->gdmac.addr_mask;
-               break;
-               case 0x76: // START DMA
-               wd->gdmac.dma_on = 1;
-               break;
-               case 0x78: // STOP DMA
-               wd->gdmac.dma_on = 0;
-               break;
-               case 0x74: // "secret1"
-               case 0x7a: // "secret2"
-               case 0x7c: // "secret3"
-               write_log(_T("gvp_wput_config %04X=%04X PC=%08X\n"), addr, b & 65535, M68K_GETPC);
-               break;
-               default:
-               write_log(_T("gvp_wput_unk %04X=%04X PC=%08X\n"), addr, b & 65535, M68K_GETPC);
-               break;
        }
 }
 
@@ -2111,38 +2246,90 @@ static void dmac_gvp_write_byte(struct wd_state *wd, uaecptr addr, uae_u32 b)
        if (addr >= GVP_ROM_OFFSET)
                return;
 
-#if GVP_DEBUG_IO > 0
-       write_log(_T("gvp_bput %04X=%02X PC=%08X\n"), addr, b & 255, M68K_GETPC);
+       if (addr >= GVP_SERIES_I_RAM_OFFSET && !wd->gdmac.series2) {
+               wd->gdmac.buffer[wd->gdmac.bufoffset++] = b;
+               wd->gdmac.bufoffset &= GVP_SERIES_I_RAM_MASK;
+               return;
+       }
+
+       if (wd->gdmac.series2) {
+#if GVP_S2_DEBUG_IO > 0
+               write_log(_T("gvp_s2_bput %04X=%02X PC=%08X\n"), addr, b & 255, M68K_GETPC);
 #endif
-       switch (addr)
-       {
-               case 0x40:
-               wd->gdmac.cntr &= 0x00ff;
-               wd->gdmac.cntr |= b << 8;
-               break;
-               case 0x41:
-               b &= ~(1 | 2);
-               wd->gdmac.cntr &= 0xff00;
-               wd->gdmac.cntr |= b << 0;
-               break;
-               case 0x61: // SASR
-               wdscsi_sasr(&wd->wc, b);
-               break;
-               case 0x63: // SCMD
-               wdscsi_put(&wd->wc, wd, b);
-               break;
-               case 0x74: // "secret1"
-               case 0x75:
-               case 0x7a: // "secret2"
-               case 0x7b:
-               case 0x7c: // "secret3"
-               case 0x7d:
-               write_log(_T("gvp_bput_config %04X=%04X PC=%08X\n"), addr, b & 255, M68K_GETPC);
-               break;
-               default:
-               write_log(_T("gvp_bput_unk %04X=%02X PC=%08X\n"), addr, b & 255, M68K_GETPC);
-               break;
+               switch (addr)
+               {
+                       case 0x40:
+                       wd->gdmac.cntr &= 0x00ff;
+                       wd->gdmac.cntr |= b << 8;
+                       break;
+                       case 0x41:
+                       b &= ~(1 | 2);
+                       wd->gdmac.cntr &= 0xff00;
+                       wd->gdmac.cntr |= b << 0;
+                       break;
+                       case 0x61: // SASR
+                       wdscsi_sasr(&wd->wc, b);
+                       break;
+                       case 0x63: // SCMD
+                       wdscsi_put(&wd->wc, wd, b);
+                       break;
+               
+                       case 0x74: // "secret1"
+                       case 0x75:
+                       case 0x7a: // "secret2"
+                       case 0x7b:
+                       case 0x7c: // "secret3"
+                       case 0x7d:
+                       write_log(_T("gvp_s2_bput_config %04X=%04X PC=%08X\n"), addr, b & 255, M68K_GETPC);
+                       break;
+                       default:
+                       write_log(_T("gvp_s2_bput_unk %04X=%02X PC=%08X\n"), addr, b & 255, M68K_GETPC);
+                       break;
+               }
+       } else {
+#if GVP_S1_DEBUG_IO > 0
+               write_log(_T("gvp_s1_bput %04X=%02X PC=%08X\n"), addr, b & 255, M68K_GETPC);
+#endif
+               switch (addr)
+               {
+                       case 0x60: // SASR
+                       wdscsi_sasr(&wd->wc, b);
+                       break;
+                       case 0x62: // SCMD
+                       wdscsi_put(&wd->wc, wd, b);
+                       break;
+               
+                       // 68:
+                       // 00 CPU SRAM access 
+                       // ff WD SRAM access
+
+                       // 6c:
+                       // 28 0010 startup reset?
+                       // b8 1011 before CPU reading from SRAM
+                       // a8 1100 before CPU writing to SRAM
+                       // e8 1110 before starting WD write DMA
+                       // f8 1111 access done/start WD read DMA
+                       // 08 = intena?
+
+                       case 0x68:
+#if GVP_S1_DEBUG_IO > 0
+                       write_log(_T("gvp_s1_bput_s1 %04X=%04X PC=%08X\n"), addr, b & 255, M68K_GETPC);
+#endif
+                       wd->gdmac.bufoffset = 0;
+                       break;
+                       case 0x6c:
+#if GVP_S1_DEBUG_IO > 0
+                       write_log(_T("gvp_s1_bput_s1 %04X=%04X PC=%08X\n"), addr, b & 255, M68K_GETPC);
+#endif
+                       wd->gdmac.cntr = b & 8;
+                       break;
+               
+                       default:
+                       write_log(_T("gvp_s1_bput_unk %04X=%02X PC=%08X\n"), addr, b & 255, M68K_GETPC);
+                       break;
+               }
        }
+
 }
 
 static uae_u32 REGPARAM2 dmac_gvp_lget(struct wd_state *wd, uaecptr addr)
@@ -2230,10 +2417,12 @@ static uae_u32 REGPARAM2 dmac_gvp_wgeti(struct wd_state *wd, uaecptr addr)
        special_mem |= S_READ;
 #endif
        addr &= 65535;
-       if (addr >= GVP_ROM_OFFSET)
+       if (addr >= GVP_ROM_OFFSET) {
+               addr -= GVP_ROM_OFFSET;
                v = (wd->rom[addr & wd->rom_mask] << 8) | wd->rom[(addr + 1) & wd->rom_mask];
-       else
+       } else {
                write_log(_T("Invalid GVP instruction access %08x\n"), addr);
+       }
        return v;
 }
 static uae_u32 REGPARAM2 dmac_gvp_lgeti(struct wd_state *wd, uaecptr addr)
@@ -2306,11 +2495,53 @@ addrbank gvp_bank = {
        dmac_gvp_xlate, dmac_gvp_check, NULL, NULL, _T("GVP"),
        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_lget, dmac_gvp_wget, dmac_gvp_bget,
-       dmac_gvp_lput, dmac_gvp_wput, dmac_gvp_bput,
-       dmac_gvp_xlate, dmac_gvp_check, NULL, NULL, _T("GVP #2"),
-       dmac_gvp_lgeti, dmac_gvp_wgeti, ABFLAG_IO | ABFLAG_SAFE
+       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) */
@@ -2616,7 +2847,7 @@ static void *scsi_thread (void *wdv)
                                wd_cmd_sel_xfer (wd, wds, false);
                                break;
                        case WD_CMD_TRANS_INFO:
-                               wd_cmd_trans_info (wd, wd->scsi);
+                               wd_cmd_trans_info (wds, wd->scsi);
                                break;
                        case WD_CMD_TRANS_ADDR:
                                wd_cmd_trans_addr(wd, wds);
@@ -2660,109 +2891,15 @@ void init_wd_scsi (struct wd_state *wd)
        }
 }
 
-static void freescsi (struct scsi_data *sd)
-{
-       if (!sd)
-               return;
-       hdf_hd_close (sd->hfd);
-       scsi_free (sd);
-}
-
-int add_wd_scsi_hd (struct wd_state *wd, int ch, struct hd_hardfiledata *hfd, struct uaedev_config_info *ci, int scsi_level)
-{
-       freescsi (wd->scsis[ch]);
-       wd->scsis[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;
-       wd->scsis[ch] = scsi_alloc_hd (ch, hfd);
-       return wd->scsis[ch] ? 1 : 0;
-}
-
-int add_wd_scsi_cd (struct wd_state *wd, int ch, int unitnum)
-{
-       device_func_init (0);
-       freescsi (wd->scsis[ch]);
-       wd->scsis[ch] = scsi_alloc_cd (ch, unitnum, false);
-       return wd->scsis[ch] ? 1 : 0;
-}
-
-int add_wd_scsi_tape (struct wd_state *wd, int ch, const TCHAR *tape_directory, bool readonly)
-{
-       freescsi (wd->scsis[ch]);
-       wd->scsis[ch] = scsi_alloc_tape (ch, tape_directory, readonly);
-       return wd->scsis[ch] ? 1 : 0;
-}
-
-static void freenativescsi (struct wd_state *wd)
-{
-       int i;
-       for (i = 0; i < 8; i++) {
-               freescsi (wd->scsis[i]);
-               wd->scsis[i] = NULL;
-       }
-}
-
-static void addnativescsi (struct wd_state *wd)
-{
-       int i, j;
-       int devices[MAX_TOTAL_SCSI_DEVICES];
-       int types[MAX_TOTAL_SCSI_DEVICES];
-       struct device_info dis[MAX_TOTAL_SCSI_DEVICES];
-
-       freenativescsi (wd);
-       i = 0;
-       while (i < MAX_TOTAL_SCSI_DEVICES) {
-               types[i] = -1;
-               devices[i] = -1;
-               if (sys_command_open (i)) {
-                       if (sys_command_info (i, &dis[i], 0)) {
-                               devices[i] = i;
-                               types[i] = 100 - i;
-                               if (dis[i].type == INQ_ROMD)
-                                       types[i] = 1000 - i;
-                       }
-                       sys_command_close (i);
-               }
-               i++;
-       }
-       i = 0;
-       while (devices[i] >= 0) {
-               j = i + 1;
-               while (devices[j] >= 0) {
-                       if (types[i] > types[j]) {
-                               int tmp = types[i];
-                               types[i] = types[j];
-                               types[j] = tmp;
-                       }
-                       j++;
-               }
-               i++;
-       }
-       i = 0; j = 0;
-       while (devices[i] >= 0 && j < 7) {
-               if (wd->scsis[j] == NULL) {
-                       wd->scsis[j] = scsi_alloc_native(j, devices[i]);
-                       write_log (_T("SCSI: %d:'%s'\n"), j, dis[i].label);
-                       i++;
-               }
-               j++;
-       }
-}
-
 int a3000_add_scsi_unit (int ch, struct uaedev_config_info *ci)
 {
        struct wd_state *wd = &wd_a3000;
        if (ci->type == UAEDEV_CD)
-               return add_wd_scsi_cd (wd, ch, ci->device_emu_unit);
+               return add_scsi_cd (wd->scsis, ch, ci->device_emu_unit);
        else if (ci->type == UAEDEV_TAPE)
-               return add_wd_scsi_tape (wd, ch, ci->rootdir, ci->readonly);
+               return add_scsi_tape (wd->scsis, ch, ci->rootdir, ci->readonly);
        else
-               return add_wd_scsi_hd (wd, ch, NULL, ci, 2);
+               return add_scsi_hd (wd->scsis, ch, NULL, ci, 2);
 }
 
 void a3000scsi_reset (void)
@@ -2781,7 +2918,7 @@ void a3000scsi_reset (void)
 void a3000scsi_free (void)
 {
        struct wd_state *wd = &wd_a3000;
-       freenativescsi (wd);
+       scsi_freenative(wd->scsis);
        if (wd->scsi_thread_running > 0) {
                wd->scsi_thread_running = 0;
                write_comm_pipe_u32 (&wd->requests, 0xffffffff, 1);
@@ -2796,11 +2933,11 @@ int a2091_add_scsi_unit(int ch, struct uaedev_config_info *ci, int devnum)
        struct wd_state *wd = wda2091[devnum];
 
        if (ci->type == UAEDEV_CD)
-               return add_wd_scsi_cd(wd, ch, ci->device_emu_unit);
+               return add_scsi_cd(wd->scsis, ch, ci->device_emu_unit);
        else if (ci->type == UAEDEV_TAPE)
-               return add_wd_scsi_tape(wd, ch, ci->rootdir, ci->readonly);
+               return add_scsi_tape(wd->scsis, ch, ci->rootdir, ci->readonly);
        else
-               return add_wd_scsi_hd(wd, ch, NULL, ci, 1);
+               return add_scsi_hd(wd->scsis, ch, NULL, ci, 1);
 }
 
 int gvp_add_scsi_unit(int ch, struct uaedev_config_info *ci, int devnum)
@@ -2808,16 +2945,16 @@ int gvp_add_scsi_unit(int ch, struct uaedev_config_info *ci, int devnum)
        struct wd_state *wd = gvpscsi[devnum];
 
        if (ci->type == UAEDEV_CD)
-               return add_wd_scsi_cd(wd, ch, ci->device_emu_unit);
+               return add_scsi_cd(wd->scsis, ch, ci->device_emu_unit);
        else if (ci->type == UAEDEV_TAPE)
-               return add_wd_scsi_tape(wd, ch, ci->rootdir, ci->readonly);
+               return add_scsi_tape(wd->scsis, ch, ci->rootdir, ci->readonly);
        else
-               return add_wd_scsi_hd(wd, ch, NULL, ci, 2);
+               return add_scsi_hd(wd->scsis, ch, NULL, ci, 2);
 }
 
 void a2091_free_device (struct wd_state *wd)
 {
-       freenativescsi (wd);
+       scsi_freenative(wd->scsis);
        xfree (wd->rom);
        wd->rom = NULL;
 }
@@ -2835,7 +2972,7 @@ static void a2091_reset_device(struct wd_state *wd)
        wd->dmac_type = COMMODORE_DMAC;
        wd->cdmac.old_dmac = 0;
        if (currprefs.scsi == 2)
-               addnativescsi (wd);
+               scsi_addnative(wd->scsis);
        wd_cmd_reset (&wd->wc, false);
        reset_dmac(wd);
        if (wd == &wd_a2091)
@@ -2927,7 +3064,7 @@ addrbank *a2091_init (int devnum)
 
 void gvp_free_device (struct wd_state *wd)
 {
-       freenativescsi (wd);
+       scsi_freenative(wd->scsis);
        xfree (wd->rom);
        wd->rom = NULL;
 }
@@ -2942,13 +3079,9 @@ static void gvp_reset_device(struct wd_state *wd)
        wd->configured = 0;
        wd->wc.wd_used = 0;
        wd->wc.wd33c93_ver = 1;
-       wd->dmac_type = GVP_DMAC;
-       wd->gdmac.version = GVP_SERIESII;
-       if (wd->gdmac.series2)
-               wd->gdmac.version |= 1;
-       wd->gdmac.addr_mask = 0x00ffffff;
+       wd->dmac_type = wd->gdmac.series2 ? GVP_DMAC_S2 : GVP_DMAC_S1;
        if (currprefs.scsi == 2)
-               addnativescsi (wd);
+               scsi_addnative(wd->scsis);
        wd_cmd_reset (&wd->wc, false);
        reset_dmac(wd);
        if (wd == &wd_gvp)
@@ -2966,13 +3099,14 @@ void gvp_reset (void)
 static const uae_u8 gvp_scsi_i_autoconfig[16] = { 0xd1, 0x09, 0x00, 0x00, 0x07, 0xe1, 0xee, 0xee, 0xee, 0xee, 0x80, 0x00 };
 static const uae_u8 gvp_scsi_ii_autoconfig[16] = { 0xd1, 0x0b, 0x00, 0x00, 0x07, 0xe1, 0xee, 0xee, 0xee, 0xee, 0x80, 0x00 };
 
-addrbank *gvp_init(int devnum)
+addrbank *gvp_init(int devnum, bool series2)
 {
        struct wd_state *wd = gvpscsi[devnum];
        int roms[6];
        struct romlist *rl;
+       struct boardromconfig *brc = series2 ? &currprefs.gvps2rom : &currprefs.gvps1rom;
 
-       if (devnum > 0 && !wd->enabled)
+       if (devnum > 0 && !wd->enabled && currprefs.cpuboard_type != BOARD_GVP_A530)
                return &expamem_null;
 
        init_wd_scsi(wd);
@@ -2981,6 +3115,13 @@ addrbank *gvp_init(int devnum)
        wd->autoconfig = true;
        wd->rombankswitcher = 0;
        memset(wd->dmacmemory, 0xff, sizeof wd->dmacmemory);
+       wd->gdmac.series2 = series2;
+       wd->gdmac.version = GVP_SERIESII;
+       wd->gdmac.addr_mask = 0x00ffffff;
+       if (currprefs.cpuboard_type == BOARD_GVP_A530) {
+               wd->gdmac.version = GVP_A530_SCSI;
+               wd->gdmac.addr_mask = 0x01ffffff;
+       }
 
        roms[0] = 109;
        roms[1] = 110;
@@ -2990,36 +3131,45 @@ addrbank *gvp_init(int devnum)
        wd->rom_size = 32768;
        wd->rom = xcalloc(uae_u8, wd->rom_size);
        memset(wd->rom, 0xff, wd->rom_size);
-       wd->rom_mask = wd->rom_size - 1;
-       wd->gdmac.series2 = true;
-
-       for (int i = 0; i < 16; i++) {
-               uae_u8 b = wd->gdmac.series2 ? gvp_scsi_ii_autoconfig[i] : gvp_scsi_i_autoconfig[i];
-               ew(wd, i * 4, b);
-       }
+       wd->rom_mask = 32768 - 1;
 
-       if (_tcscmp (currprefs.gvprom.roms[0].romfile, _T(":NOROM"))) {
-               const TCHAR *romname = devnum && currprefs.gvprom.roms[1].romfile[0] ? currprefs.gvprom.roms[1].romfile : currprefs.gvprom.roms[0].romfile;
+       if (_tcscmp (brc->roms[0].romfile, _T(":NOROM"))) {
+               const TCHAR *romname = devnum && brc->roms[1].romfile[0] ? brc->roms[1].romfile : brc->roms[0].romfile;
                struct zfile *z = read_rom_name(romname);
                if (!z) {
                        rl = getromlistbyids(roms, romname);
                        if (rl) {
                                z = read_rom(rl->rd);
                        }
-                       if (rl && rl->rd && rl->rd->id == 111)
-                               wd->gdmac.series2 = false;
                }
                if (z) {
                        write_log(_T("GVP BOOT ROM '%s'\n"), zfile_getname(z));
-                       int size = zfile_fread(wd->rom, 1, wd->rom_size, z);
+                       int size = zfile_size(z);
+                       if (series2) {
+                               zfile_fread(wd->rom, 1, wd->rom_size, z);
+                       } else {
+                               xfree(wd->gdmac.buffer);
+                               wd->gdmac.buffer = xcalloc(uae_u8, GVP_SERIES_I_RAM_MASK + 1);
+                               for (int i = 0; i < 16384; i++) {
+                                       uae_u8 b;
+                                       zfile_fread(&b, 1, 1, z);
+                                       wd->rom[i] = b;
+                               }
+                       }
                        zfile_fclose(z);
-                       if (size > 16384) {
+                       if (series2 && size > 16384) {
                                wd->rombankswitcher = 1;
                        }
                } else {
                        romwarning(roms);
                }
        }
+
+       for (int i = 0; i < 16; i++) {
+               uae_u8 b = wd->gdmac.series2 ? gvp_scsi_ii_autoconfig[i] : gvp_scsi_i_autoconfig[i];
+               ew(wd, i * 4, b);
+       }
+       gvp_reset_device(wd);
        return wd == &wd_gvp ? &gvp_bank : &gvp_2_bank;
 }
 
@@ -3163,19 +3313,19 @@ uae_u8 *restore_scsi_device (int wdtype, uae_u8 *src)
                        wd->cdmac.xt_control = restore_u8();
                }
                if (size)
-                       add_wd_scsi_hd (wd, num, hfd, NULL, s->hfd->ansi_version);
+                       add_scsi_hd (wd->scsis, num, hfd, NULL, s->hfd->ansi_version);
                xfree (path);
        break;
        case UAEDEV_CD:
                num2 = restore_u32 ();
-               add_wd_scsi_cd (wd, num, num2);
+               add_scsi_cd (wd->scsis, num, num2);
        break;
        case UAEDEV_TAPE:
                num2 = restore_u32 ();
                blocksize = restore_u32 ();
                readonly = restore_u32 ();
                path = restore_string ();
-               add_wd_scsi_tape (wd, num, path, readonly != 0);
+               add_scsi_tape (wd->scsis, num, path, readonly != 0);
                xfree (path);
        break;
        }
index 02ba686d918258d57d334239d6ba5268a3c717a7..0c4fe64314d78bc4b95ce6fbbdbfcb68b382aea0 100644 (file)
--- a/cdtv.cpp
+++ b/cdtv.cpp
@@ -30,6 +30,7 @@
 #include "a2091.h"
 #include "uae.h"
 #include "savestate.h"
+#include "scsi.h"
 
 /* DMAC CNTR bits. */
 #define CNTR_TCEN               (1<<7)
@@ -1635,7 +1636,7 @@ uae_u8 cdtv_battram_read (int addr)
 
 int cdtv_add_scsi_hd_unit (int ch, struct uaedev_config_info *ci)
 {
-       return add_wd_scsi_hd (&wd_cdtv, ch, NULL, ci, 1);
+       return add_scsi_hd (wd_cdtv.scsis, ch, NULL, ci, 1);
 }
 
 void cdtv_free (void)
index 86148bd076591df697f0b70ac52c5b8ae703223d..edd03b6cb1d676bf1b6b7cd85e4fc74fdff09f8e 100644 (file)
@@ -225,6 +225,8 @@ static const TCHAR *cpuboards[] = {
        _T("FusionForty"),
        _T("A3001SI"),
        _T("A3001SII"),
+       _T("Apollo"),
+       _T("GVPA530"),
        NULL
 };
 static const TCHAR *ppc_implementations[] = {
@@ -251,16 +253,34 @@ static const TCHAR *ppc_cpu_idle[] = {
 static const TCHAR *waitblits[] = { _T("disabled"), _T("automatic"), _T("noidleonly"), _T("always"), 0 };
 static const TCHAR *autoext2[] = { _T("disabled"), _T("copy"), _T("replace"), 0 };
 static const TCHAR *leds[] = { _T("power"), _T("df0"), _T("df1"), _T("df2"), _T("df3"), _T("hd"), _T("cd"), _T("fps"), _T("cpu"), _T("snd"), _T("md"), 0 };
-static int leds_order[] = { 3, 6, 7, 8, 9, 4, 5, 2, 1, 0, 9 };
+static const int leds_order[] = { 3, 6, 7, 8, 9, 4, 5, 2, 1, 0, 9 };
 static const TCHAR *lacer[] = { _T("off"), _T("i"), _T("p"), 0 };
 static const TCHAR *hdcontrollers[] = {
        _T("uae"),
-       _T("ide%d"), _T("ide%d_mainboard"), _T("ide%d_a3001"),
-       _T("scsi%d"), _T("scsi%d_a2091"),  _T("scsi%d_a2091-2"), _T("scsi%d_gvp"), _T("scsi%d_gvp-2"), _T("scsi%d_a4091"),  _T("scsi%d_a4091-2"),
+
+       _T("ide%d"),
+       _T("ide%d_mainboard"),
+       _T("ide%d_a3001"),
+       _T("ide%d_alfa"), _T("ide%d_alfa-2"),
+       _T("ide%d_apollo"), _T("ide%d_apollo-2"),
+       _T("ide%d_masoboshi"), _T("ide%d_masoboshi-2"),
+       //_T("ide%d_adide"), _T("ide%d_adide-2"),
+
+       _T("scsi%d"),
+       _T("scsi%d_a2091"),  _T("scsi%d_a2091-2"),
+       _T("scsi%d_gvp"), _T("scsi%d_gvp-2"),
+       _T("scsi%d_a4091"),  _T("scsi%d_a4091-2"),
        _T("scsi%d_fastlane"), _T("scsi%d_fastlane-2"),
        _T("scsi%d_oktagon2008"), _T("scsi%d_oktagon2008-2"),
-       _T("scsi%d_a3000"),  _T("scsi%d_a4000t"),  _T("scsi%d_cdtv"), _T("scsi%d_cpuboard"),
-       _T("scsram"), _T("scide")
+       _T("scsi%d_apollo"), _T("scsi%d_apollo-2"),
+       _T("scsi%d_masoboshi"), _T("scsi%d_masoboshi-2"),
+       _T("scsi%d_a3000"),
+       _T("scsi%d_a4000t"),
+       _T("scsi%d_cdtv"),
+       _T("scsi%d_cpuboard"),
+
+       _T("scsram"),
+       _T("scide")
 };
 static const TCHAR *z3mapping[] = {
        _T("auto"),
@@ -290,6 +310,16 @@ static const TCHAR *obsolete[] = {
        _T("gfx_filter_vert_offset"), _T("gfx_filter_horiz_offset"),
        _T("rtg_vert_zoom_multf"), _T("rtg_horiz_zoom_multf"),
        
+       // created by some buggy beta
+       _T("uaehf0%s,%s"),
+       _T("uaehf1%s,%s"),
+       _T("uaehf2%s,%s"),
+       _T("uaehf3%s,%s"),
+       _T("uaehf4%s,%s"),
+       _T("uaehf5%s,%s"),
+       _T("uaehf6%s,%s"),
+       _T("uaehf7%s,%s"),
+
        NULL
 };
 
@@ -1030,10 +1060,15 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
                cfgfile_write_str (f, _T("kickstart_ext_rom="), p->romextident);
 
        cfgfile_write_board_rom(f, &p->path_rom, &p->a2091rom, _T("a2091"));
-       cfgfile_write_board_rom(f, &p->path_rom, &p->gvprom, _T("gvp"));
+       cfgfile_write_board_rom(f, &p->path_rom, &p->gvps1rom, _T("gvp1"));
+       cfgfile_write_board_rom(f, &p->path_rom, &p->gvps2rom, _T("gvp"));
        cfgfile_write_board_rom(f, &p->path_rom, &p->a4091rom, _T("a4091"));
        cfgfile_write_board_rom(f, &p->path_rom, &p->fastlanerom, _T("fastlane"));
        cfgfile_write_board_rom(f, &p->path_rom, &p->oktagonrom, _T("oktagon2008"));
+       cfgfile_write_board_rom(f, &p->path_rom, &p->alfrom, _T("alfapower"));
+       cfgfile_write_board_rom(f, &p->path_rom, &p->alfplusrom, _T("alfapowerplus"));
+       cfgfile_write_board_rom(f, &p->path_rom, &p->apollorom, _T("apollo"));
+       cfgfile_write_board_rom(f, &p->path_rom, &p->masoboshirom, _T("masoboshi"));
 
        cfgfile_write_rom(f, &p->path_rom, p->acceleratorromfile, _T("cpuboard_rom_file"));
        if (p->acceleratorromident[0])
@@ -3136,7 +3171,7 @@ static void get_filesys_controller (const TCHAR *hdc, int *type, int *num)
                                const TCHAR *ext2 = _tcsrchr(hdcontrollers[i], '_');
                                if (ext2) {
                                        ext2++;
-                                       if (!_tcsicmp(ext, ext2)) {
+                                       if (!_tcsicmp(ext, ext2) && hdc[0] == hdcontrollers[i][0]) {
                                                hdcv = i;
                                                break;
                                        }
@@ -3841,7 +3876,9 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH
 
        if (cfgfile_read_board_rom(option, value, &p->path_rom, &p->a2091rom, _T("a2091"), ROMTYPE_A2091))
                return 1;
-       if (cfgfile_read_board_rom(option, value, &p->path_rom, &p->gvprom, _T("gvp"), ROMTYPE_GVP))
+       if (cfgfile_read_board_rom(option, value, &p->path_rom, &p->gvps1rom, _T("gvp1"), ROMTYPE_GVPS1))
+               return 1;
+       if (cfgfile_read_board_rom(option, value, &p->path_rom, &p->gvps2rom, _T("gvp"), ROMTYPE_GVPS2))
                return 1;
        if (cfgfile_read_board_rom(option, value, &p->path_rom, &p->a4091rom, _T("a4091"), ROMTYPE_A4091))
                return 1;
@@ -3849,6 +3886,14 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH
                return 1;
        if (cfgfile_read_board_rom(option, value, &p->path_rom, &p->oktagonrom, _T("oktagon2008"), ROMTYPE_OKTAGON))
                return 1;
+       if (cfgfile_read_board_rom(option, value, &p->path_rom, &p->alfrom, _T("alfapower"), ROMTYPE_ALFA))
+               return 1;
+       if (cfgfile_read_board_rom(option, value, &p->path_rom, &p->alfplusrom, _T("alfapowerplus"), ROMTYPE_ALFAPLUS))
+               return 1;
+       if (cfgfile_read_board_rom(option, value, &p->path_rom, &p->apollorom, _T("apollo"), ROMTYPE_APOLLO))
+               return 1;
+       if (cfgfile_read_board_rom(option, value, &p->path_rom, &p->masoboshirom, _T("masoboshi"), ROMTYPE_MASOBOSHI))
+               return 1;
 
        for (i = 0; i < 4; i++) {
                _stprintf (tmpbuf, _T("floppy%d"), i);
@@ -4435,9 +4480,13 @@ static int cfgfile_load_2 (struct uae_prefs *p, const TCHAR *filename, bool real
 
        for (i = 0; i < MAX_BOARD_ROMS; i++) {
                subst(p->path_rom.path[0], p->a2091rom.roms[i].romfile, MAX_DPATH / sizeof(TCHAR));
-               subst(p->path_rom.path[0], p->gvprom.roms[i].romfile, MAX_DPATH / sizeof(TCHAR));
+               subst(p->path_rom.path[0], p->gvps1rom.roms[i].romfile, MAX_DPATH / sizeof(TCHAR));
+               subst(p->path_rom.path[0], p->gvps2rom.roms[i].romfile, MAX_DPATH / sizeof(TCHAR));
                subst(p->path_rom.path[0], p->a4091rom.roms[i].romfile, MAX_DPATH / sizeof(TCHAR));
                subst(p->path_rom.path[0], p->fastlanerom.roms[i].romfile, MAX_DPATH / sizeof (TCHAR));
+               subst(p->path_rom.path[0], p->alfrom.roms[i].romfile, MAX_DPATH / sizeof (TCHAR));
+               subst(p->path_rom.path[0], p->alfplusrom.roms[i].romfile, MAX_DPATH / sizeof (TCHAR));
+               subst(p->path_rom.path[0], p->masoboshirom.roms[i].romfile, MAX_DPATH / sizeof (TCHAR));
        }
 
        return 1;
@@ -6093,6 +6142,8 @@ static int bip_a1200 (struct uae_prefs *p, int config, int compa, int romcheck)
        roms[2] = 31;
        roms[3] = -1;
        p->cs_rtc = 0;
+       p->cs_compatible = CP_A1200;
+       built_in_chipset_prefs (p);
        switch (config)
        {
                case 1:
@@ -6132,8 +6183,6 @@ static int bip_a1200 (struct uae_prefs *p, int config, int compa, int romcheck)
                break;
        }
        set_68020_compa (p, compa, 0);
-       p->cs_compatible = CP_A1200;
-       built_in_chipset_prefs (p);
        return configure_rom (p, roms, romcheck);
 }
 
@@ -6145,6 +6194,9 @@ static int bip_a600 (struct uae_prefs *p, int config, int compa, int romcheck)
        roms[1] = 9;
        roms[2] = 8;
        roms[3] = -1;
+       set_68000_compa (p, compa);
+       p->cs_compatible = CP_A600;
+       built_in_chipset_prefs (p);
        p->bogomem_size = 0;
        p->chipmem_size = 0x100000;
        if (config > 0)
@@ -6154,9 +6206,6 @@ static int bip_a600 (struct uae_prefs *p, int config, int compa, int romcheck)
        if (config == 2)
                p->fastmem_size = 0x400000;
        p->chipset_mask = CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE;
-       set_68000_compa (p, compa);
-       p->cs_compatible = CP_A600;
-       built_in_chipset_prefs (p);
        return configure_rom (p, roms, romcheck);
 }
 
@@ -6166,6 +6215,9 @@ static int bip_a500p (struct uae_prefs *p, int config, int compa, int romcheck)
 
        roms[0] = 7;
        roms[1] = -1;
+       set_68000_compa (p, compa);
+       p->cs_compatible = CP_A500P;
+       built_in_chipset_prefs (p);
        p->bogomem_size = 0;
        p->chipmem_size = 0x100000;
        if (config > 0)
@@ -6175,9 +6227,6 @@ static int bip_a500p (struct uae_prefs *p, int config, int compa, int romcheck)
        if (config == 2)
                p->fastmem_size = 0x400000;
        p->chipset_mask = CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE;
-       set_68000_compa (p, compa);
-       p->cs_compatible = CP_A500P;
-       built_in_chipset_prefs (p);
        return configure_rom (p, roms, romcheck);
 }
 static int bip_a500 (struct uae_prefs *p, int config, int compa, int romcheck)
index b7857919a533bafc36196437350775183b5b6a51..cbfdbed49fb934108300aff551108fa3ed239244 100644 (file)
@@ -28,6 +28,8 @@
 #include "flashrom.h"
 #include "uae.h"
 #include "uae/ppc.h"
+#include "idecontrollers.h"
+#include "scsi.h"
 
 #define CPUBOARD_IO_LOG 0
 #define CPUBOARD_IRQ_LOG 0
@@ -266,6 +268,10 @@ static bool is_fusionforty(void)
 {
        return currprefs.cpuboard_type == BOARD_FUSIONFORTY;
 }
+static bool is_apollo(void)
+{
+       return currprefs.cpuboard_type == BOARD_APOLLO;
+}
 
 DECLARE_MEMORY_FUNCTIONS(blizzardio);
 static addrbank blizzardio_bank = {
@@ -756,7 +762,7 @@ static void REGPARAM2 blizzarde8_bput(uaecptr addr, uae_u32 b)
        addr &= 65535;
        if (addr == 0x48 && !configured) {
                map_banks(&blizzardea_bank, b, 0x20000 >> 16, 0x20000);
-               write_log(_T("Blizzard/CyberStorm Z2 autoconfigured at %02X0000\n"), b);
+               write_log(_T("Accelerator Z2 board autoconfigured at %02X0000\n"), b);
                configured = 1;
                expamem_next (&blizzardea_bank, NULL);
                return;
@@ -1310,6 +1316,9 @@ void cpuboard_map(void)
                map_banks(&blizzardio_bank, 0x021d0000 >> 16, 65536 >> 16, 0);
                map_banks(&blizzardram_bank, blizzardram_bank.start >> 16, cpuboard_size >> 16, 0);
        }
+       if (is_apollo()) {
+               map_banks(&blizzardf0_bank, 0xf00000 >> 16, 131072 >> 16, 0);
+       }
 }
 
 void cpuboard_reset(void)
@@ -1403,6 +1412,13 @@ void cpuboard_init(void)
                blizzardea_bank.mask = blizzardea_bank.allocated - 1;
                mapped_malloc(&blizzardea_bank);
 
+       } else if (is_apollo()) {
+
+               blizzardf0_bank.start = 0x00f00000;
+               blizzardf0_bank.allocated = 131072;
+               blizzardf0_bank.mask = blizzardf0_bank.allocated - 1;
+               mapped_malloc(&blizzardf0_bank);
+
        } else if (is_fusionforty()) {
 
                blizzardf0_bank.start = 0x00f40000;
@@ -1635,8 +1651,10 @@ int cpuboard_memorytype(struct uae_prefs *p)
                case BOARD_TEKMAGIC:
                case BOARD_FUSIONFORTY:
                case BOARD_DKB1200: // ??
+               case BOARD_APOLLO:
                return BOARD_MEMORY_HIGHMEM;
                case BOARD_A2630:
+               case BOARD_GVP_A530:
                return BOARD_MEMORY_Z2;
                case BOARD_BLIZZARD_1230_IV:
                case BOARD_BLIZZARD_1230_IV_SCSI:
@@ -1819,6 +1837,11 @@ addrbank *cpuboard_autoconfig_init(void)
                roms[0] = 105;
                roms[1] = 106;
                break;
+       case BOARD_GVP_A530:
+               return &expamem_null;
+       case BOARD_APOLLO:
+               roms[0] = 119;
+               break;
        case BOARD_A3001_I:
        case BOARD_A3001_II:
                return &expamem_null;
@@ -1869,31 +1892,36 @@ addrbank *cpuboard_autoconfig_init(void)
                return &expamem_null;
        }
 
-       struct romlist *rl = getromlistbyids(roms, romname);
-       if (!rl) {
-               rd = getromdatabyids(roms);
-               if (!rd)
-                       return &expamem_null;
-       } else {
-               rd = rl->rd;
+       struct romlist *rl = NULL;
+       if (roms[0] >= 0) {
+               getromlistbyids(roms, romname);
+               if (!rl) {
+                       rd = getromdatabyids(roms);
+                       if (!rd)
+                               return &expamem_null;
+               } else {
+                       rd = rl->rd;
+               }
+               defaultromname = rd->defaultfilename;
        }
-       defaultromname = rd->defaultfilename;
-       if (rl && !isflashrom) {
+       if (!isflashrom) {
                if (romname)
                        autoconfig_rom = zfile_fopen(romname, _T("rb"));
                if (!autoconfig_rom && defaultromname)
                        autoconfig_rom = zfile_fopen(defaultromname, _T("rb"));
-               if (autoconfig_rom) {
-                       struct romdata *rd2 = getromdatabyids(roms);
-                       // Do not use image if it is not long enough (odd or even only?)
-                       if (!rd2 || zfile_size(autoconfig_rom) < rd2->size) {
-                               zfile_fclose(autoconfig_rom);
-                               autoconfig_rom = NULL;
+               if (rl) {
+                       if (autoconfig_rom) {
+                               struct romdata *rd2 = getromdatabyids(roms);
+                               // Do not use image if it is not long enough (odd or even only?)
+                               if (!rd2 || zfile_size(autoconfig_rom) < rd2->size) {
+                                       zfile_fclose(autoconfig_rom);
+                                       autoconfig_rom = NULL;
+                               }
                        }
+                       if (!autoconfig_rom)
+                               autoconfig_rom = read_rom(rl->rd);
                }
-               if (!autoconfig_rom)
-                       autoconfig_rom = read_rom(rl->rd);
-       } else if (isflashrom) {
+       } else {
                autoconfig_rom = flashfile_open(romname);
                if (!autoconfig_rom) {
                        if (rl)
@@ -1913,8 +1941,12 @@ addrbank *cpuboard_autoconfig_init(void)
                write_log (_T("ROM id %d not found for CPU board emulation\n"), roms[0]);
                return &expamem_null;
        }
-       if (autoconfig_rom)
-               write_log(_T("CPUBoard ROM '%s' %lld loaded\n"), zfile_getname(autoconfig_rom), zfile_size(autoconfig_rom));
+       if (!autoconfig_rom) {
+               write_log(_T("Couldn't open CPU board rom '%s'\n"), defaultromname);
+               return &expamem_null;
+       }
+
+       write_log(_T("CPUBoard ROM '%s' %lld loaded\n"), zfile_getname(autoconfig_rom), zfile_size(autoconfig_rom));
 
        protect_roms(false);
        cpuboard_non_byte_ea = true;
@@ -1923,6 +1955,10 @@ addrbank *cpuboard_autoconfig_init(void)
                zfile_fread(blizzardf0_bank.baseaddr, 1, f0rom_size, autoconfig_rom);
                autoconf = false;
                autoconf_stop = true;
+       } else if (is_apollo()) {
+               f0rom_size = 131072;
+               zfile_fread(blizzardf0_bank.baseaddr, 1, 131072, autoconfig_rom);
+               autoconf = false;
        } else if (is_fusionforty()) {
                f0rom_size = 262144;
                zfile_fread(blizzardf0_bank.baseaddr, 1, 131072, autoconfig_rom);
index 58fd34c8977b8c99b9a9947bef4f24d943d4ed56..e656636ea2392aa541d69a6dc13ba5602b80549b 100644 (file)
@@ -65,6 +65,7 @@ void devices_reset(int hardreset)
        DISK_reset ();
        CIA_reset ();
        gayle_reset (0);
+       apolloscsi_reset();
 #ifdef A2091
        a2091_reset ();
        gvp_reset ();
@@ -274,6 +275,7 @@ void do_leave_program (void)
        gvp_free ();
        a3000scsi_free ();
 #endif
+       apolloscsi_free();
 #ifdef NCR
        ncr710_free();
        ncr_free();
index 17d5b28df09489c06c9261b01ffd7addf446b369..fc28c202df68e07906ccdf8e0898c3e093b16296 100644 (file)
@@ -1066,6 +1066,9 @@ static addrbank *expamem_init_fastcard_2 (int boardnum)
        int allocated = boardnum ? fastmem2_bank.allocated : fastmem_bank.allocated;
        uae_u32 serial = 1;
 
+       if (allocated == 0)
+               return &expamem_null;
+
        expamem_init_clear ();
        if (allocated == 65536)
                type |= Z2_MEM_64KB;
@@ -1095,10 +1098,22 @@ static addrbank *expamem_init_fastcard_2 (int boardnum)
                pid = commodore_a2091_ram;
                mid = commodore;
                serial = 0;
-       } else if (cfgfile_board_enabled(&currprefs.gvprom) || currprefs.cpuboard_type == BOARD_A3001_I || currprefs.cpuboard_type == BOARD_A3001_II) {
+       } else if (cfgfile_board_enabled(&currprefs.gvps1rom) || cfgfile_board_enabled(&currprefs.gvps2rom) || currprefs.cpuboard_type == BOARD_A3001_I || currprefs.cpuboard_type == BOARD_A3001_II) {
                pid = 10;
                mid = 2017;
                serial = 0;
+       } else if (cfgfile_board_enabled(&currprefs.alfrom) || cfgfile_board_enabled(&currprefs.alfplusrom)) {
+               pid = 8;
+               mid = 2092;
+               serial = 0;
+       } else if (cfgfile_board_enabled(&currprefs.apollorom)) {
+               pid = 0;
+               mid = 8738;
+               serial = 0;
+       } else if (cfgfile_board_enabled(&currprefs.masoboshirom)) {
+               pid = 3;
+               mid = 2157;
+               serial = 0;
        } else {
                pid = currprefs.maprom && !currprefs.cpuboard_type ? 1 : 81;
                mid = uae_id;
@@ -1644,6 +1659,34 @@ uaecptr need_uae_boot_rom (void)
        return v;
 }
 
+static addrbank *expamem_init_masoboshi(void)
+{
+       return masoboshi_init (0);
+}
+static addrbank *expamem_init_masoboshi_2(void)
+{
+       return masoboshi_init (1);
+}
+static addrbank *expamem_init_alf(void)
+{
+       return alf_init (0);
+}
+static addrbank *expamem_init_alf_2(void)
+{
+       return alf_init (1);
+}
+static addrbank *expamem_init_apollo(void)
+{
+       return apollo_init (0);
+}
+static addrbank *expamem_init_apollo_2(void)
+{
+       return apollo_init (1);
+}
+static addrbank *expamem_init_apollo_cpu(void)
+{
+       return apollo_init (-1);
+}
 #ifdef WITH_TOCCATA
 static addrbank *expamem_init_toccata(void)
 {
@@ -1667,23 +1710,27 @@ static addrbank *expamem_init_a2091(void)
 {
        return a2091_init (0);
 }
-#endif
-#ifdef A2091
 static addrbank *expamem_init_a2091_2(void)
 {
        return a2091_init (1);
 }
 #endif
 #ifdef A2091
-static addrbank *expamem_init_gvp(void)
+static addrbank *expamem_init_gvp_s1(void)
 {
-       return gvp_init(0);
+       return gvp_init(0, false);
 }
-#endif
-#ifdef A2091
-static addrbank *expamem_init_gvp_2(void)
+static addrbank *expamem_init_gvp_s1_2(void)
 {
-       return gvp_init(1);
+       return gvp_init(1, false);
+}
+static addrbank *expamem_init_gvp_s2(void)
+{
+       return gvp_init(0, true);
+}
+static addrbank *expamem_init_gvp_s2_2(void)
+{
+       return gvp_init(1, true);
 }
 #endif
 #ifdef NCR
@@ -1820,6 +1867,18 @@ void expamem_reset (void)
                card_init[cardno] = expamem_init_a3001_ide;
                card_map[cardno++] = NULL;
        }
+       if (currprefs.cpuboard_type == BOARD_GVP_A530) {
+               card_flags[cardno] = 1;
+               card_name[cardno] = _T("GVP A530");
+               card_init[cardno] = expamem_init_gvp_s2_2;
+               card_map[cardno++] = NULL;
+       }
+
+       if (currprefs.cpuboard_type == BOARD_APOLLO) {
+               card_name[cardno] = _T("Apollo");
+               card_init[cardno] = expamem_init_apollo_cpu;
+               card_map[cardno++] = NULL;
+       }
 
 #ifdef A2091
        if (cfgfile_board_enabled(&currprefs.a2091rom)) {
@@ -1833,13 +1892,22 @@ void expamem_reset (void)
        }
 #endif
 #ifdef A2091
-       if (cfgfile_board_enabled(&currprefs.gvprom)) {
+       if (cfgfile_board_enabled(&currprefs.gvps2rom)) {
+               card_flags[cardno] = 0;
+               card_name[cardno] = _T("GVP SII");
+               card_init[cardno] = expamem_init_gvp_s2;
+               card_map[cardno++] = NULL;
+               card_name[cardno] = _T("GVP SII #2");
+               card_init[cardno] = expamem_init_gvp_s2_2;
+               card_map[cardno++] = NULL;
+       }
+       if (cfgfile_board_enabled(&currprefs.gvps1rom)) {
                card_flags[cardno] = 0;
-               card_name[cardno] = _T("GVP");
-               card_init[cardno] = expamem_init_gvp;
+               card_name[cardno] = _T("GVP SI");
+               card_init[cardno] = expamem_init_gvp_s1;
                card_map[cardno++] = NULL;
-               card_name[cardno] = _T("GVP #2");
-               card_init[cardno] = expamem_init_gvp_2;
+               card_name[cardno] = _T("GVP SI #2");
+               card_init[cardno] = expamem_init_gvp_s1_2;
                card_map[cardno++] = NULL;
        }
 #endif
@@ -1853,6 +1921,30 @@ void expamem_reset (void)
                card_map[cardno++] = NULL;
        }
 #endif
+       if (cfgfile_board_enabled(&currprefs.alfrom) || cfgfile_board_enabled(&currprefs.alfplusrom)) {
+               card_name[cardno] = _T("ALF");
+               card_init[cardno] = expamem_init_alf;
+               card_map[cardno++] = NULL;
+               card_name[cardno] = _T("ALF #2");
+               card_init[cardno] = expamem_init_alf_2;
+               card_map[cardno++] = NULL;
+       }
+       if (cfgfile_board_enabled(&currprefs.apollorom)) {
+               card_name[cardno] = _T("Apollo");
+               card_init[cardno] = expamem_init_apollo;
+               card_map[cardno++] = NULL;
+               card_name[cardno] = _T("Apollo #2");
+               card_init[cardno] = expamem_init_apollo_2;
+               card_map[cardno++] = NULL;
+       }
+       if (cfgfile_board_enabled(&currprefs.masoboshirom)) {
+               card_name[cardno] = _T("Masoboshi");
+               card_init[cardno] = expamem_init_masoboshi;
+               card_map[cardno++] = NULL;
+               card_name[cardno] = _T("Masoboshi #2");
+               card_init[cardno] = expamem_init_masoboshi_2;
+               card_map[cardno++] = NULL;
+       }
 #ifdef CDTV
        if (currprefs.cs_cdtvcd && !currprefs.cs_cdtvcr) {
                card_flags[cardno] = 0;
index e758dfb0521c00129485cd043f8e9ed5443c6ee2..33870a90e3f85decb668f6378e14a1871c620b25 100644 (file)
@@ -455,8 +455,10 @@ TCHAR *validatevolumename (TCHAR *s, const TCHAR *def)
        stripsemicolon (s);
        fixcharset (s);
        striplength (s, 30);
-       if (_tcslen(s) == 0 && def)
-               _tcscpy(s, def);
+       if (_tcslen(s) == 0 && def) {
+               xfree(s);
+               s = my_strdup(def);
+       }
        return s;
 }
 TCHAR *validatedevicename (TCHAR *s, const TCHAR *def)
@@ -465,8 +467,10 @@ TCHAR *validatedevicename (TCHAR *s, const TCHAR *def)
        stripspace (s);
        fixcharset (s);
        striplength (s, 30);
-       if (_tcslen(s) == 0 && def)
-               _tcscpy(s, def);
+       if (_tcslen(s) == 0 && def) {
+               xfree(s);
+               s = my_strdup(def);
+       }
        return s;
 }
 
@@ -484,7 +488,7 @@ TCHAR *filesys_createvolname (const TCHAR *volname, const TCHAR *rootdir, struct
 
        if (zv && zv->volumename && _tcslen(zv->volumename) > 0) {
                nvol = my_strdup(zv->volumename);
-               validatevolumename (nvol, def);
+               nvol = validatevolumename (nvol, def);
                return nvol;
        }
 
@@ -523,7 +527,7 @@ TCHAR *filesys_createvolname (const TCHAR *volname, const TCHAR *rootdir, struct
                else
                        nvol = my_strdup (_T(""));
        }
-       validatevolumename (nvol, def);
+       nvol = validatevolumename (nvol, def);
        xfree (p);
        return nvol;
 }
@@ -812,6 +816,13 @@ static bool add_cpuboard_scsi_unit(int unit, struct uaedev_config_info *uci)
                        added = true;
        }
 #endif
+       if (currprefs.cpuboard_type == BOARD_APOLLO) {
+               apollo_add_scsi_unit(unit, uci, 0);
+               added = true;
+       } else if (currprefs.cpuboard_type == BOARD_GVP_A530) {
+               gvp_add_scsi_unit(unit, uci, 1);
+               added = true;
+       }
        return added;
 }
 
@@ -824,8 +835,40 @@ static bool add_ide_unit(int type, int unit, struct uaedev_config_info *uci)
                        added = true;
                }
        } else if (type == HD_CONTROLLER_TYPE_IDE_GVP) {
-               gvp_add_ide_unit(unit, uci);
-               added = true;
+               if (currprefs.cpuboard_type == BOARD_A3001_I || currprefs.cpuboard_type == BOARD_A3001_II) {
+                       gvp_add_ide_unit(unit, uci);
+                       added = true;
+               }
+       } else if (type == HD_CONTROLLER_TYPE_IDE_ALFA) {
+               if (cfgfile_board_enabled(&currprefs.alfrom) || cfgfile_board_enabled(&currprefs.alfplusrom)) {
+                       alf_add_ide_unit(unit, uci, 0);
+                       added = true;
+               }
+       } else if (type == HD_CONTROLLER_TYPE_IDE_ALFA_2) {
+               if (cfgfile_board_enabled(&currprefs.alfrom) || cfgfile_board_enabled(&currprefs.alfplusrom)) {
+                       alf_add_ide_unit(unit, uci, 1);
+                       added = true;
+               }
+       } else if (type == HD_CONTROLLER_TYPE_IDE_APOLLO) {
+               if (cfgfile_board_enabled(&currprefs.apollorom)) {
+                       apollo_add_ide_unit(unit, uci, 0);
+                       added = true;
+               }
+       } else if (type == HD_CONTROLLER_TYPE_IDE_APOLLO_2) {
+               if (cfgfile_board_enabled(&currprefs.apollorom)) {
+                       apollo_add_ide_unit(unit, uci, 1);
+                       added = true;
+               }
+       } else if (type == HD_CONTROLLER_TYPE_IDE_MASOBOSHI) {
+               if (cfgfile_board_enabled(&currprefs.masoboshirom)) {
+                       masoboshi_add_ide_unit(unit, uci, 0);
+                       added = true;
+               }
+       } else if (type == HD_CONTROLLER_TYPE_IDE_MASOBOSHI_2) {
+               if (cfgfile_board_enabled(&currprefs.masoboshirom)) {
+                       masoboshi_add_ide_unit(unit, uci, 1);
+                       added = true;
+               }
        }
        return added;
 }
@@ -872,15 +915,14 @@ static bool add_scsi_unit(int type, int unit, struct uaedev_config_info *uci)
 #endif
        } else if (type == HD_CONTROLLER_TYPE_SCSI_GVP) {
 #ifdef A2091
-               if (cfgfile_board_enabled(&currprefs.gvprom)) {
+               if (cfgfile_board_enabled(&currprefs.gvps2rom) || cfgfile_board_enabled(&currprefs.gvps1rom)) {
                        gvp_add_scsi_unit(unit, uci, 0);
                        added = true;
                }
 #endif
-       }
-       else if (type == HD_CONTROLLER_TYPE_SCSI_GVP_2) {
+       } else if (type == HD_CONTROLLER_TYPE_SCSI_GVP) {
 #ifdef A2091
-               if (cfgfile_board_enabled(&currprefs.gvprom)) {
+               if (cfgfile_board_enabled(&currprefs.gvps2rom) || cfgfile_board_enabled(&currprefs.gvps1rom)) {
                        gvp_add_scsi_unit(unit, uci, 1);
                        added = true;
                }
@@ -927,6 +969,26 @@ static bool add_scsi_unit(int type, int unit, struct uaedev_config_info *uci)
                        added = true;
                }
 #endif
+       } else if (type == HD_CONTROLLER_TYPE_SCSI_APOLLO) {
+               if (cfgfile_board_enabled(&currprefs.apollorom)) {
+                       apollo_add_scsi_unit(unit, uci, 0);
+                       added = true;
+               }
+       } else if (type == HD_CONTROLLER_TYPE_SCSI_APOLLO_2) {
+               if (cfgfile_board_enabled(&currprefs.apollorom)) {
+                       apollo_add_scsi_unit(unit, uci, 1);
+                       added = true;
+               }
+       } else if (type == HD_CONTROLLER_TYPE_SCSI_MASOBOSHI) {
+               if (cfgfile_board_enabled(&currprefs.masoboshirom)) {
+                       masoboshi_add_scsi_unit(unit, uci, 0);
+                       added = true;
+               }
+       } else if (type == HD_CONTROLLER_TYPE_SCSI_MASOBOSHI_2) {
+               if (cfgfile_board_enabled(&currprefs.masoboshirom)) {
+                       masoboshi_add_scsi_unit(unit, uci, 1);
+                       added = true;
+               }
        }
        return added;
 }
index 38d50be7aace442b89c85f0b5528051d88a2f684..cf4df931082aa1c848428cc7a297f215722b61eb 100644 (file)
--- a/gayle.cpp
+++ b/gayle.cpp
@@ -909,7 +909,7 @@ addrbank mbres_bank = {
 
 void gayle_hsync (void)
 {
-       if (ide_interrupt_check(idedrive, TOTAL_IDE * 2))
+       if (ide_interrupt_check(idedrive[0]) || ide_interrupt_check(idedrive[2]) || ide_interrupt_check(idedrive[4]))
                rethink_gayle ();
 }
 
diff --git a/ide.cpp b/ide.cpp
index 79509fe3d3963567055aa7af9e8141585246046b..89030e841e4785f29a667b795d20e37823d45b8b 100644 (file)
--- a/ide.cpp
+++ b/ide.cpp
@@ -128,11 +128,11 @@ static bool ide_interrupt_do (struct ide_hdf *ide)
        return true;
 }
 
-bool ide_interrupt_check(struct ide_hdf **idetable, int num)
+bool ide_interrupt_check(struct ide_hdf *idep)
 {
        bool irq = false;
-       for (int i = 0; i < num; i++) {
-               struct ide_hdf *ide = idetable[i];
+       for (int i = 0; i < 2; i++) {
+               struct ide_hdf *ide = i == 0 ? idep : idep->pair;
                if (ide) {
                        if (ide->irq_delay > 0) {
                                ide->irq_delay--;
@@ -588,8 +588,8 @@ static void do_process_rw_command (struct ide_hdf *ide)
        bool last;
 
        ide->data_offset = 0;
-       get_lbachs (ide, &lba, &cyl, &head, &sec);
        nsec = get_nsec (ide);
+       get_lbachs (ide, &lba, &cyl, &head, &sec);
        if (IDE_LOG > 1)
                write_log (_T("IDE%d off=%d, nsec=%d (%d) lba48=%d\n"), ide->num, (uae_u32)lba, nsec, ide->multiple_mode, ide->lba48 + ide->lba48cmd);
        if (nsec * ide->blocksize > ide->hdhfd.size - lba * ide->blocksize) {
@@ -759,6 +759,8 @@ static void ide_do_command (struct ide_hdf *ide, uae_u8 cmd)
                        ide_set_features (ide);
                } else if (cmd == 0x00) { /* nop */
                        ide_fail (ide);
+               } else if (cmd == 0x70) { /* seek */
+                       ide_interrupt (ide);
                } else if (cmd == 0xe0 || cmd == 0xe1 || cmd == 0xe7 || cmd == 0xea) { /* standby now/idle/flush cache/flush cache ext */
                        ide_interrupt (ide);
                } else if (cmd == 0xe5) { /* check power mode */
@@ -776,8 +778,6 @@ uae_u16 ide_get_data (struct ide_hdf *ide)
        bool irq = false;
        uae_u16 v;
 
-       if (IDE_LOG > 4)
-               write_log (_T("IDE%d DATA read\n"), ide->num);
        if (ide->data_size == 0) {
                if (IDE_LOG > 0)
                        write_log (_T("IDE%d DATA but no data left!? %02X PC=%08X\n"), ide->num, ide->regs.ide_status, m68k_getpc ());
@@ -787,6 +787,8 @@ uae_u16 ide_get_data (struct ide_hdf *ide)
        }
        if (ide->packet_state) {
                v = ide->secbuf[ide->packet_data_offset + ide->data_offset + 1] | (ide->secbuf[ide->packet_data_offset + ide->data_offset + 0] << 8);
+               if (IDE_LOG > 4)
+                       write_log (_T("IDE%d DATA read %04x\n"), ide->num, v);
                ide->data_offset += 2;
                if (ide->data_size < 0)
                        ide->data_size += 2;
@@ -807,6 +809,8 @@ uae_u16 ide_get_data (struct ide_hdf *ide)
                }
        } else {
                v = ide->secbuf[ide->data_offset + 1] | (ide->secbuf[ide->data_offset + 0] << 8);
+               if (IDE_LOG > 4)
+                       write_log (_T("IDE%d DATA read %04x\n"), ide->num, v);
                ide->data_offset += 2;
                if (ide->data_size < 0) {
                        ide->data_size += 2;
@@ -876,7 +880,7 @@ uae_u32 ide_read_reg (struct ide_hdf *ide, int ide_reg)
                if (ide_reg == IDE_STATUS && ide->pair->irq)
                        ide->pair->irq = 0;
                if (ide_isdrive (ide->pair))
-                       v = 0x00;
+                       v = 0x01;
                else
                        v = 0xff;
                goto end;
index 7dfe7c24e3d43a6a19ff2fb5343ed358863cc56a..1cb2738e4f549599031ecf172bf3bd8a3271da77 100644 (file)
 #include "custom.h"
 #include "rommgr.h"
 #include "cpuboard.h"
+#include "scsi.h"
+#include "ncr9x_scsi.h"
 
 #define DEBUG_IDE 0
+#define DEBUG_IDE_GVP 0
+#define DEBUG_IDE_ALF 0
+#define DEBUG_IDE_APOLLO 0
+#define DEBUG_IDE_MASOBOSHI 0
 
 #define GVP_IDE 0 // GVP A3001
-#define TOTAL_IDE 1
+#define ALF_IDE 1
+#define APOLLO_IDE 3
+#define MASOBOSHI_IDE 5
+#define TOTAL_IDE 7
 
+#define ALF_ROM_OFFSET 0x0100
 #define GVP_IDE_ROM_OFFSET 0x8000
+#define APOLLO_ROM_OFFSET 0x8000
+#define MASOBOSHI_ROM_OFFSET 0x0080
+#define MASOBOSHI_ROM_OFFSET_END 0xf000
+#define MASOBOSHI_SCSI_OFFSET 0xf800
+#define MASOBOSHI_SCSI_OFFSET_END 0xfc00
+
+/* masoboshi:
+
+IDE 
+
+- FFCC = base address, data (0)
+- FF81 = -004B
+- FF41 = -008B
+- FF01 = -01CB
+- FEC1 = -010B
+- FE81 = -014B
+- FE41 = -018B select (6)
+- FE01 = -01CB status (7)
+- FE03 = command (7)
+
+- FA00 = ESP, 2 byte register spacing
+- F9CC = data
+
+- F047 = -0F85 (-0FB9) interrupt request? (bit 3)
+- F040 = -0F8C interrupt request? (bit 1) Write anything = clear irq?
+- F000 = some status register
+
+- F04C = DMA address (long)
+- F04A = number of words
+- F044 = ???
+- F047 = bit 7 = start dma
+
+*/
 
 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];
 static struct ide_hdf *idecontroller_drive[TOTAL_IDE * 2];
 static struct ide_thread_state idecontroller_its;
 
-static void init_ide(struct ide_board *board, struct ide_hdf **idetable)
+static struct ide_board *ide_boards[] =
+{
+       &gvp_ide_rom_board,
+       &alf_board[0],
+       &alf_board[1],
+       &apollo_board[0],
+       &apollo_board[1],
+       &masoboshi_board[0],
+       &masoboshi_board[1],
+       NULL
+};
+
+static void init_ide(struct ide_board *board, int ide_num, bool byteswap)
 {
+       struct ide_hdf **idetable = &idecontroller_drive[ide_num * 2];
        alloc_ide_mem (idetable, 2, &idecontroller_its);
        board->ide = idetable[0];
        idetable[0]->board = board;
        idetable[1]->board = board;
-       idetable[0]->byteswap = true;
-       idetable[1]->byteswap = true;
-       ide_initialize(idetable, 0);
+       idetable[0]->byteswap = byteswap;
+       idetable[1]->byteswap = byteswap;
+       ide_initialize(idecontroller_drive, ide_num);
        idecontroller_its.idetable = idecontroller_drive;
        idecontroller_its.idetotal = TOTAL_IDE * 2;
        start_ide_thread(&idecontroller_its);
 }
 
-static bool ide_irq_check(void)
+static bool ide_irq_check(struct ide_board *board)
 {
-       bool irq = ide_interrupt_check(idecontroller_drive, 2);
-       gvp_ide_controller_board.irq = irq;
+       if (!board->configured)
+               return false;
+       bool irq = ide_interrupt_check(board->ide);
+       board->irq = irq;
+       return irq;
+}
+
+static bool ide_rethink(struct ide_board *board)
+{
+       bool irq = false;
+       if (board->configured) {
+               if (board->intena && ide_irq_check(board)) {
+                       irq = true;
+               }
+       }
        return irq;
 }
 
 void idecontroller_rethink(void)
 {
-       if (!gvp_ide_controller_board.configured)
-               return;
-       if (gvp_ide_controller_board.intena && ide_irq_check() && !(intreq & 0x0008)) {
+       bool irq = false;
+       for (int i = 0; ide_boards[i]; i++) {
+               irq |= ide_rethink(ide_boards[i]);
+       }
+       if (irq && !(intreq & 0x0008)) {
                INTREQ_0(0x8000 | 0x0008);
        }
 }
 
 void idecontroller_hsync(void)
 {
-       if (!gvp_ide_controller_board.configured)
-               return;
-       if (ide_irq_check())
-               idecontroller_rethink();
+       for (int i = 0; ide_boards[i]; i++) {
+               if (ide_irq_check(ide_boards[i])) {
+                       idecontroller_rethink();
+               }
+       }
 }
 
 void idecontroller_free_units(void)
@@ -81,26 +156,23 @@ void idecontroller_free_units(void)
        }
 }
 
-int gvp_add_ide_unit(int ch, struct uaedev_config_info *ci)
+static void reset_ide(struct ide_board *board)
 {
-       struct ide_hdf *ide;
-
-       ide = add_ide_unit (idecontroller_drive, 2, ch, ci);
-       if (ide == NULL)
-               return 0;
-       return 1;
+       board->configured = 0;
+       board->intena = false;
+       board->enabled = false;
 }
 
-
-void idecontroller_free(void)
+void idecontroller_reset(void)
 {
-       stop_ide_thread(&idecontroller_its);
+       for (int i = 0; ide_boards[i]; i++) {
+               reset_ide(ide_boards[i]);
+       }
 }
 
-void idecontroller_reset(void)
+void idecontroller_free(void)
 {
-       gvp_ide_controller_board.configured = 0;
-       gvp_ide_controller_board.intena = false;
+       stop_ide_thread(&idecontroller_its);
 }
 
 static bool is_gvp2_intreq(uaecptr addr)
@@ -138,64 +210,198 @@ static int get_gvp_reg(uaecptr addr, struct ide_board *board, struct ide_hdf **i
                reg &= IDE_SECONDARY | 7;
 
        ide = board->ide;
-       if (idecontroller_drive[GVP_IDE]->ide_drv)
+       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)
+{
+       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)
+{
+       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) {
+               addr &= 0xfff;
+               addr >>= 9;
+       } else if (addr & 0x2000) {
+               addr &= 0xfff;
+               addr >>= 9;
+               addr |= IDE_SECONDARY;
+       }
+       return addr;
+}
+
+static int get_masoboshi_reg(uaecptr addr, struct ide_board *board, struct ide_hdf **idep)
+{
+       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 uae_u32 ide_read_byte(struct ide_board *board, uaecptr addr)
 {
-       uae_u8 v = 0;
+       uae_u8 v = 0xff;
        addr &= 0xffff;
+
+#ifdef JIT
+       special_mem |= S_READ;
+#endif
+
+       addr &= board->mask;
+
+#if DEBUG_IDE
+       write_log(_T("IDE IO BYTE READ %08x %08x\n"), addr, M68K_GETPC);
+#endif
+       
        if (addr < 0x40)
                return board->acmemory[addr];
-       if (addr >= GVP_IDE_ROM_OFFSET) {
-               if (board->rom) {
-                       if (addr & 1)
-                               v = 0xe8; // board id
-                       else 
-                               v = board->rom[((addr - GVP_IDE_ROM_OFFSET) / 2) & board->rom_mask];
+       if (board->type == ALF_IDE) {
+
+               if (addr < 0x1100 || (addr & 1)) {
+                       if (board->rom)
+                               v = board->rom[addr & board->rom_mask];
                        return v;
                }
-               v = 0xe8;
-#if DEBUG_IDE
-               write_log(_T("GVP BOOT GET %08x %02x %08x\n"), addr, v, M68K_GETPC);
+               struct ide_hdf *ide;
+               int regnum = get_alf_reg(addr, board, &ide);
+               if (regnum >= 0) {
+                       v = ide_read_reg(ide, regnum);
+               }
+#if DEBUG_IDE_ALF
+               write_log(_T("ALF GET %08x %02x %d %08x\n"), addr, v, regnum, M68K_GETPC);
 #endif
-               return v;
-       }
-       if (board->configured) {
-               if (board == &gvp_ide_rom_board && currprefs.cpuboard_type == BOARD_A3001_II) {
-                       if (addr == 0x42) {
-                               v = 0xff;
+
+       } else if (board->type == MASOBOSHI_IDE) {
+               int regnum = -1;
+               bool rom = false;
+               if (addr >= MASOBOSHI_ROM_OFFSET && addr < MASOBOSHI_ROM_OFFSET_END) {
+                       if (board->rom) {
+                               v = board->rom[addr & board->rom_mask];
+                               rom = true;
                        }
-#if DEBUG_IDE
-                       write_log(_T("GVP BOOT GET %08x %02x %08x\n"), addr, v, M68K_GETPC);
-#endif
+               } else if (addr >= 0xf000 && addr <= 0xf007) {
+                       v = masoboshi_ncr9x_scsi_get(addr, board == &masoboshi_board[0] ? 0 : 1);
+               } else if (addr == 0xf040) {
+                       v = board->irq ? 2 : 0;
+                       v |= masoboshi_ncr9x_scsi_get(addr, board == &masoboshi_board[0] ? 0 : 1);
+               } else if (addr == 0xf047) {
+                       v = board->state;
                } else {
                        struct ide_hdf *ide;
-                       int regnum = get_gvp_reg(addr, board, &ide);
-#if DEBUG_IDE
-                       write_log(_T("GVP IDE GET %08x %02x %d %08x\n"), addr, v, regnum, M68K_GETPC);
-#endif
+                       regnum = get_masoboshi_reg(addr, board, &ide);
                        if (regnum >= 0) {
                                v = ide_read_reg(ide, regnum);
-                       } else if (is_gvp2_intreq(addr)) {
-                               v = board->irq ? 0x40 : 0x00;
-#if DEBUG_IDE
-                               write_log(_T("GVP IRQ %02x\n"), v);
+                       } else if (addr >= MASOBOSHI_SCSI_OFFSET && addr < MASOBOSHI_SCSI_OFFSET_END) {
+                               v = masoboshi_ncr9x_scsi_get(addr, board == &masoboshi_board[0] ? 0 : 1);
+                       }
+               }
+#if DEBUG_IDE_MASOBOSHI
+               if (!rom)
+                       write_log(_T("MASOBOSHI BYTE GET %08x %02x %d %08x\n"), addr, v, regnum, M68K_GETPC);
 #endif
-                               ide_irq_check();
-                       } else if (is_gvp1_intreq(addr)) {
-                               v = gvp_ide_controller_board.irq ? 0x80 : 0x00;
-#if DEBUG_IDE
-                               write_log(_T("GVP IRQ %02x\n"), v);
+       } else if (board->type == APOLLO_IDE) {
+
+               if (addr >= APOLLO_ROM_OFFSET) {
+                       if (board->rom)
+                               v = board->rom[(addr - APOLLO_ROM_OFFSET) & board->rom_mask];
+               } else if (board->configured) {
+                       if ((addr & 0xc000) == 0x4000) {
+                               v = apollo_scsi_bget(addr);
+                       } else if (addr < 0x4000) {
+                               struct ide_hdf *ide;
+                               int regnum = get_apollo_reg(addr, board, &ide);
+                               if (regnum >= 0) {
+                                       v = ide_read_reg(ide, regnum);
+                               } else {
+                                       v = 0;
+                               }
+                       }
+               }
+
+       } else if (board->type == GVP_IDE) {
+
+               if (addr >= GVP_IDE_ROM_OFFSET) {
+                       if (board->rom) {
+                               if (addr & 1)
+                                       v = 0xe8; // board id
+                               else 
+                                       v = board->rom[((addr - GVP_IDE_ROM_OFFSET) / 2) & board->rom_mask];
+                               return v;
+                       }
+                       v = 0xe8;
+#if DEBUG_IDE_GVP
+                       write_log(_T("GVP BOOT GET %08x %02x %08x\n"), addr, v, M68K_GETPC);
+#endif
+                       return v;
+               }
+               if (board->configured) {
+                       if (board == &gvp_ide_rom_board && currprefs.cpuboard_type == BOARD_A3001_II) {
+                               if (addr == 0x42) {
+                                       v = 0xff;
+                               }
+#if DEBUG_IDE_GVP
+                               write_log(_T("GVP BOOT GET %08x %02x %08x\n"), addr, v, M68K_GETPC);
 #endif
-                               ide_irq_check();
+                       } else {
+                               struct ide_hdf *ide;
+                               int regnum = get_gvp_reg(addr, board, &ide);
+#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);
+                               } else if (is_gvp2_intreq(addr)) {
+                                       v = board->irq ? 0x40 : 0x00;
+#if DEBUG_IDE_GVP
+                                       write_log(_T("GVP IRQ %02x\n"), v);
+#endif
+                                       ide_irq_check(board);
+                               } else if (is_gvp1_intreq(addr)) {
+                                       v = gvp_ide_controller_board.irq ? 0x80 : 0x00;
+#if DEBUG_IDE_GVP
+                                       write_log(_T("GVP IRQ %02x\n"), v);
+#endif
+                                       ide_irq_check(board);
+                               }
                        }
+               } else {
+                       v = 0xff;
                }
-       } else {
-               v = 0xff;
        }
        return v;
 }
@@ -204,42 +410,128 @@ static uae_u32 ide_read_word(struct ide_board *board, uaecptr addr)
 {
        uae_u32 v = 0xffff;
 
-       addr &= 65535;
-       if (board->configured && (board == &gvp_ide_controller_board || currprefs.cpuboard_type == BOARD_A3001_I)) {
-               if (addr < 0x60) {
-                       if (is_gvp1_intreq(addr))
-                               v = gvp_ide_controller_board.irq ? 0x8000 : 0x0000;
-                       else if (addr == 0x40) {
-                               if (currprefs.cpuboard_type == BOARD_A3001_II)
-                                       v = board->intena ? 8 : 0;
+#ifdef JIT
+       special_mem |= S_READ;
+#endif
+
+       addr &= board->mask;
+
+       if (board->type == APOLLO_IDE) {
+
+               if (addr >= APOLLO_ROM_OFFSET) {
+                       if (board->rom) {
+                               v = board->rom[(addr + 0 - APOLLO_ROM_OFFSET) & board->rom_mask];
+                               v <<= 8;
+                               v |= board->rom[(addr + 1 - APOLLO_ROM_OFFSET) & board->rom_mask];
                        }
-#if DEBUG_IDE
-                       write_log(_T("GVP IO WORD READ %08x %08x\n"), addr, M68K_GETPC);
+               }
+       }
+
+
+       if (board->configured) {
+
+               if (board->type == ALF_IDE) {
+
+                       struct ide_hdf *ide;
+                       int regnum = get_alf_reg(addr, board, &ide);
+                       if (regnum == IDE_DATA) {
+                               v = ide_get_data(ide);
+                       } else {
+                               v = 0;
+                               if (addr == 0x4000 && board->intena)
+                                       v = board->irq ? 0x8000 : 0x0000;
+#if DEBUG_IDE_ALF
+                               write_log(_T("ALF IO WORD READ %08x %08x\n"), addr, M68K_GETPC);
 #endif
+                       }
+
+       } 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_gvp_reg(addr, board, &ide);
+                       int regnum = get_masoboshi_reg(addr, board, &ide);
                        if (regnum == IDE_DATA) {
                                v = ide_get_data(ide);
-#if DEBUG_IDE > 2
-                               write_log(_T("IDE WORD READ %04x\n"), v);
-#endif
                        } else {
                                v = ide_read_byte(board, addr) << 8;
                                v |= ide_read_byte(board, addr + 1);
                        }
                }
+
+       } 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);
+                               if (regnum == IDE_DATA) {
+                                       v = ide_get_data(ide);
+                               } else {
+                                       v = 0;
+                               }
+                       }
+
+               } else if (board->type == GVP_IDE) {
+
+                       if (board == &gvp_ide_controller_board || currprefs.cpuboard_type == BOARD_A3001_I) {
+                               if (addr < 0x60) {
+                                       if (is_gvp1_intreq(addr))
+                                               v = gvp_ide_controller_board.irq ? 0x8000 : 0x0000;
+                                       else if (addr == 0x40) {
+                                               if (currprefs.cpuboard_type == BOARD_A3001_II)
+                                                       v = board->intena ? 8 : 0;
+                                       }
+#if DEBUG_IDE_GVP
+                                       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);
+                                       if (regnum == IDE_DATA) {
+                                               v = ide_get_data(ide);
+#if DEBUG_IDE_GVP > 2
+                                               write_log(_T("IDE WORD READ %04x\n"), v);
+#endif
+                                       } else {
+                                               v = ide_read_byte(board, addr) << 8;
+                                               v |= ide_read_byte(board, addr + 1);
+                                       }
+                               }       
+                       }
+               }
        }
+
+#if DEBUG_IDE
+       write_log(_T("IDE IO WORD READ %08x %04x %08x\n"), addr, v, M68K_GETPC);
+#endif
+
        return v;
 }
 
 static void ide_write_byte(struct ide_board *board, uaecptr addr, uae_u8 v)
 {
-       addr &= 65535;
+       addr &= board->mask;
+
+#ifdef JIT
+       special_mem |= S_WRITE;
+#endif
+
+#if DEBUG_IDE
+       write_log(_T("IDE IO BYTE WRITE %08x=%02x %08x\n"), addr, v, M68K_GETPC);
+#endif
+
        if (!board->configured) {
                addrbank *ab = board->bank;
                if (addr == 0x48) {
-                       map_banks_z2(ab, v, 0x10000 >> 16);
+                       map_banks_z2(ab, v, (board->mask + 1) >> 16);
                        board->configured = 1;
                        expamem_next(ab, NULL);
                        return;
@@ -251,96 +543,149 @@ static void ide_write_byte(struct ide_board *board, uaecptr addr, uae_u8 v)
                }
        }
        if (board->configured) {
-               if (board == &gvp_ide_rom_board && currprefs.cpuboard_type == BOARD_A3001_II) {
-#if DEBUG_IDE
-                       write_log(_T("GVP BOOT PUT %08x %02x %08x\n"), addr, v, M68K_GETPC);
-#endif
-               } else {
+               if (board->type == ALF_IDE) {
                        struct ide_hdf *ide;
-                       int regnum = get_gvp_reg(addr, board, &ide);
-#if DEBUG_IDE
-                       write_log(_T("GVP IDE PUT %08x %02x %d %08x\n"), addr, v, regnum, M68K_GETPC);
-#endif
+                       int regnum = get_alf_reg(addr, board, &ide);
                        if (regnum >= 0)
                                ide_write_reg(ide, 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) {
 
-static void ide_write_word(struct ide_board *board, uaecptr addr, uae_u16 v)
-{
-       addr &= 65535;
-       if (board->configured && (board == &gvp_ide_controller_board || currprefs.cpuboard_type == BOARD_A3001_I)) {
-               if (addr < 0x60) {
-#if DEBUG_IDE
-                       write_log(_T("GVP IO WORD WRITE %08x %04x %08x\n"), addr, v, M68K_GETPC);
+#if DEBUG_IDE_MASOBOSHI
+                       write_log(_T("MASOBOSHI IO BYTE PUT %08x %02x %08x\n"), addr, v, M68K_GETPC);
 #endif
-                       if (addr == 0x40 && currprefs.cpuboard_type == BOARD_A3001_II)
-                               board->intena = (v & 8) != 0;
-               } else {
                        struct ide_hdf *ide;
-                       int regnum = get_gvp_reg(addr, board, &ide);
-                       if (regnum == IDE_DATA) {
-                               ide_put_data(ide, v);
-#if DEBUG_IDE > 2
-                               write_log(_T("IDE WORD WRITE %04x\n"), v);
+                       int regnum = get_masoboshi_reg(addr, board, &ide);
+                       if (regnum >= 0) {
+                               ide_write_reg(ide, regnum, v);
+                       } else if (addr >= MASOBOSHI_SCSI_OFFSET && addr < MASOBOSHI_SCSI_OFFSET_END) {
+                               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(addr, v, board == &masoboshi_board[0] ? 0 : 1);
+                       } else if (addr >= 0xf040 && addr < 0xf048) {
+                               masoboshi_ncr9x_scsi_put(addr, v, board == &masoboshi_board[0] ? 0 : 1);
+                               if (addr == 0xf047) {
+                                       board->state = v;
+                                       board->intena = (v & 8) != 0;
+                               }
+                               if (addr == 0xf040) {
+                                       board->irq = false;
+                               }
+                               write_log(_T("MASOBOSHI STATUS BYTE PUT %08x %02x %08x\n"), addr, v, M68K_GETPC);
+                       }
+
+       } else if (board->type == APOLLO_IDE) {
+
+                       if ((addr & 0xc000) == 0x4000) {
+                               apollo_scsi_bput(addr, v);
+                       } else if (addr < 0x4000) {
+                               struct ide_hdf *ide;
+                               int regnum = get_apollo_reg(addr, board, &ide);
+                               if (regnum >= 0) {
+                                       ide_write_reg(ide, regnum, v);
+                               }
+                       }
+
+       } else if (board->type == GVP_IDE) {
+                       if (board == &gvp_ide_rom_board && currprefs.cpuboard_type == BOARD_A3001_II) {
+#if DEBUG_IDE_GVP
+                               write_log(_T("GVP BOOT PUT %08x %02x %08x\n"), addr, v, M68K_GETPC);
 #endif
                        } else {
-                               ide_write_byte(board, addr, v >> 8);
-                               ide_write_byte(board, addr + 1, v & 0xff);
+                               struct ide_hdf *ide;
+                               int regnum = get_gvp_reg(addr, board, &ide);
+#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);
                        }
                }
        }
 }
 
-static uae_u32 REGPARAM2 ide_controller_gvp_lget (uaecptr addr)
+static void ide_write_word(struct ide_board *board, uaecptr addr, uae_u16 v)
 {
-       uae_u32 v;
+       addr &= board->mask;
+
 #ifdef JIT
-       special_mem |= S_READ;
+       special_mem |= S_WRITE;
 #endif
-       v =  ide_read_word (&gvp_ide_controller_board, addr + 0) << 16;
-       v |= ide_read_word (&gvp_ide_controller_board, addr + 2) << 0;
-       return v;
-}
-static uae_u32 REGPARAM2 ide_controller_gvp_wget (uaecptr addr)
-{
-       uae_u32 v;
-#ifdef JIT
-       special_mem |= S_READ;
+
+#if DEBUG_IDE
+       write_log(_T("IDE IO WORD WRITE %08x=%04x %08x\n"), addr, v, M68K_GETPC);
 #endif
-       v =  ide_read_word (&gvp_ide_controller_board, addr);
-       return v;
-}
-static uae_u32 REGPARAM2 ide_controller_gvp_bget (uaecptr addr)
-{
-#ifdef JIT
-       special_mem |= S_READ;
+       if (board->configured) {
+               if (board->type == ALF_IDE) {
+
+                       struct ide_hdf *ide;
+                       int regnum = get_alf_reg(addr, board, &ide);
+                       if (regnum == IDE_DATA) {
+                               ide_put_data(ide, v);
+                       } else {
+#if DEBUG_IDE_ALF
+                               write_log(_T("ALF IO WORD WRITE %08x %04x %08x\n"), addr, v, M68K_GETPC);
 #endif
-       return ide_read_byte (&gvp_ide_controller_board, addr);
-}
-static void REGPARAM2 ide_controller_gvp_lput (uaecptr addr, uae_u32 l)
-{
-#ifdef JIT
-       special_mem |= S_WRITE;
+                       }
+
+               } else if (board->type == MASOBOSHI_IDE) {
+
+                       struct ide_hdf *ide;
+                       int regnum = get_masoboshi_reg(addr, board, &ide);
+                       if (regnum == IDE_DATA) {
+                               ide_put_data(ide, v);
+                       } else {
+                               ide_write_byte(board, addr, v >> 8);
+                               ide_write_byte(board, addr + 1, v);
+                       }
+#if DEBUG_IDE_MASOBOSHI
+                       write_log(_T("MASOBOSHI IO WORD WRITE %08x %04x %08x\n"), addr, v, M68K_GETPC);
 #endif
-       ide_write_word (&gvp_ide_controller_board, addr + 0, l >> 16);
-       ide_write_word (&gvp_ide_controller_board, addr + 2, l >> 0);
-}
-static void REGPARAM2 ide_controller_gvp_wput (uaecptr addr, uae_u32 w)
-{
-#ifdef JIT
-       special_mem |= S_WRITE;
+       
+               } else if (board->type == APOLLO_IDE) {
+
+                       if ((addr & 0xc000) == 0x4000) {
+                               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);
+                               if (regnum == IDE_DATA) {
+                                       ide_put_data(ide, v);
+                               }
+                       }
+
+               } else if (board->type == GVP_IDE) {
+
+                       if (board == &gvp_ide_controller_board || currprefs.cpuboard_type == BOARD_A3001_I) {
+                               if (addr < 0x60) {
+#if DEBUG_IDE_GVP
+                                       write_log(_T("GVP IO WORD WRITE %08x %04x %08x\n"), addr, v, M68K_GETPC);
 #endif
-       ide_write_word (&gvp_ide_controller_board, addr + 0, w);
-}
-static void REGPARAM2 ide_controller_gvp_bput (uaecptr addr, uae_u32 b)
-{
-#ifdef JIT
-       special_mem |= S_WRITE;
+                                       if (addr == 0x40 && currprefs.cpuboard_type == BOARD_A3001_II)
+                                               board->intena = (v & 8) != 0;
+                               } else {
+                                       struct ide_hdf *ide;
+                                       int regnum = get_gvp_reg(addr, board, &ide);
+                                       if (regnum == IDE_DATA) {
+                                               ide_put_data(ide, v);
+#if DEBUG_IDE_GVP > 2
+                                               write_log(_T("IDE WORD WRITE %04x\n"), v);
 #endif
-       ide_write_byte (&gvp_ide_controller_board, addr, b);
+                                       } else {
+                                               ide_write_byte(board, addr, v >> 8);
+                                               ide_write_byte(board, addr + 1, v & 0xff);
+                                       }
+                               }
+                       }
+               }
+       }
 }
+
+IDE_MEMORY_FUNCTIONS(ide_controller_gvp, ide, gvp_ide_controller_board);
+
 addrbank gvp_ide_controller_bank = {
        ide_controller_gvp_lget, ide_controller_gvp_wget, ide_controller_gvp_bget,
        ide_controller_gvp_lput, ide_controller_gvp_wput, ide_controller_gvp_bput,
@@ -348,54 +693,8 @@ addrbank gvp_ide_controller_bank = {
        dummy_lgeti, dummy_wgeti, ABFLAG_IO | ABFLAG_SAFE
 };
 
-static uae_u32 REGPARAM2 ide_rom_gvp_lget (uaecptr addr)
-{
-       uae_u32 v;
-#ifdef JIT
-       special_mem |= S_READ;
-#endif
-       v =  ide_read_word (&gvp_ide_rom_board, addr + 0) << 16;
-       v |= ide_read_word (&gvp_ide_rom_board, addr + 2) << 0;
-       return v;
-}
-static uae_u32 REGPARAM2 ide_rom_gvp_wget (uaecptr addr)
-{
-       uae_u32 v;
-#ifdef JIT
-       special_mem |= S_READ;
-#endif
-       v =  ide_read_word (&gvp_ide_rom_board, addr);
-       return v;
-}
-static uae_u32 REGPARAM2 ide_rom_gvp_bget (uaecptr addr)
-{
-#ifdef JIT
-       special_mem |= S_READ;
-#endif
-       return ide_read_byte (&gvp_ide_rom_board, addr);
-}
-static void REGPARAM2 ide_rom_gvp_lput (uaecptr addr, uae_u32 l)
-{
-#ifdef JIT
-       special_mem |= S_WRITE;
-#endif
-       ide_write_word (&gvp_ide_rom_board, addr + 0, l >> 16);
-       ide_write_word (&gvp_ide_rom_board, addr + 2, l >> 0);
-}
-static void REGPARAM2 ide_rom_gvp_wput (uaecptr addr, uae_u32 w)
-{
-#ifdef JIT
-       special_mem |= S_WRITE;
-#endif
-       ide_write_word (&gvp_ide_rom_board, addr + 0, w);
-}
-static void REGPARAM2 ide_rom_gvp_bput (uaecptr addr, uae_u32 b)
-{
-#ifdef JIT
-       special_mem |= S_WRITE;
-#endif
-       ide_write_byte (&gvp_ide_rom_board, addr, b);
-}
+IDE_MEMORY_FUNCTIONS(ide_rom_gvp, ide, gvp_ide_rom_board);
+
 addrbank gvp_ide_rom_bank = {
        ide_rom_gvp_lget, ide_rom_gvp_wget, ide_rom_gvp_bget,
        ide_rom_gvp_lput, ide_rom_gvp_wput, ide_rom_gvp_bput,
@@ -403,6 +702,40 @@ 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"),
+       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)
 {
        addr &= 0xffff;
@@ -429,7 +762,7 @@ addrbank *gvp_ide_rom_autoconfig_init(void)
        if (currprefs.cpuboard_type == BOARD_A3001_I) {
                ide->bank = &gvp_ide_rom_bank;
                autoconfig = gvp_ide1_controller_autoconfig;
-               init_ide(ide, &idecontroller_drive[GVP_IDE]);
+               init_ide(ide, GVP_IDE, true);
                ide->rom_size = 8192;
                gvp_ide_controller_board.intena = true;
                gvp_ide_controller_board.configured = -1;
@@ -441,6 +774,8 @@ addrbank *gvp_ide_rom_autoconfig_init(void)
                ide->rom_size = 16384;
                roms[0] = -1;
        }
+       ide->mask = 65536 - 1;
+       ide->type = GVP_IDE;
        ide->configured = 0;
        memset(ide->acmemory, 0xff, sizeof ide->acmemory);
 
@@ -474,7 +809,7 @@ addrbank *gvp_ide_controller_autoconfig_init(void)
 {
        struct ide_board *ide = &gvp_ide_controller_board;
 
-       init_ide(ide, &idecontroller_drive[GVP_IDE]);
+       init_ide(ide, GVP_IDE, true);
        ide->configured = 0;
        ide->bank = &gvp_ide_controller_bank;
        memset(ide->acmemory, 0xff, sizeof ide->acmemory);
@@ -485,3 +820,240 @@ addrbank *gvp_ide_controller_autoconfig_init(void)
        return ide->bank;
 }
 
+int gvp_add_ide_unit(int ch, struct uaedev_config_info *ci)
+{
+       struct ide_hdf *ide;
+
+       ide = add_ide_unit (&idecontroller_drive[GVP_IDE], 2, ch, ci);
+       if (ide == NULL)
+               return 0;
+       return 1;
+}
+
+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)
+{
+       struct ide_board *ide = &alf_board[devnum];
+       int roms[2];
+       struct romlist *rl;
+       bool alfplus = cfgfile_board_enabled(&currprefs.alfplusrom);
+
+       if (devnum > 0 && !ide->enabled)
+               return &expamem_null;
+
+       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->rom_size = 32768 * 6;
+       ide->userdata = alfplus;
+       ide->intena = alfplus;
+       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;
+       const TCHAR *romname = alfplus ? currprefs.alfplusrom.roms[0].romfile : currprefs.alfrom.roms[0].romfile;
+       struct zfile *z = read_rom_name(romname);
+       if (!z) {
+               rl = getromlistbyids(roms, romname);
+               if (rl) {
+                       z = read_rom(rl->rd);
+               }
+       }
+       for (int i = 0; i < 16; i++) {
+               uae_u8 b = alfplus ? alfplus_autoconfig[i] : alf_autoconfig[i];
+               ew(ide, i * 4, b);
+       }
+       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);
+                       ide->rom[ALF_ROM_OFFSET + i * 4 + 0] = b;
+                       zfile_fread(&b, 1, 1, z);
+                       ide->rom[ALF_ROM_OFFSET + i * 4 + 2] = b;
+               }
+               for (int i = 0; i < 32768 - 0x1000; i++) {
+                       uae_u8 b;
+                       zfile_fread(&b, 1, 1, z);
+                       ide->rom[0x2000 + i * 4 + 1] = b;
+                       zfile_fread(&b, 1, 1, z);
+                       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, int devnum)
+{
+       struct ide_hdf *ide;
+
+       ide = add_ide_unit (&idecontroller_drive[(ALF_IDE + devnum) * 2], 2, ch, ci);
+       if (ide == NULL)
+               return 0;
+       return 1;
+}
+
+// prod 0x22 = IDE + SCSI
+// prod 0x23 = SCSI only
+// prod 0x33 = IDE only
+
+const uae_u8 apollo_autoconfig[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[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)
+{
+       struct ide_board *ide;
+       int roms[2];
+       struct romlist *rl;
+       const uae_u8 *autoconfig;
+       bool cpuboard = false;
+
+       if (devnum < 0) {
+               cpuboard = true;
+               devnum = 0;
+       }
+
+       ide = &apollo_board[devnum];
+       if (devnum > 0 && !ide->enabled)
+               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->rom_size = 32768;
+       ide->mask = 131072 - 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;
+       autoconfig = apollo_autoconfig;
+       if (cpuboard) {
+               if (currprefs.cpu_model == 68060)
+                       autoconfig = apollo_autoconfig_cpuboard_060;
+               else
+                       autoconfig = apollo_autoconfig_cpuboard;
+       }
+       const TCHAR *romname = cpuboard ? currprefs.acceleratorromfile : currprefs.apollorom.roms[0].romfile;
+       struct zfile *z = read_rom_name(romname);
+       if (!z) {
+               rl = getromlistbyids(roms, romname);
+               if (rl) {
+                       z = read_rom(rl->rd);
+               }
+       }
+       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);
+               for (int i = 0; i < 32768; i++) {
+                       uae_u8 b;
+                       zfile_fread(&b, 1, 1, z);
+                       ide->rom[i] = b;
+               }
+               zfile_fclose(z);
+       } else {
+               romwarning(roms);
+       }
+       return ide->bank;
+}
+
+int apollo_add_ide_unit(int ch, struct uaedev_config_info *ci, int devnum)
+{
+       struct ide_hdf *ide;
+
+       ide = add_ide_unit (&idecontroller_drive[(APOLLO_IDE + devnum) * 2], 2, ch, ci);
+       if (ide == NULL)
+               return 0;
+       return 1;
+}
+
+static const uae_u8 masoboshi_fake_no_rom[] = { 0xcf, 0x1f, 0xff, 0xbf, 0xbf, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x9f, 0x2f };
+
+addrbank *masoboshi_init(int devnum)
+{
+       struct ide_board *ide;
+       int roms[2];
+       struct romlist *rl;
+
+       ide = &masoboshi_board[devnum];
+       if (devnum > 0 && !ide->enabled)
+               return &expamem_null;
+
+       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->rom_size = 65536;
+       ide->mask = 65536 - 1;
+
+       ide->rom = xcalloc(uae_u8, ide->rom_size);
+       memset(ide->rom, 0xff, ide->rom_size);
+       memset(ide->acmemory, 0xff, sizeof ide->acmemory);
+       ide->rom_mask = ide->rom_size - 1;
+       if (_tcscmp (currprefs.masoboshirom.roms[0].romfile, _T(":NOROM"))) {
+               const TCHAR *romname = currprefs.masoboshirom.roms[0].romfile;
+               struct zfile *z = read_rom_name(romname);
+               if (!z) {
+                       rl = getromlistbyids(roms, romname);
+                       if (rl) {
+                               z = read_rom(rl->rd);
+                       }
+               }
+               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);
+                       memcpy(ide->acmemory, ide->rom, sizeof ide->acmemory);
+               } else {
+                       romwarning(roms);
+               }
+       } else {
+               for (int i = 0; i < sizeof masoboshi_fake_no_rom; i++) {
+                       ide->acmemory[i * 2 + 0] =  masoboshi_fake_no_rom[i];
+               }
+       }
+       // init SCSI part
+       ncr_masoboshi_autoconfig_init(devnum);
+       return ide->bank;
+}
+
+int masoboshi_add_ide_unit(int ch, struct uaedev_config_info *ci, int devnum)
+{
+       struct ide_hdf *ide;
+
+       ide = add_ide_unit (&idecontroller_drive[(MASOBOSHI_IDE + devnum) * 2], 2, ch, ci);
+       if (ide == NULL)
+               return 0;
+       return 1;
+}
index 9f223fc91f834c52de5fb64a586dc434524a56a2..265ce153045524f1ecbdde98524b2cb84baf44e9 100644 (file)
@@ -24,7 +24,8 @@ struct wd_chip_state {
 
 #define COMMODORE_DMAC 1
 #define COMMODORE_SDMAC 2
-#define GVP_DMAC 3
+#define GVP_DMAC_S2 3
+#define GVP_DMAC_S1 4
 
 struct commodore_dmac
 {
@@ -55,6 +56,8 @@ struct gvp_dmac
        uae_u8 version;
        uae_u32 addr_mask;
        bool series2;
+       uae_u8 *buffer;
+       int bufoffset;
 };
 
 struct wd_state {
@@ -91,7 +94,7 @@ extern addrbank *a2091_init (int devnum);
 extern void a2091_free(void);
 extern void a2091_reset (void);
 
-extern addrbank *gvp_init(int devnum);
+extern addrbank *gvp_init(int devnum, bool series2);
 extern void gvp_free(void);
 extern void gvp_reset (void);
 
index 6b547271c855c7b7e278f1a8a8b4d3c0ecc56536..58596799dd307f8ea539925680cac4e606fb7b72 100644 (file)
@@ -46,4 +46,5 @@ extern uae_u8 *REGPARAM3 cyberstorm_scsi_ram_xlate(uaecptr addr) REGPARAM;
 #define BOARD_FUSIONFORTY 15
 #define BOARD_A3001_I 16
 #define BOARD_A3001_II 17
-
+#define BOARD_APOLLO 18
+#define BOARD_GVP_A530 19
index 7312dfd9abcd48578760ccb75660071756f8ad5a..c15dcbfb068a2b49781358e2ffa327ccbcbe0ece 100644 (file)
@@ -91,28 +91,38 @@ struct hd_hardfiledata {
 #define HD_CONTROLLER_TYPE_IDE_AUTO 1
 #define HD_CONTROLLER_TYPE_IDE_MB 2
 #define HD_CONTROLLER_TYPE_IDE_GVP 3
-#define HD_CONTROLLER_TYPE_SCSI_AUTO 4
-#define HD_CONTROLLER_TYPE_SCSI_A2091 5
-#define HD_CONTROLLER_TYPE_SCSI_A2091_2 6
-#define HD_CONTROLLER_TYPE_SCSI_GVP 7
-#define HD_CONTROLLER_TYPE_SCSI_GVP_2 8
-#define HD_CONTROLLER_TYPE_SCSI_A4091 9
-#define HD_CONTROLLER_TYPE_SCSI_A4091_2 10
-#define HD_CONTROLLER_TYPE_SCSI_FASTLANE 11
-#define HD_CONTROLLER_TYPE_SCSI_FASTLANE_2 12
-#define HD_CONTROLLER_TYPE_SCSI_OKTAGON 13
-#define HD_CONTROLLER_TYPE_SCSI_OKTAGON_2 14
-#define HD_CONTROLLER_TYPE_SCSI_A3000 15
-#define HD_CONTROLLER_TYPE_SCSI_A4000T 16
-#define HD_CONTROLLER_TYPE_SCSI_CDTV 17
-#define HD_CONTROLLER_TYPE_SCSI_CPUBOARD 18
-#define HD_CONTROLLER_TYPE_PCMCIA_SRAM 19
-#define HD_CONTROLLER_TYPE_PCMCIA_IDE 20
+#define HD_CONTROLLER_TYPE_IDE_ALFA 4
+#define HD_CONTROLLER_TYPE_IDE_ALFA_2 5
+#define HD_CONTROLLER_TYPE_IDE_APOLLO 6
+#define HD_CONTROLLER_TYPE_IDE_APOLLO_2 7
+#define HD_CONTROLLER_TYPE_IDE_MASOBOSHI 8
+#define HD_CONTROLLER_TYPE_IDE_MASOBOSHI_2 9
+#define HD_CONTROLLER_TYPE_SCSI_AUTO 10
+#define HD_CONTROLLER_TYPE_SCSI_A2091 11
+#define HD_CONTROLLER_TYPE_SCSI_A2091_2 12
+#define HD_CONTROLLER_TYPE_SCSI_GVP 13
+#define HD_CONTROLLER_TYPE_SCSI_GVP_2 14
+#define HD_CONTROLLER_TYPE_SCSI_A4091 15
+#define HD_CONTROLLER_TYPE_SCSI_A4091_2 16
+#define HD_CONTROLLER_TYPE_SCSI_FASTLANE 17
+#define HD_CONTROLLER_TYPE_SCSI_FASTLANE_2 18
+#define HD_CONTROLLER_TYPE_SCSI_OKTAGON 19
+#define HD_CONTROLLER_TYPE_SCSI_OKTAGON_2 20
+#define HD_CONTROLLER_TYPE_SCSI_APOLLO 21
+#define HD_CONTROLLER_TYPE_SCSI_APOLLO_2 22
+#define HD_CONTROLLER_TYPE_SCSI_MASOBOSHI 23
+#define HD_CONTROLLER_TYPE_SCSI_MASOBOSHI_2 24
+#define HD_CONTROLLER_TYPE_SCSI_A3000 25
+#define HD_CONTROLLER_TYPE_SCSI_A4000T 26
+#define HD_CONTROLLER_TYPE_SCSI_CDTV 27
+#define HD_CONTROLLER_TYPE_SCSI_CPUBOARD 28
+#define HD_CONTROLLER_TYPE_PCMCIA_SRAM 29
+#define HD_CONTROLLER_TYPE_PCMCIA_IDE 30
 
 #define HD_CONTROLLER_TYPE_IDE_FIRST 1
-#define HD_CONTROLLER_TYPE_IDE_LAST 3
-#define HD_CONTROLLER_TYPE_SCSI_FIRST 4
-#define HD_CONTROLLER_TYPE_SCSI_LAST 18
+#define HD_CONTROLLER_TYPE_IDE_LAST 9
+#define HD_CONTROLLER_TYPE_SCSI_FIRST 10
+#define HD_CONTROLLER_TYPE_SCSI_LAST 28
 
 #define FILESYS_VIRTUAL 0
 #define FILESYS_HARDFILE 1
index c944bee5b7ecf508664efae2c230551018460573..b7a67dca85dc8d0a446af61ab5396047e7acb259 100644 (file)
@@ -30,10 +30,15 @@ struct ide_board
        int rom_size;
        int rom_mask;
        int configured;
+       int mask;
        addrbank *bank;
        struct ide_hdf *ide;
        bool irq;
        bool intena;
+       bool enabled;
+       int state;
+       int type;
+       int userdata;
 };
 
 struct ide_hdf
@@ -87,7 +92,7 @@ void ide_write_reg (struct ide_hdf *ide, int ide_reg, uae_u32 val);
 void ide_put_data (struct ide_hdf *ide, uae_u16 v);
 uae_u16 ide_get_data (struct ide_hdf *ide);
 
-bool ide_interrupt_check(struct ide_hdf **ide, int num);
+bool ide_interrupt_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);
@@ -100,3 +105,31 @@ void stop_ide_thread(struct ide_thread_state *its);
 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); \
+} \
+static void REGPARAM2 x ## _wput(uaecptr addr, uae_u32 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); \
+} \
+static uae_u32 REGPARAM2 x ## _bget(uaecptr addr) \
+{ \
+return y ## _read_byte(& ## z, addr); \
+} \
+static uae_u32 REGPARAM2 x ## _wget(uaecptr 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); \
+       return v; \
+}
index f46e93cba7cc1e4e30e6289385cf2e1bf50039f0..a2eade4e3f74539249456e099306067faa5855fc 100644 (file)
@@ -9,3 +9,21 @@ void idecontroller_hsync(void);
 int gvp_add_ide_unit(int ch, struct uaedev_config_info *ci);
 addrbank *gvp_ide_rom_autoconfig_init(void);
 addrbank *gvp_ide_controller_autoconfig_init(void);
+
+int alf_add_ide_unit(int ch, struct uaedev_config_info *ci, int devnum);
+addrbank *alf_init(int);
+
+int apollo_add_ide_unit(int ch, struct uaedev_config_info *ci, int devnum);
+addrbank *apollo_init(int);
+
+int masoboshi_add_ide_unit(int ch, struct uaedev_config_info *ci, int devnum);
+addrbank *masoboshi_init(int);
+
+uae_u32 REGPARAM3 apollo_ide_lget (uaecptr addr) REGPARAM;
+uae_u32 REGPARAM3 apollo_ide_wget (uaecptr addr) REGPARAM;
+uae_u32 REGPARAM3 apollo_ide_bget (uaecptr addr) REGPARAM;
+void REGPARAM3 apollo_ide_lput (uaecptr addr, uae_u32 l) REGPARAM;
+void REGPARAM3 apollo_ide_wput (uaecptr addr, uae_u32 w) REGPARAM;
+void REGPARAM3 apollo_ide_bput (uaecptr addr, uae_u32 b) REGPARAM;
+extern const uae_u8 apollo_autoconfig[16];
+extern const uae_u8 apollo_autoconfig_060[16];
index 58ea600f228af507401cc09a9114491cc4aa0ef6..c2c2826493d6741f256bd27d101409ec72718c3d 100644 (file)
@@ -9,6 +9,7 @@ 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, int devnum);
 extern int oktagon_add_scsi_unit(int ch, struct uaedev_config_info *ci, int devnum);
+extern int masoboshi_add_scsi_unit(int ch, struct uaedev_config_info *ci, int devnum);
 
 extern addrbank *ncr_fastlane_autoconfig_init(int devnum);
 extern addrbank *ncr_oktagon_autoconfig_init(int devnum);
@@ -17,6 +18,10 @@ extern addrbank *ncr_dkb_autoconfig_init(void);
 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);
+
 #define BLIZZARD_2060_SCSI_OFFSET 0x1ff00
 #define BLIZZARD_2060_DMA_OFFSET 0x1fff0
 #define BLIZZARD_2060_LED_OFFSET 0x1ffe0
index d87e19fe29f9b2e515c340f7c56b68b48979de4f..35c999e66d1d953f76caef98bb2d2b0c2155fd93 100644 (file)
@@ -484,7 +484,12 @@ struct uae_prefs {
        struct boardromconfig a4091rom;
        struct boardromconfig fastlanerom;
        struct boardromconfig oktagonrom;
-       struct boardromconfig gvprom;
+       struct boardromconfig gvps1rom;
+       struct boardromconfig gvps2rom;
+       struct boardromconfig alfrom;
+       struct boardromconfig alfplusrom;
+       struct boardromconfig apollorom;
+       struct boardromconfig masoboshirom;
 
        TCHAR romfile[MAX_DPATH];
        TCHAR romident[256];
index 31aaa9afb564c62a9fe79c6e6c55ba88be51d602..ff3239e6429b59b831fe094aaf1f8a7de1000bad 100644 (file)
@@ -30,8 +30,13 @@ extern int decode_cloanto_rom_do (uae_u8 *mem, int size, int real_size);
 #define ROMTYPE_CPUBOARDEXT    0x00100003
 #define ROMTYPE_FASTLANE       0x00100004
 #define ROMTYPE_OKTAGON                0x00100005
-#define ROMTYPE_GVP                    0x00100006
-#define ROMTYPE_AMAX           0x00100007
+#define ROMTYPE_GVPS1          0x00100006
+#define ROMTYPE_GVPS2          0x00100007
+#define ROMTYPE_AMAX           0x00100008
+#define ROMTYPE_ALFA           0x00100009
+#define ROMTYPE_ALFAPLUS       0x0010000a
+#define ROMTYPE_APOLLO         0x0010000b
+#define ROMTYPE_MASOBOSHI      0x0010000c
 
 #define ROMTYPE_QUAD           0x01000000
 #define ROMTYPE_EVEN           0x02000000
index bb96a165052290321e006fcd2c7ed8db5af2fe7f..bb9c83822223bc1055fa741c90952b634c267ab3 100644 (file)
@@ -71,6 +71,14 @@ 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_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);
+void free_scsi (struct scsi_data *sd);
+
+void scsi_freenative(struct scsi_data **sd);
+void scsi_addnative(struct scsi_data **sd);
+
 #define SCSI_NO_SENSE_DATA             0x00
 #define SCSI_NOT_READY                 0x04
 #define SCSI_NOT_LOADED                        0x09
@@ -137,3 +145,10 @@ static uae_u32 REGPARAM2 x ## _lget(uaecptr addr) \
 { \
 return y ## _lget(& ## z, addr); \
 }
+
+
+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, int devnum);
+void apolloscsi_free(void);
+void apolloscsi_reset(void);
index 72d5bd30b4fd22ecbe3624545d01898c1beb409e..a70b03594ae2f8af2affb92959da77aa8b2bad40 100644 (file)
 #define OKTAGON_EEPROM_SDA 0x8018
 #define OKTAGON_EEPROM_SIZE 512
 
+#define MASOBOSHI_ESP_ADDR 0xfa00
+#define MASOBOSHI_DMA_START 0xf900
+#define MASOBOSHI_DMA_END 0xfa00
+
 #define DKB_BOARD_SIZE 131072
 #define DKB_ROM_SIZE 32768
 #define DKB_ROM_OFFSET 0x8000
@@ -92,6 +96,8 @@ struct ncr9x_state
        uaecptr dma_ptr;
        int dma_cnt;
        int state;
+       int state2;
+       int state3;
 
        uae_u8 data;
        bool data_valid;
@@ -100,11 +106,11 @@ struct ncr9x_state
        bool romisoddonly;
        bool romisevenonly;
 
-       uae_u8 *dkb_data_buf;
-       int dkb_data_size_allocated;
-       int dkb_data_size;
-       int dkb_data_offset;
-       uae_u8 *dkb_data_write_buffer;
+       uae_u8 *fakedma_data_buf;
+       int fakedma_data_size_allocated;
+       int fakedma_data_size;
+       int fakedma_data_offset;
+       uae_u8 *fakedma_data_write_buffer;
 };
 
 
@@ -144,9 +150,9 @@ 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,
@@ -154,6 +160,8 @@ static struct ncr9x_state *ncrs[] =
        &ncr_fastlane_scsi[1],
        &ncr_oktagon2008_scsi[0],
        &ncr_oktagon2008_scsi[1],
+       &ncr_masoboshi_scsi[0],
+       &ncr_masoboshi_scsi[1],
        &ncr_dkb1200_scsi,
        NULL
 };
@@ -161,8 +169,10 @@ static struct ncr9x_state *ncrs[] =
 void ncr9x_rethink(void)
 {
        for (int i = 0; ncrs[i]; i++) {
-               if (ncrs[i]->boardirq)
+               if (ncrs[i]->boardirq) {
                        INTREQ_0(0x8000 | 0x0008);
+                       return;
+               }
        }
 }
 
@@ -211,6 +221,18 @@ static void set_irq2_fastlane(struct ncr9x_state *ncr)
        }
 }
 
+static void set_irq2_masoboshi(struct ncr9x_state *ncr)
+{
+       if (ncr->chipirq && !ncr->boardirq) {
+               ncr->state2 |= 2;
+               ncr->boardirq = true;
+#if NCR_DEBUG > 1
+               write_log(_T("MASOBOSHI IRQ\n"));
+#endif
+               ncr9x_rethink();
+       }
+}
+
 void esp_irq_raise(qemu_irq irq)
 {
        struct ncr9x_state *ncr = (struct ncr9x_state*)irq;
@@ -225,40 +247,40 @@ void esp_irq_lower(qemu_irq irq)
        ncr->irq_func(ncr);
 }
 
-static void dkb_buffer_size(struct ncr9x_state *ncr, int size)
+static void fakedma_buffer_size(struct ncr9x_state *ncr, int size)
 {
        size = (size + 1) & ~1;
-       if (ncr->dkb_data_size_allocated >= size)
+       if (ncr->fakedma_data_size_allocated >= size)
                return;
-       if (ncr->dkb_data_buf)
-               xfree(ncr->dkb_data_buf);
-       ncr->dkb_data_buf = xmalloc(uae_u8, size);
-       ncr->dkb_data_size_allocated = size;
+       if (ncr->fakedma_data_buf)
+               xfree(ncr->fakedma_data_buf);
+       ncr->fakedma_data_buf = xmalloc(uae_u8, size);
+       ncr->fakedma_data_size_allocated = size;
 }
 
 /* Fake DMA */
-static int dkb_dma_read(void *opaque, uint8_t *buf, int len)
+static int fake_dma_read(void *opaque, uint8_t *buf, int len)
 {
        struct ncr9x_state *ncr = (struct ncr9x_state*)opaque;
-       ncr->dkb_data_offset = 0;
-       ncr->dkb_data_write_buffer = buf;
-       dkb_buffer_size(ncr, len);
+       ncr->fakedma_data_offset = 0;
+       ncr->fakedma_data_write_buffer = buf;
+       fakedma_buffer_size(ncr, len);
        return 0;
 }
-static int dkb_dma_write(void *opaque, uint8_t *buf, int len)
+static int fake_dma_write(void *opaque, uint8_t *buf, int len)
 {
        struct ncr9x_state *ncr = (struct ncr9x_state*)opaque;
-       ncr->dkb_data_offset = 0;
-       dkb_buffer_size(ncr, len);
-       memcpy(ncr->dkb_data_buf, buf, len);
+       ncr->fakedma_data_offset = 0;
+       fakedma_buffer_size(ncr, len);
+       memcpy(ncr->fakedma_data_buf, buf, len);
        if (len & 1)
-               ncr->dkb_data_buf[len] = 0;
-       ncr->dkb_data_size = len;
+               ncr->fakedma_data_buf[len] = 0;
+       ncr->fakedma_data_size = len;
        return 0;
 }
 
 /* Fake DMA */
-static int oktagon_dma_read(void *opaque, uint8_t *buf, int len)
+static int fake2_dma_read(void *opaque, uint8_t *buf, int len)
 {
        struct ncr9x_state *ncr = (struct ncr9x_state*)opaque;
        esp_dma_enable(ncr->devobject.lsistate, 0);
@@ -268,7 +290,7 @@ static int oktagon_dma_read(void *opaque, uint8_t *buf, int len)
        }
        return 1;
 }
-static int oktagon_dma_write(void *opaque, uint8_t *buf, int len)
+static int fake2_dma_write(void *opaque, uint8_t *buf, int len)
 {
        struct ncr9x_state *ncr = (struct ncr9x_state*)opaque;
        esp_dma_enable(ncr->devobject.lsistate, 0);
@@ -501,7 +523,63 @@ 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_oktagon2008_scsi[0] || ncr == &ncr_oktagon2008_scsi[1]) {
+       if (ncr == &ncr_masoboshi_scsi[0] || ncr == &ncr_masoboshi_scsi[1]) {
+
+               if (addr >= 0xf04c && addr < 0xf04f) {
+                       int shift = (addr - 0xf04c) * 8;
+                       uae_u32 mask = 0xff << shift;
+                       ncr->dma_ptr &= ~mask;
+                       ncr->dma_ptr |= val << shift;
+                       ncr->dma_ptr &= 0xffffff;
+                       return;
+               }
+               if (addr >= 0xf040 && addr <= 0xf047) {
+                       if (addr == 0xf047) {
+                               if (val & 0x80)
+                                       ncr->state3 = 0x80;
+                       }
+                       if (addr == 0xf040) {
+                               ncr->state3 = 0;
+                       }
+                       return;
+               }
+
+               if (addr == 0xf007) {
+                       ncr->state = val;
+               }
+               if (addr == 0xf000) {
+                       ncr->state2 &= ~2;
+               }
+               if (addr == 0xf004) {
+                       ncr->state2 &= ~1;
+               }
+               if (addr >= MASOBOSHI_DMA_START && addr < MASOBOSHI_DMA_END) {
+                       if (esp_reg_read(ncr->devobject.lsistate, ESP_RSTAT) & STAT_TC) {
+#if NCR_DEBUG > 2
+                               write_log(_T("MASOBOSHI DMA OVERFLOW %08X PUT %02x %08x\n"), addr, val & 0xff, M68K_GETPC);
+#endif
+                       } else {
+                               ncr->data = val;
+                               ncr->data_valid = true;
+                               esp_dma_enable(ncr->devobject.lsistate, 1);
+#if NCR_DEBUG > 2
+                               write_log(_T("MASOBOSHI DMA %08X PUT %02x %08x\n"), addr, val & 0xff, M68K_GETPC);
+#endif
+                       }
+                       return;
+               }
+               if (addr < MASOBOSHI_ESP_ADDR || addr >= MASOBOSHI_ESP_ADDR + 0x100) {
+#if NCR_DEBUG
+                       write_log(_T("MASOBOSHI IO %08X PUT %02x %08x\n"), addr, val & 0xff, M68K_GETPC);
+#endif
+                       return;
+               }
+               if (addr == MASOBOSHI_ESP_ADDR + 3 * 2 && val == 0x02)
+                       ncr->state |= 0x80;
+               reg_shift = 1;
+               addr &= 0x3f;
+
+       } else if (ncr == &ncr_oktagon2008_scsi[0] || ncr == &ncr_oktagon2008_scsi[1]) {
                if (addr == OKTAGON_EEPROM_SCL) {
                        eeprom_i2c_set(ncr->eeprom, BITBANG_I2C_SCL, (val & 0x80) != 0);
                } else if (addr == OKTAGON_EEPROM_SDA) {
@@ -615,10 +693,10 @@ static void ncr9x_io_bput(struct ncr9x_state *ncr, uaecptr addr, uae_u32 val)
                }
                if (addr >= 0x10080 && addr < 0x10088) {
                        //write_log(_T("DKB PUT BYTE %02x\n"), val & 0xff);
-                       if (ncr->dkb_data_offset < ncr->dkb_data_size) {
-                               ncr->dkb_data_buf[ncr->dkb_data_offset++] = val;
-                               if (ncr->dkb_data_offset == ncr->dkb_data_size) {
-                                       memcpy(ncr->dkb_data_write_buffer, ncr->dkb_data_buf, ncr->dkb_data_size);
+                       if (ncr->fakedma_data_offset < ncr->fakedma_data_size) {
+                               ncr->fakedma_data_buf[ncr->fakedma_data_offset++] = val;
+                               if (ncr->fakedma_data_offset == ncr->fakedma_data_size) {
+                                       memcpy(ncr->fakedma_data_write_buffer, ncr->fakedma_data_buf, ncr->fakedma_data_size);
                                        esp_fake_dma_done(ncr->devobject.lsistate);
                                }
                        }
@@ -638,12 +716,54 @@ static void ncr9x_io_bput(struct ncr9x_state *ncr, uaecptr addr, uae_u32 val)
 }
 
 
+static int perse = 0;
+
 uae_u32 ncr9x_io_bget(struct ncr9x_state *ncr, uaecptr addr)
 {
        uae_u8 v;
        int reg_shift = 2;
        addr &= ncr->board_mask;
-       if (ncr == &ncr_oktagon2008_scsi[0] || ncr == &ncr_oktagon2008_scsi[1]) {
+       if (ncr == &ncr_masoboshi_scsi[0] || ncr == &ncr_masoboshi_scsi[1]) {
+
+               if (addr == MASOBOSHI_ESP_ADDR + 3 * 2 && (ncr->state & 0x80))
+                       return 2;
+               if (ncr->state & 0x80)
+                       ncr->state &= ~0x80;
+
+               if (addr == 0xf040) {
+                       return ncr->state3;
+               }
+
+               if (addr == 0xf000) {
+                       if (esp_reg_read(ncr->devobject.lsistate, ESP_RSTAT) & STAT_TC) {
+                               if (perse)
+                                       activate_debugger();
+                               ncr->state2 |= 1; // dma complete
+                       }
+                       return ncr->state2 & 0x7f;
+               }
+               if (addr == 0xf007) {
+                       v = ncr->state;
+               }
+               if (addr >= MASOBOSHI_DMA_START && addr < MASOBOSHI_DMA_END) {
+                       esp_dma_enable(ncr->devobject.lsistate, 1);
+                       v = ncr->data;
+                       ncr->data_valid = false;
+#if NCR_DEBUG > 2
+                       write_log(_T("MASOBOSHI DMA %08X GET %02x %08x\n"), addr, v, M68K_GETPC);
+#endif
+                       return v;
+               }
+               if (addr < MASOBOSHI_ESP_ADDR || addr >= MASOBOSHI_ESP_ADDR + 0x100) {
+#if NCR_DEBUG
+                       write_log(_T("MASOBOSHI IO %08X GET %02x %08x\n"), addr, v, M68K_GETPC);
+#endif
+                       return v;
+               }
+               reg_shift = 1;
+               addr &= 0x3f;
+
+       } else if (ncr == &ncr_oktagon2008_scsi[0] || ncr == &ncr_oktagon2008_scsi[1]) {
                if (addr == OKTAGON_EEPROM_SCL) {
                        return eeprom_i2c_set(ncr->eeprom, BITBANG_I2C_SCL, -1) ? 0x80 : 0x00;
                } else if (addr == OKTAGON_EEPROM_SDA) {
@@ -697,20 +817,20 @@ uae_u32 ncr9x_io_bget(struct ncr9x_state *ncr, uaecptr addr)
                        uae_u8 v = 0;
                        if (ncr->chipirq)
                                v |= 0x40;
-                       if (ncr->dkb_data_offset < ncr->dkb_data_size)
+                       if (ncr->fakedma_data_offset < ncr->fakedma_data_size)
                                v |= 0x80;
                        //write_log(_T("DKB IO GET %02x %08x\n"), v, M68K_GETPC);
                        return v;
                }
                if (addr >= 0x10080 && addr < 0x10088) {
-                       //write_log(_T("DKB GET BYTE %02x\n"), ncr->dkb_data_buf[ncr->dkb_data_offset]);
-                       if (ncr->dkb_data_offset >= ncr->dkb_data_size)
+                       //write_log(_T("DKB GET BYTE %02x\n"), ncr->fakedma_data_buf[ncr->fakedma_data_offset]);
+                       if (ncr->fakedma_data_offset >= ncr->fakedma_data_size)
                                return 0;
-                       if (ncr->dkb_data_offset == ncr->dkb_data_size - 1) {
+                       if (ncr->fakedma_data_offset == ncr->fakedma_data_size - 1) {
                                esp_fake_dma_done(ncr->devobject.lsistate);
                                //write_log(_T("DKB fake dma finished\n"));
                        }
-                       return ncr->dkb_data_buf[ncr->dkb_data_offset++];
+                       return ncr->fakedma_data_buf[ncr->fakedma_data_offset++];
                }
                if (addr < 0x10000 || addr >= 0x10040) {
                        write_log(_T("DKB IO GET %08x %08x\n"), addr, M68K_GETPC);
@@ -913,6 +1033,15 @@ void cpuboard_ncr9x_scsi_put(uaecptr addr, uae_u32 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);
+}
+void masoboshi_ncr9x_scsi_put(uaecptr addr, uae_u32 v, int devnum)
+{
+       ncr9x_io_bput(&ncr_masoboshi_scsi[devnum], addr, v);
+}
+
 static void ew(struct ncr9x_state *ncr, int addr, uae_u8 value)
 {
        if (addr == 00 || addr == 02 || addr == 0x40 || addr == 0x42) {
@@ -1000,8 +1129,11 @@ static void ncr9x_reset_board(struct ncr9x_state *ncr)
                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;
        }
-       ncr->name = ncr->bank->name;
+       if (ncr->bank)
+               ncr->name = ncr->bank->name;
 }
 
 void ncr9x_reset(void)
@@ -1220,6 +1352,20 @@ addrbank *ncr_dkb_autoconfig_init(void)
 }
 
 
+void ncr_masoboshi_autoconfig_init(int devnum)
+{
+       struct ncr9x_state *ncr = &ncr_masoboshi_scsi[devnum];
+
+       if (!ncr->enabled && devnum > 0)
+               return;
+
+       ncr->enabled = true;
+
+       ncr9x_init ();
+       ncr9x_reset_board(ncr);
+}
+
+
 static void freescsi_hdf(struct scsi_data *sd)
 {
        if (!sd)
@@ -1260,9 +1406,11 @@ void ncr9x_init(void)
                        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, oktagon_dma_read, oktagon_dma_write);
-               esp_scsi_init(&ncr_oktagon2008_scsi[1].devobject, oktagon_dma_read, oktagon_dma_write);
-               esp_scsi_init(&ncr_dkb1200_scsi.devobject, dkb_dma_read, dkb_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);
        }
 }
 
@@ -1350,4 +1498,10 @@ int oktagon_add_scsi_unit (int ch, struct uaedev_config_info *ci, int devnum)
        return ncr9x_add_scsi_unit(&ncr_oktagon2008_scsi[devnum], ch, ci);
 }
 
+int masoboshi_add_scsi_unit (int ch, struct uaedev_config_info *ci, int devnum)
+{
+       return ncr9x_add_scsi_unit(&ncr_masoboshi_scsi[devnum], ch, ci);
+}
+
+
 #endif
index 4b9eb8b3368fbd5432de87be9afe55d14eddc2e6..1e8420a146426843360691cc417c3a185b325230 100644 (file)
@@ -331,7 +331,7 @@ void esp_transfer_data(SCSIRequest *req, uint32_t len)
        s->async_buf = scsiesp_req_get_buf(req);
     if (s->dma_left) {
         esp_do_dma(s);
-    } else if (s->dma_counter != 0 && s->ti_size <= 0) {
+    } else if (s->dma_counter != 0 && s->ti_size == 0) {
         /* If this was the last part of a DMA transfer then the
            completion interrupt is deferred to here.  */
         esp_dma_done(s);
@@ -450,6 +450,8 @@ uint64_t esp_reg_read(void *opaque, uint32_t saddr)
         esp_lower_irq(s);
 
         return old_val;
+       case ESP_RFLAGS:
+               return s->rregs[saddr] | s->rregs[ESP_RSEQ] << 5;
        case ESP_RES4:
                return 0x80 | 0x20 | 0x2;
     default:
@@ -520,6 +522,8 @@ void esp_reg_write(void *opaque, uint32_t saddr, uint64_t val)
             s->rregs[ESP_RINTR] = INTR_DC;
             s->rregs[ESP_RSEQ] = 0;
             s->rregs[ESP_RFLAGS] = 0;
+                       // Masoboshi driver expects phase=0!
+                       s->rregs[ESP_RSTAT] &= ~7;
             esp_raise_irq(s);
             break;
         case CMD_PAD:
@@ -544,7 +548,8 @@ void esp_reg_write(void *opaque, uint32_t saddr, uint64_t val)
             s->rregs[ESP_RINTR] = 0;
             break;
         case CMD_DISSEL:
-            s->rregs[ESP_RINTR] = 0;
+                       // Masoboshi driver expects Function Complete.
+            s->rregs[ESP_RINTR] = INTR_FC;
             esp_raise_irq(s);
             break;
         default:
index d3795e4f16cb2dbce79071fa5870fc2bf49e30eb..e2b3fcaa49a381881792fc11175895094304905f 100644 (file)
@@ -94,7 +94,7 @@ struct romdata *getromdatabypath (const TCHAR *path)
        return NULL;
 }
 
-#define NEXT_ROM_ID 117
+#define NEXT_ROM_ID 121
 
 static struct romheader romheaders[] = {
        { _T("Freezer Cartridges"), 1 },
@@ -284,7 +284,6 @@ static struct romdata roms[] = {
        ALTROM(116, 1, 1, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, 0x1909f7e9, 0x5abe9b9d,0xaae328c8,0x134e2b62,0x7b33b698,0xe342afc2)
        ALTROM(116, 1, 2, 32768, ROMTYPE_ODD  | ROMTYPE_8BIT, 0xa3927c72, 0x7adc9352,0x2d112ae9,0x23b9a70d,0x951b1e7a,0xba800ea6)
 
-
        { _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") },
 
@@ -343,17 +342,23 @@ static struct romdata roms[] = {
        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_CPUBOARD, 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_CPUBOARD, 0, 0, NULL,
+       0xaaff7c65, 0x424cf3da,0xcc9da794,0x0ba74446,0x69dd1691,0x44ae87ee, NULL, NULL },
 
-       { _T("GVP Series I ROM"), 3, 15, 3, 15, _T("GVP\0"), 16384, 111, 0, 0, ROMTYPE_GVP, 0, 0, NULL,
+       { _T("GVP Series II v3.15 ROM"), 3, 15, 3, 15, _T("GVPII\0"), 16384, 111, 0, 0, ROMTYPE_GVPS2, 0, 0, NULL,
        0xf99c6f11, 0x77098a9e,0x35acaef2,0x11a546f0,0xc564cdac,0xf52836c4, NULL, NULL },
-       { _T("GVP Series II ROM"), 4, 15, 4, 15, _T("GVPII\0"), 16384, 109, 0, 0, ROMTYPE_GVP, 0, 0, NULL,
+       { _T("GVP Series II v4.15 ROM"), 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_GVP, 0, 0, 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("GVP A3001 Series I ROM"), 3, 3, 3, 3, _T("A3001SI\0"), 8192, 114, 0, 0, ROMTYPE_CPUBOARD, 0, 0, NULL,
-       0xaaff7c65, 0x424cf3da,0xcc9da794,0x0ba74446,0x69dd1691,0x44ae87ee, NULL, NULL },
-
+       { _T("AlfaPower v6.10 ROM"), 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,
+       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,
+       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_CPUBOARD, 0, 0, NULL,
          0, 0, 0, 0, 0, 0, NULL, _T("cyberstormmk1_040.rom") },
@@ -1128,6 +1133,8 @@ void romwarning (const int *ids)
        TCHAR tmp1[MAX_DPATH], tmp2[MAX_DPATH];
        TCHAR tmp3[MAX_DPATH];
 
+       if (ids[0] == -1)
+               return;
        exp = 0;
        tmp2[0] = 0;
        i = 0;
index 09699517e727f6b8c4805a4d1a4c3aeb13cd24d3..1fbb0c8f55a01ea96afacba0132a5ee14b291c7a 100644 (file)
--- a/scsi.cpp
+++ b/scsi.cpp
 #include "filesys.h"
 #include "blkdev.h"
 #include "zfile.h"
+#include "debug.h"
 
 #define SCSI_EMU_DEBUG 0
+#define RAW_SCSI_DEBUG 0
 
 extern int log_scsiemu;
 
@@ -371,7 +373,115 @@ int scsi_receive_data(struct scsi_data *sd, uae_u8 *b)
        return 0;
 }
 
+void free_scsi (struct scsi_data *sd)
+{
+       if (!sd)
+               return;
+       hdf_hd_close (sd->hfd);
+       scsi_free (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;
+       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;
+       sd[ch] = scsi_alloc_hd (ch, hfd);
+       return sd[ch] ? 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;
+}
+
+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;
+}
+
+void scsi_freenative(struct scsi_data **sd)
+{
+       for (int i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) {
+               free_scsi (sd[i]);
+               sd[i] = NULL;
+       }
+}
+
+void scsi_addnative(struct scsi_data **sd)
+{
+       int i, j;
+       int devices[MAX_TOTAL_SCSI_DEVICES];
+       int types[MAX_TOTAL_SCSI_DEVICES];
+       struct device_info dis[MAX_TOTAL_SCSI_DEVICES];
+
+       scsi_freenative (sd);
+       i = 0;
+       while (i < MAX_TOTAL_SCSI_DEVICES) {
+               types[i] = -1;
+               devices[i] = -1;
+               if (sys_command_open (i)) {
+                       if (sys_command_info (i, &dis[i], 0)) {
+                               devices[i] = i;
+                               types[i] = 100 - i;
+                               if (dis[i].type == INQ_ROMD)
+                                       types[i] = 1000 - i;
+                       }
+                       sys_command_close (i);
+               }
+               i++;
+       }
+       i = 0;
+       while (devices[i] >= 0) {
+               j = i + 1;
+               while (devices[j] >= 0) {
+                       if (types[i] > types[j]) {
+                               int tmp = types[i];
+                               types[i] = types[j];
+                               types[j] = tmp;
+                       }
+                       j++;
+               }
+               i++;
+       }
+       i = 0; j = 0;
+       while (devices[i] >= 0 && j < 7) {
+               if (sd[j] == NULL) {
+                       sd[j] = scsi_alloc_native(j, devices[i]);
+                       write_log (_T("SCSI: %d:'%s'\n"), j, dis[i].label);
+                       i++;
+               }
+               j++;
+       }
+}
+
+
 // raw scsi
+
+#define SCSI_IO_BUSY 0x80
+#define SCSI_IO_ATN 0x40
+#define SCSI_IO_SEL 0x20
+#define SCSI_IO_REQ 0x10
+#define SCSI_IO_DIRECTION 0x01
+#define SCSI_IO_COMMAND 0x02
+#define SCSI_IO_MESSAGE 0x04
+
+#define SCSI_SIGNAL_PHASE_FREE -1
+#define SCSI_SIGNAL_PHASE_ARBIT -2
+#define SCSI_SIGNAL_PHASE_SELECT_1 -3
+#define SCSI_SIGNAL_PHASE_SELECT_2 -4
+
 #define SCSI_SIGNAL_PHASE_DATA_OUT 0
 #define SCSI_SIGNAL_PHASE_DATA_IN 1
 #define SCSI_SIGNAL_PHASE_COMMAND 2
@@ -379,90 +489,298 @@ int scsi_receive_data(struct scsi_data *sd, uae_u8 *b)
 #define SCSI_SIGNAL_PHASE_MESSAGE_OUT 6
 #define SCSI_SIGNAL_PHASE_MESSAGE_IN 7
 
-#define SCSI_BUS_PHASE_FREE 0
-#define SCSI_BUS_PHASE_ARBITRATION 1
-#define SCSI_BUS_PHASE_SELECTION 2
-#define SCSI_BUS_PHASE_RESELECTION 3
-#define SCSI_BUS_PHASE_COMMAND 4
-#define SCSI_BUS_PHASE_DATA_IN 5
-#define SCSI_BUS_PHASE_DATA_OUT 6
-#define SCSI_BUS_PHASE_STATUS 7
-#define SCSI_BUS_PHASE_MESSAGE_IN 8
-#define SCSI_BUS_PHASE_MESSAGE_OUT 9
-
-struct raw_scsi_device
-{
-       int x;
-       int id;
-};
 struct raw_scsi
 {
-       int signal_phase;
-       int old_signal_phase;
+       int io;
        int bus_phase;
+       bool atn;
        uae_u8 data;
-       int initiator;
-       int target;
-       uae_u8 cmd[16];
-       int len;
-       struct raw_scsi_device *device[8];
+       int initiator_id, target_id;
+       struct scsi_data *device[8];
+       struct scsi_data *target;
 };
 
-struct raw_scsi *new_raw_scsi(void)
+void raw_scsi_reset(struct raw_scsi *rs)
 {
-       struct raw_scsi *rs = xcalloc(struct raw_scsi, 1);
-       return rs;
+       rs->target = NULL;
+       rs->io = 0;
+       rs->bus_phase = SCSI_SIGNAL_PHASE_FREE;
 }
 
-void free_raw_scsi(struct raw_scsi *rs)
+void raw_scsi_busfree(struct raw_scsi *rs)
 {
-       if (!rs)
-               return;
-       for (int i = 0; i < 8; i++)
-               xfree(rs->device[i]);
-       xfree(rs);
+       rs->target = NULL;
+       rs->io = 0;
+       rs->bus_phase = SCSI_SIGNAL_PHASE_FREE;
 }
 
-struct raw_scsi_device *new_raw_scsi_device(struct raw_scsi *rs, int id)
+static void bus_free(struct raw_scsi *rs)
 {
-       rs->device[id] = xcalloc(struct raw_scsi_device, 1);
-       rs->device[id]->id = id;
-       return rs->device[id];
+       rs->bus_phase = SCSI_SIGNAL_PHASE_FREE;
+       rs->io = 0;
 }
 
-void free_raw_scsi_device(struct raw_scsi *rs, struct raw_scsi_device *dev)
+static int getbit(uae_u8 v)
 {
-       if (!dev)
-               return;
-       rs->device[dev->id] = NULL;
-       xfree(dev);
+       for (int i = 0; i < 8; i++) {
+               if ((1 << i) & v)
+                       return i;
+       }
+       return -1;
 }
 
-int raw_scsi_get_signal_phase(struct raw_scsi *rs, struct raw_scsi_device *dev)
+void raw_scsi_set_signal_phase(struct raw_scsi *rs, bool busy, bool select, bool atn)
 {
-       return rs->signal_phase;
+       switch (rs->bus_phase)
+       {
+               case SCSI_SIGNAL_PHASE_FREE:
+               if (busy && !select) {
+                       rs->bus_phase = SCSI_SIGNAL_PHASE_ARBIT;
+               }
+               break;
+               case SCSI_SIGNAL_PHASE_ARBIT:
+               rs->target_id = -1;
+               rs->target = NULL;
+               if (busy && select) {
+                       rs->bus_phase = SCSI_SIGNAL_PHASE_SELECT_1;
+               }
+               break;
+               case SCSI_SIGNAL_PHASE_SELECT_1:
+               rs->atn = atn;
+               if (!busy) {
+                       uae_u8 data = rs->data & ~(1 << rs->initiator_id);
+                       rs->target_id = getbit(data);
+                       if (rs->target_id >= 0) {
+                               rs->target = rs->device[rs->target_id];
+                               if (rs->target) {
+#if RAW_SCSI_DEBUG
+                                       write_log(_T("raw_scsi: selected id %d\n"), rs->target_id);
+#endif
+                                       rs->io |= SCSI_IO_BUSY;
+                               } else {
+#if RAW_SCSI_DEBUG
+                                       write_log(_T("raw_scsi: selected non-existing id %d\n"), rs->target_id);
+#endif
+                                       rs->target_id = -1;
+                               }
+                       }
+                       if (rs->target_id >= 0) {
+                               rs->bus_phase = SCSI_SIGNAL_PHASE_SELECT_2;
+                       } else {
+                               if (!select) {
+                                       rs->bus_phase = SCSI_SIGNAL_PHASE_FREE;
+                               }
+                       }
+               }
+               break;
+               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->io = SCSI_IO_BUSY | SCSI_IO_REQ;
+               }
+               break;
+       }
 }
 
-void raw_scsi_put_signal_phase(struct raw_scsi *rs, struct raw_scsi_device *dev, uae_u8 phase)
+uae_u8 raw_scsi_get_signal_phase(struct raw_scsi *rs)
 {
-       if (rs->signal_phase == phase)
-               return;
-       rs->old_signal_phase = rs->signal_phase;
-       rs->signal_phase = phase;
-       switch(rs->bus_phase)
+       uae_u8 v = rs->io;
+       if (rs->bus_phase >= 0)
+               v |= rs->bus_phase;
+       return v;
+}
+
+uae_u8 raw_scsi_get_data(struct raw_scsi *rs)
+{
+       struct scsi_data *sd = rs->target;
+       uae_u8 v = 0;
+
+       switch (rs->bus_phase)
        {
-       case SCSI_BUS_PHASE_FREE:
+               case SCSI_SIGNAL_PHASE_FREE:
+#if RAW_SCSI_DEBUG
+               write_log(_T("raw_scsi: bus free\n"));
+#endif
+               v = 0;
+               break;
+               case SCSI_SIGNAL_PHASE_ARBIT:
+#if RAW_SCSI_DEBUG
+               write_log(_T("raw_scsi: arbitration\n"));
+#endif
+               v = rs->data;
+               break;
+               case SCSI_SIGNAL_PHASE_DATA_IN:
+               if (scsi_receive_data(sd, & v)) {
+                       rs->bus_phase = SCSI_SIGNAL_PHASE_STATUS;
+#if RAW_SCSI_DEBUG
+                       write_log(_T("raw_scsi: data in finished, %d bytes: status phase\n"), sd->offset);
+#endif
+               }
+               break;
+               case SCSI_SIGNAL_PHASE_STATUS:
+#if RAW_SCSI_DEBUG
+               write_log(_T("raw_scsi: status byte read %02x\n"), sd->status);
+#endif
+               v = sd->status;
+               bus_free(rs);
+               break;
+               default:
+               write_log(_T("raw_scsi_get_data but bus phase is %d!\n"), rs->bus_phase);
+               break;
+       }
+
+       return v;
+}
+
+void raw_scsi_put_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_ARBIT:
+               rs->initiator_id = getbit(data);
+               write_log(_T("raw_scsi: arbitration initiator id %d\n"), rs->initiator_id);
                break;
-       
+               case SCSI_SIGNAL_PHASE_SELECT_1:
+               break;
+               case SCSI_SIGNAL_PHASE_COMMAND:
+               sd->cmd[sd->offset++] = data;
+               len = scsicmdsizes[sd->cmd[0] >> 5];
+               if (sd->offset >= len) {
+#if RAW_SCSI_DEBUG
+                       write_log(_T("raw_scsi: got command %02x (%d bytes)\n"), sd->cmd[0], len);
+#endif
+                       scsi_emulate_analyze(rs->target);
+                       if (sd->direction > 0) {
+#if RAW_SCSI_DEBUG
+                               write_log(_T("raw_scsi: data out %d bytes required\n"), sd->data_len);
+#endif
+                               scsi_start_transfer(sd);
+                               rs->bus_phase = SCSI_SIGNAL_PHASE_DATA_OUT;
+                       } else if (sd->direction <= 0) {
+                               scsi_emulate_cmd(sd);
+                               scsi_start_transfer(sd);
+                               if (!sd->status && sd->data_len > 0) {
+#if RAW_SCSI_DEBUG
+                                       write_log(_T("raw_scsi: data in %d bytes waiting\n"), sd->data_len);
+#endif
+                                       rs->bus_phase = SCSI_SIGNAL_PHASE_DATA_IN;
+                               } else {
+#if RAW_SCSI_DEBUG
+                                       write_log(_T("raw_scsi: no data, status = %d\n"), sd->status);
+#endif
+                                       rs->bus_phase = SCSI_SIGNAL_PHASE_STATUS;
+                               }
+                       }
+               }
+               break;
+               case SCSI_SIGNAL_PHASE_DATA_OUT:
+               if (scsi_send_data(sd, data)) {
+#if RAW_SCSI_DEBUG
+                       write_log(_T("raw_scsi: data out finished, %d bytes\n"), sd->data_len);
+#endif
+                       scsi_emulate_cmd(sd);
+                       rs->bus_phase = SCSI_SIGNAL_PHASE_STATUS;
+               }
+               break;
+               default:
+               write_log(_T("raw_scsi_put_data but bus phase is %d!\n"), rs->bus_phase);
+               break;
+       }
+}
+
+struct apollo_soft_scsi
+{
+       bool enabled;
+       int configured;
+       bool autoconfig;
+       bool irq;
+       struct raw_scsi rscsi;
+};
+static struct apollo_soft_scsi apolloscsi[2];
+
+void apollo_scsi_bput(uaecptr addr, uae_u8 v)
+{
+       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);
+       } else if (bank == 0xc00 && !(addr & 1)) {
+               as->irq = (v & 64) != 0;
+               raw_scsi_set_signal_phase(rs,
+                       (v & 128) != 0,
+                       (v & 32) != 0,
+                       false);
+       } else if (bank == 0x400 && (addr & 1)) {
+               raw_scsi_set_signal_phase(rs, true, false, false);
+               raw_scsi_put_data(rs, v);
+       }
+       //write_log(_T("apollo scsi put %04x = %02x\n"), addr, v);
+}
+
+uae_u8 apollo_scsi_bget(uaecptr addr)
+{
+       int bank = addr & (0x800 | 0x400);
+       struct apollo_soft_scsi *as = &apolloscsi[0];
+       struct raw_scsi *rs = &as->rscsi;
+       uae_u8 v = 0xff;
+       addr &= 0x3fff;
+       if (bank == 0) {
+               v = raw_scsi_get_data(rs);
+       } else if (bank == 0x800 && (addr & 1)) {
+               uae_u8 t = raw_scsi_get_signal_phase(rs);
+               v = 1; // disable switch off
+               if (t & SCSI_IO_BUSY)
+                       v |= 128;
+               if (t & SCSI_IO_SEL)
+                       v |= 32;
+               if (t & SCSI_IO_REQ)
+                       v |= 2;
+               if (t & SCSI_IO_DIRECTION)
+                       v |= 8;
+               if (t & SCSI_IO_COMMAND)
+                       v |= 16;
+               if (t & SCSI_IO_MESSAGE)
+                       v |= 4;
+               v ^= (1 | 2 | 4 | 8 | 16 | 32 | 128);
+               //v |= apolloscsi.irq ? 64 : 0;
        }
+       //write_log(_T("apollo scsi get %04x = %02x\n"), addr, v);
+       return v;
 }
 
-uae_u16 raw_scsi_get_data(struct raw_scsi *rs, struct raw_scsi_device *dev)
+int apollo_add_scsi_unit(int ch, struct uaedev_config_info *ci, int devnum)
 {
-       return rs->data;
+       struct raw_scsi *rs = &apolloscsi[devnum].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 raw_scsi_put_data(struct raw_scsi *rs, struct raw_scsi_device *dev, uae_u16 data)
+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 apolloscsi_reset(void)
+{
+       raw_scsi_reset(&apolloscsi[0].rscsi);
+       raw_scsi_reset(&apolloscsi[1].rscsi);
+}
\ No newline at end of file