]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
imported winuaesrc1430b2.zip
authorToni Wilen <twilen@winuae.net>
Sun, 20 May 2007 10:10:03 +0000 (13:10 +0300)
committerToni Wilen <twilen@winuae.net>
Mon, 22 Feb 2010 19:33:58 +0000 (21:33 +0200)
28 files changed:
a2091.c
ar.c
autoconf.c
cdtv.c
cfgfile.c
custom.c
filesys.c
gayle.c
hardfile.c
include/a2091.h
include/cdtv.h
include/filesys.h
include/memory.h
include/native2amiga.h
include/scsi.h [new file with mode: 0755]
memory.c
ncr_scsi.c
newcpu.c
od-win32/mman.c
od-win32/resources/resource
od-win32/resources/resource.h
od-win32/resources/winuae.rc
od-win32/win32.h
od-win32/win32gui.c
od-win32/winuae_msvc/winuae_msvc.vcproj
od-win32/winuaechangelog.txt
scsi.c [new file with mode: 0755]
scsiemul.c

diff --git a/a2091.c b/a2091.c
index d44eba7f54ce5b91ccb6de882c8b8f0e4ed68313..7084ed3afbe8c34697606fe6fd6133bba9403ad2 100755 (executable)
--- a/a2091.c
+++ b/a2091.c
@@ -9,9 +9,7 @@
 
 #define A2091_DEBUG 0
 #define A3000_DEBUG 0
-#define WD33C93_DEBUG 1
-
-#define HAVE_DRIVE_ID -1
+#define WD33C93_DEBUG 0
 
 #include "sysconfig.h"
 #include "sysdeps.h"
 #include "custom.h"
 #include "newcpu.h"
 #include "debug.h"
+#include "scsi.h"
 #include "a2091.h"
 #include "blkdev.h"
 #include "gui.h"
 #include "zfile.h"
-#include "threaddep/thread.h"
+#include "filesys.h"
+#include "autoconf.h"
+#include "cdtv.h"
 
 #define ROM_VECTOR 0x2000
 #define ROM_OFFSET 0x2000
 #define ISTR_FE_FLG             (1<<0)  
 
 /* wd register names */
-#define WD_OWN_ID    0x00
-#define WD_CONTROL      0x01
-#define WD_TIMEOUT_PERIOD  0x02
-#define WD_CDB_1     0x03
-#define WD_CDB_2     0x04
-#define WD_CDB_3     0x05
-#define WD_CDB_4     0x06
-#define WD_CDB_5     0x07
-#define WD_CDB_6     0x08
-#define WD_CDB_7     0x09
-#define WD_CDB_8     0x0a
-#define WD_CDB_9     0x0b
-#define WD_CDB_10    0x0c
-#define WD_CDB_11    0x0d
-#define WD_CDB_12    0x0e
-#define WD_TARGET_LUN      0x0f
-#define WD_COMMAND_PHASE   0x10
+#define WD_OWN_ID              0x00
+#define WD_CONTROL             0x01
+#define WD_TIMEOUT_PERIOD      0x02
+#define WD_CDB_1               0x03
+#define WD_CDB_2               0x04
+#define WD_CDB_3               0x05
+#define WD_CDB_4               0x06
+#define WD_CDB_5               0x07
+#define WD_CDB_6               0x08
+#define WD_CDB_7               0x09
+#define WD_CDB_8               0x0a
+#define WD_CDB_9               0x0b
+#define WD_CDB_10              0x0c
+#define WD_CDB_11              0x0d
+#define WD_CDB_12              0x0e
+#define WD_TARGET_LUN          0x0f
+#define WD_COMMAND_PHASE       0x10
 #define WD_SYNCHRONOUS_TRANSFER 0x11
-#define WD_TRANSFER_COUNT_MSB 0x12
-#define WD_TRANSFER_COUNT  0x13
-#define WD_TRANSFER_COUNT_LSB 0x14
-#define WD_DESTINATION_ID  0x15
-#define WD_SOURCE_ID    0x16
-#define WD_SCSI_STATUS     0x17
-#define WD_COMMAND      0x18
-#define WD_DATA      0x19
-#define WD_QUEUE_TAG    0x1a
-#define WD_AUXILIARY_STATUS   0x1f 
+#define WD_TRANSFER_COUNT_MSB  0x12
+#define WD_TRANSFER_COUNT      0x13
+#define WD_TRANSFER_COUNT_LSB  0x14
+#define WD_DESTINATION_ID      0x15
+#define WD_SOURCE_ID           0x16
+#define WD_SCSI_STATUS         0x17
+#define WD_COMMAND             0x18
+#define WD_DATA                        0x19
+#define WD_QUEUE_TAG           0x1a
+#define WD_AUXILIARY_STATUS    0x1f 
 /* WD commands */
-#define WD_CMD_RESET    0x00
-#define WD_CMD_ABORT    0x01
-#define WD_CMD_ASSERT_ATN  0x02
-#define WD_CMD_NEGATE_ACK  0x03
-#define WD_CMD_DISCONNECT  0x04
-#define WD_CMD_RESELECT    0x05
-#define WD_CMD_SEL_ATN     0x06
-#define WD_CMD_SEL      0x07
-#define WD_CMD_SEL_ATN_XFER   0x08
-#define WD_CMD_SEL_XFER    0x09
-#define WD_CMD_RESEL_RECEIVE  0x0a
-#define WD_CMD_RESEL_SEND  0x0b
-#define WD_CMD_WAIT_SEL_RECEIVE 0x0c
-#define WD_CMD_TRANS_ADDR  0x18
-#define WD_CMD_TRANS_INFO  0x20
-#define WD_CMD_TRANSFER_PAD   0x21          
-#define WD_CMD_SBT_MODE    0x80
-
-#define CSR_MSGIN    0x20      
-#define CSR_SDP         0x21
-#define CSR_SEL_ABORT      0x22
-#define CSR_RESEL_ABORT    0x25
-#define CSR_RESEL_ABORT_AM 0x27   
-#define CSR_ABORT    0x28
+#define WD_CMD_RESET           0x00
+#define WD_CMD_ABORT           0x01
+#define WD_CMD_ASSERT_ATN      0x02
+#define WD_CMD_NEGATE_ACK      0x03
+#define WD_CMD_DISCONNECT      0x04
+#define WD_CMD_RESELECT                0x05
+#define WD_CMD_SEL_ATN         0x06
+#define WD_CMD_SEL             0x07
+#define WD_CMD_SEL_ATN_XFER    0x08
+#define WD_CMD_SEL_XFER                0x09
+#define WD_CMD_RESEL_RECEIVE   0x0a
+#define WD_CMD_RESEL_SEND      0x0b
+#define WD_CMD_WAIT_SEL_RECEIVE        0x0c
+#define WD_CMD_TRANS_ADDR      0x18
+#define WD_CMD_TRANS_INFO      0x20
+#define WD_CMD_TRANSFER_PAD    0x21          
+#define WD_CMD_SBT_MODE                0x80
+
+#define CSR_MSGIN          0x20      
+#define CSR_SDP                    0x21
+#define CSR_SEL_ABORT      0x22
+#define CSR_RESEL_ABORT            0x25
+#define CSR_RESEL_ABORT_AM  0x27   
+#define CSR_ABORT          0x28
+/* successful completion interrupts */
+#define CSR_RESELECT       0x10
+#define CSR_SELECT         0x11
+#define CSR_SEL_XFER_DONE   0x16
+#define CSR_XFER_DONE      0x18
+  /* terminated interrupts */
+#define CSR_INVALID        0x40
+#define CSR_UNEXP_DISC     0x41
+#define CSR_TIMEOUT        0x42   
+#define CSR_PARITY         0x43   
+#define CSR_PARITY_ATN     0x44
+#define CSR_BAD_STATUS     0x45
+#define CSR_UNEXP          0x48   
+  /* service required interrupts */
+#define CSR_RESEL          0x80         
+#define CSR_RESEL_AM       0x81   
+#define CSR_DISC           0x85           
+#define CSR_SRV_REQ        0x88 
+/* SCSI Bus Phases */          
+#define PHS_DATA_OUT       0x00
+#define PHS_DATA_IN        0x01
+#define PHS_COMMAND        0x02
+#define PHS_STATUS         0x03
+#define PHS_MESS_OUT       0x06
+#define PHS_MESS_IN        0x07
+
 
 static int configured;
 static uae_u8 dmacmemory[100];
@@ -123,37 +150,80 @@ static uae_u32 dmac_wtc;
 static int dmac_dma;
 static uae_u8 sasr, scmd, auxstatus;
 static int wd_used;
+static int wd_phase, wd_next_phase, wd_busy;
+static int wd_dataoffset, wd_tc;
+static uae_u8 wd_data[32];
 
 static int superdmac;
+static int scsiirqdelay;
 
-static uae_u8 wdregs[32];
+struct scsi_data *scsis[8];
 
-#define WD33C93 "WD33C93"
+uae_u8 wdregs[32];
+
+static int isirq(void)
+{
+    if (superdmac) {
+       if ((dmac_cntr & SCNTR_INTEN) && (dmac_istr & ISTR_INTS))
+           return 1;
+    } else {
+        if ((dmac_cntr & CNTR_INTEN) && (dmac_istr & ISTR_INTS))
+           return 1;
+    }
+    return 0;
+}
 
 void rethink_a2091(void)
 {
-    if (dmac_istr & ISTR_INTS)
-       INTREQ_0 (0x8000 | 0x0008);
+    if (isirq()) {
+       uae_int_requested |= 2;
+#if A2091_DEBUG > 2 || A3000_DEBUG > 2
+       write_log("Interrupt_RETHINK\n");
+#endif
+    } else {
+       uae_int_requested &= ~2;
+    }
 }
 
-static void INT2(void)
+static void INT2(int quick)
 {
     int irq = 0;
 
     if (!(auxstatus & 0x80))
        return;
     dmac_istr |= ISTR_INTS;
-    if (superdmac) {
-       if ((dmac_cntr & SCNTR_INTEN) && (dmac_istr & ISTR_INTS))
-           irq = 1;
-    } else {
-        if ((dmac_cntr & CNTR_INTEN) && (dmac_istr & ISTR_INTS))
-           irq = 1;
+    if (isirq()) {
+        if (quick)
+           uae_int_requested |= 2;
+       else
+           scsiirqdelay = 2;
     }
-    if (irq) {
-       if (!(intreq & 8))
-           INTREQ_f(0x8000 | 0x0008);
+}
+
+void scsi_hsync(void)
+{
+    if (scsiirqdelay == 1) {
+       scsiirqdelay = 0;
+       uae_int_requested |= 2;
+#if A2091_DEBUG > 2 || A3000_DEBUG > 2
+       write_log("Interrupt\n");
+#endif
+       return;
     }
+    if (scsiirqdelay > 1)
+       scsiirqdelay--;
+}
+
+static void dmac_start_dma(void)
+{
+#if A3000_DEBUG > 0 || A2091_DEBUG > 0
+    write_log("DMAC DMA started, ADDR=%08X, LEN=%08X words\n", dmac_acr, dmac_wtc);
+#endif
+    dmac_dma = 1;
+}
+static void dmac_stop_dma(void)
+{
+    dmac_dma = 0;
 }
 
 static void dmac_reset(void)
@@ -177,32 +247,183 @@ static void incsasr(void)
 static void dmac_cint(void)
 {
     dmac_istr = 0;
+    rethink_a2091();
 }
 
-static void set_status(uae_u8 status)
+static void set_status(uae_u8 status, int quick)
 {
     wdregs[WD_SCSI_STATUS] = status;
     auxstatus |= 0x80;
-    INT2();
+    if (!currprefs.cs_a2091 && currprefs.cs_mbdmac != 1)
+       return;
+    INT2(quick);
+}
+
+static char *scsitostring(void)
+{
+    static char buf[200];
+    char *p;
+    int i;
+
+    p = buf;
+    p[0] = 0;
+    for (i = 0; i < wd_tc && i < sizeof wd_data; i++) {
+       if (i > 0) {
+           strcat(p, ".");
+           p++;
+       }
+       sprintf(p, "%02X", wd_data[i]);
+       p += strlen(p);
+    }
+    return buf;
+}
+
+static void wd_cmd_sel_xfer(void)
+{
+    int phase = wdregs[WD_COMMAND_PHASE];
+#if WD33C93_DEBUG > 0
+    write_log("* %s select and transfer, phase=%02X\n", WD33C93, phase);
+#endif
+    if (phase >= 0x46) {
+       phase = 0x50;
+       wdregs[WD_TARGET_LUN] = SCSIID->status;
+    }
+    wdregs[WD_COMMAND_PHASE] = phase;
+    wd_phase = CSR_XFER_DONE | PHS_MESS_IN;
+    SCSIID->buffer[0] = 0;
+    set_status(wd_phase, 1);
+}
+
+static void do_dma(void)
+{
+    if (currprefs.cs_cdtvscsi)
+       cdtv_getdmadata(&dmac_acr);
+    if (SCSIID->direction == 0) {
+       write_log("%s DMA but no data!?\n");
+    } else if (SCSIID->direction < 0) {
+       for (;;) {
+           uae_u8 v;
+           int status = scsi_receive_data(SCSIID, &v);
+           put_byte(dmac_acr, v);
+           if (wd_dataoffset < sizeof wd_data)
+               wd_data[wd_dataoffset++] = v; 
+           dmac_acr++;
+           if (status)
+               break;
+       }
+    } else if (SCSIID->direction > 0) {
+       for (;;) {
+           int status;
+           uae_u8 v = get_byte(dmac_acr);
+           if (wd_dataoffset < sizeof wd_data)
+               wd_data[wd_dataoffset++] = v;
+           status = scsi_send_data(SCSIID, v);
+           dmac_acr++;
+           if (status)
+               break;
+       }
+    }
+}
+
+static void wd_do_transfer_out(void)
+{
+#if WD33C93_DEBUG > 0
+    write_log("%s SCSI O %d/%d %s\n", WD33C93, wd_dataoffset, wd_tc, scsitostring());
+#endif
+    if (wdregs[WD_COMMAND_PHASE] == 0x11) {
+       wdregs[WD_COMMAND_PHASE] = 0x20;
+       wd_phase = CSR_XFER_DONE | PHS_COMMAND;
+    } else if (wdregs[WD_COMMAND_PHASE] == 0x30) {
+       /* command was sent */
+       SCSIID->direction = scsi_data_dir(SCSIID);
+       if (SCSIID->direction > 0) {
+           /* if write command, need to wait for data */
+           wd_phase = CSR_XFER_DONE | PHS_DATA_OUT;
+           wdregs[WD_COMMAND_PHASE] = 0x46;
+       } else {
+           scsi_emulate_cmd(SCSIID);
+           if (SCSIID->data_len <= 0 || SCSIID->status != 0 || SCSIID->direction == 0) {
+               wd_phase = CSR_XFER_DONE | PHS_STATUS;
+               wdregs[WD_COMMAND_PHASE] = 0x47;
+           } else {
+               wd_phase = CSR_XFER_DONE | PHS_DATA_IN;
+               wdregs[WD_COMMAND_PHASE] = 0x3f;
+           }
+       }
+    } else if (wdregs[WD_COMMAND_PHASE] == 0x46) {
+       if (SCSIID->direction > 0) {
+           /* data was sent */
+           scsi_emulate_cmd(SCSIID);
+           wd_phase = CSR_XFER_DONE | PHS_STATUS;
+       }
+        wdregs[WD_COMMAND_PHASE] = 0x47;
+    }
+    wd_dataoffset = 0;
+    set_status(wd_phase, SCSIID->direction ? 0 : 1);
+    wd_busy = 0;
+}
+
+static void wd_do_transfer_in(void)
+{
+#if WD33C93_DEBUG > 0
+    write_log("%s SCSI I %d/%d %s\n", WD33C93, wd_dataoffset, wd_tc, scsitostring());
+#endif
+    wd_dataoffset = 0;
+    if (wdregs[WD_COMMAND_PHASE] == 0x3f) {
+       wdregs[WD_COMMAND_PHASE] = 0x47;
+       wd_phase = CSR_XFER_DONE | PHS_STATUS;
+    } else if (wdregs[WD_COMMAND_PHASE] == 0x47) {
+       wdregs[WD_COMMAND_PHASE] = 0x50;
+       wd_phase = CSR_XFER_DONE | PHS_MESS_IN;
+    } else if (wdregs[WD_COMMAND_PHASE] == 0x50) {
+       wdregs[WD_COMMAND_PHASE] = 0x60;
+       wd_phase = CSR_DISC;
+    }
+    set_status(wd_phase, 1);
+    wd_busy = 0;
+    SCSIID->direction = 0;
 }
 
 static void wd_cmd_trans_info(void)
 {
+    if (wdregs[WD_COMMAND_PHASE] == 0x47)
+       SCSIID->buffer[0] = SCSIID->status;
+    if (wdregs[WD_COMMAND_PHASE] == 0x20)
+       wdregs[WD_COMMAND_PHASE] = 0x30;
+    wd_busy = 1;
+    wd_tc = wdregs[WD_TRANSFER_COUNT_LSB] | (wdregs[WD_TRANSFER_COUNT] << 8) | (wdregs[WD_TRANSFER_COUNT_MSB] << 16);
+    if (wdregs[WD_COMMAND] & 0x80)
+       wd_tc = 1;
+    wd_dataoffset = 0;
 #if WD33C93_DEBUG > 0
-    write_log("%s TRANS_INFO\n", WD33C93);
+    write_log("* %s transfer info phase=%02x len=%d dma=%d\n", WD33C93, wdregs[WD_COMMAND_PHASE], wd_tc, wdregs[WD_CONTROL] >> 6);
 #endif
+    scsi_start_transfer(SCSIID, wd_tc);
+    if ((wdregs[WD_CONTROL] >> 6) == 2) {
+        do_dma();
+       if (SCSIID->direction < 0)
+           wd_do_transfer_in();
+       else if (SCSIID->direction > 0)
+           wd_do_transfer_out();
+       SCSIID->direction = 0;
+       dmac_dma = 0;
+    }
 }
 
-static void wd_cmd_sel(void)
+static void wd_cmd_sel_atn(void)
 {
 #if WD33C93_DEBUG > 0
-    write_log("%s select, ID=%d\n", WD33C93, wdregs[WD_DESTINATION_ID]);
+    write_log("* %s select with atn, ID=%d\n", WD33C93, wdregs[WD_DESTINATION_ID]);
 #endif
-    if (wdregs[WD_DESTINATION_ID] == HAVE_DRIVE_ID) {
-       set_status(0x10 | 8 | 2);
+    wd_phase = 0;
+    wdregs[WD_COMMAND_PHASE] = 0;
+    if (SCSIID) {
+       wd_phase = CSR_SELECT;
+       set_status(wd_phase, 1);
+       wdregs[WD_COMMAND_PHASE] = 0x10;
        return;
     }
-    set_status(0x42);
+    set_status(CSR_TIMEOUT, 0);
 }
 
 static void wd_cmd_abort(void)
@@ -210,25 +431,34 @@ static void wd_cmd_abort(void)
 #if WD33C93_DEBUG > 0
     write_log("%s abort\n", WD33C93);
 #endif
-    set_status(0x22);
+    set_status(CSR_SEL_ABORT, 0);
 }
 
 void wdscsi_put(uae_u8 d)
 {
 #if WD33C93_DEBUG > 1
-    write_log("%s REG %02.2X (%d) = %02.2X (%d)\n", WD33C93, sasr, sasr, d, d);
+    if (sasr != WD_DATA)
+       write_log("W %s REG %02.2X (%d) = %02.2X (%d)\n", WD33C93, sasr, sasr, d, d);
 #endif
     wdregs[sasr] = d;
     if (!wd_used) {
        wd_used = 1;
        write_log("%s in use\n", WD33C93);
     }
-    if (sasr == WD_COMMAND) {
-       switch (d)
+    if (sasr == WD_DATA) {
+       if (wd_dataoffset < sizeof wd_data)
+           wd_data[wd_dataoffset] = wdregs[sasr];
+       wd_dataoffset++;
+       if (scsi_send_data(SCSIID, wdregs[sasr]))
+           wd_do_transfer_out();
+    } else if (sasr == WD_COMMAND) {
+       switch (d & 0x7f)
        {
            case WD_CMD_SEL_ATN:
-           case WD_CMD_SEL:
-               wd_cmd_sel();
+               wd_cmd_sel_atn();
+           break;
+           case WD_CMD_SEL_XFER:
+               wd_cmd_sel_xfer();
            break;
            case WD_CMD_TRANS_INFO:
                wd_cmd_trans_info();
@@ -247,19 +477,37 @@ void wdscsi_sasr(uae_u8 b)
 }
 uae_u8 wdscsi_getauxstatus(void)
 {
-    return auxstatus;
+    return (auxstatus & 0x80) | (wd_busy ? 0x20 : 0) | (wd_busy ? 0x01 : 0);
 }
 
 uae_u8 wdscsi_get(void)
 {
-    uae_u8 v;
+    uae_u8 v, osasr = sasr;
     
     v = wdregs[sasr];
-    if (sasr == WD_SCSI_STATUS) {
+    if (sasr == WD_DATA) {
+       int status = scsi_receive_data(SCSIID, &v);
+       if (wd_dataoffset < sizeof wd_data)
+           wd_data[wd_dataoffset] = v;
+       wd_dataoffset++;
+       wdregs[sasr] = v;
+       if (status)
+           wd_do_transfer_in();
+    } else if (sasr == WD_SCSI_STATUS) {
+       uae_int_requested &= ~2;
        auxstatus &= ~0x80;
        dmac_istr &= ~ISTR_INTS;
+       if (wdregs[WD_COMMAND_PHASE] == 0x10) {
+           wdregs[WD_COMMAND_PHASE] = 0x11;
+           wd_phase = CSR_SRV_REQ | PHS_MESS_OUT;
+           set_status(wd_phase, 1);
+       }
     }
     incsasr();
+#if WD33C93_DEBUG > 1
+    if (osasr != WD_DATA)
+       write_log("R %s REG %02.2X (%d) = %02.2X (%d)\n", WD33C93, osasr, osasr, v, v);
+#endif
     return v;
 }
 
@@ -282,6 +530,7 @@ static uae_u32 dmac_bget2 (uaecptr addr)
        v = dmac_istr;
        if (v)
            v |= ISTR_INT_P;
+       dmac_istr &= ~0xf;
        break;
        case 0x43:
        v = dmac_cntr;
@@ -299,7 +548,12 @@ static uae_u32 dmac_bget2 (uaecptr addr)
        case 0xa7:
        v = 0xff;
        break;
-    }    
+       case 0xe8:
+       case 0xe9:
+       /* FLUSH */
+       dmac_istr |= ISTR_FE_FLG;
+       break;
+    }
 #if A2091_DEBUG > 0
     write_log ("dmac_bget %04.4X=%02.2X PC=%08.8X\n", addr, v, M68K_GETPC);
 #endif
@@ -368,14 +622,12 @@ static void dmac_bput2 (uaecptr addr, uae_u32 b)
        break;
        case 0xe0:
        case 0xe1:
-       if (!dmac_dma) {
-           dmac_dma = 1;
-           write_log("a2091 dma started\n");
-       }
+       if (!dmac_dma)
+           dmac_start_dma();
        break;
        case 0xe2:
        case 0xe3:
-       dmac_dma = 0;
+       dmac_stop_dma();
        break;
        case 0xe4:
        case 0xe5:
@@ -383,7 +635,8 @@ static void dmac_bput2 (uaecptr addr, uae_u32 b)
        break;
        case 0xe8:
        case 0xe9:
-       dmac_dma = 0;
+       /* FLUSH */
+       dmac_istr |= ISTR_FE_FLG;
        break;
     }
 #if A2091_DEBUG > 0
@@ -521,14 +774,6 @@ addrbank dmaca2091_bank = {
     dmac_lgeti, dmac_wgeti, ABFLAG_IO
 };
 
-
-static void dmac_start_dma(void)
-{
-}
-static void dmac_stop_dma(void)
-{
-}
-
 static void dmacreg_write(uae_u32 *reg, int addr, uae_u32 val, int size)
 {
     addr = (size - 1) - addr;
@@ -545,7 +790,7 @@ static void mbdmac_write (uae_u32 addr, uae_u32 val)
 {
     if (currprefs.cs_mbdmac > 1)
        return;
-#if A3000_DEBUG > 0
+#if A3000_DEBUG > 1
     write_log ("DMAC_WRITE %08.8X=%02.2X PC=%08.8X\n", addr, val & 0xff, M68K_GETPC);
 #endif
     addr &= 0xffff;
@@ -575,14 +820,13 @@ static void mbdmac_write (uae_u32 addr, uae_u32 val)
        break;
        case 0x12:
        case 0x13:
-       if (!dmac_dma) {
-           dmac_dma = 1;
+       if (!dmac_dma)
            dmac_start_dma();
-       }
        break;
        case 0x16:
        case 0x17:
        /* FLUSH */
+       dmac_istr |= ISTR_FE_FLG;
        break;
        case 0x1a:
        case 0x1b:
@@ -597,6 +841,7 @@ static void mbdmac_write (uae_u32 addr, uae_u32 val)
        dmac_dma = 0;
        dmac_stop_dma();
        break;
+       case 0x41:
        case 0x49:
        sasr = val;
        break;
@@ -625,7 +870,7 @@ static uae_u32 mbdmac_read (uae_u32 addr)
        case 0x05:
        case 0x06:
        case 0x07:
-       v = dmacreg_read(dmac_wtc, addr - 0x04, 4);
+       v = 0xff;
        break;
        case 0x0a:
        case 0x0b:
@@ -653,23 +898,24 @@ static uae_u32 mbdmac_read (uae_u32 addr)
        case 0x1e:
        case 0x1f:
        v = dmacreg_read(dmac_istr, addr - 0x1e, 2);
-       if (v)
+       if (v & ISTR_INTS)
            v |= ISTR_INT_P;
+       dmac_istr &= ~15;
        break;
        case 0x3e:
        case 0x3f:
-       dmac_dma = 0;
        dmac_stop_dma();
        v = 0;
        break;
+       case 0x41:
        case 0x49:
-       v = sasr;
+       v = wdscsi_getauxstatus();
        break;
        case 0x43:
        v = wdscsi_get();
        break;
     }
-#if A3000_DEBUG > 0
+#if A3000_DEBUG > 1
     write_log ("DMAC_READ %08.8X=%02.2X PC=%X\n", vaddr, v & 0xff, M68K_GETPC);
 #endif
     return v;
@@ -717,8 +963,8 @@ static void REGPARAM2 mbdmac_wput (uaecptr addr, uae_u32 value)
 #ifdef JIT
     special_mem |= S_WRITE;
 #endif
-    mbdmac_bput (addr, value);
-    mbdmac_bput (addr, value + 1);
+    mbdmac_bput (addr, value >> 8);
+    mbdmac_bput (addr + 1, value & 0xff);
 }
 static void REGPARAM2 mbdmac_bput (uaecptr addr, uae_u32 value)
 {
@@ -746,8 +992,62 @@ static void ew (int addr, uae_u32 value)
        dmacmemory[addr + 2] = ~((value & 0x0f) << 4);
     }
 }
+
+static void freescsi(struct scsi_data *sd)
+{
+    hdf_hd_close(sd->hfd);
+    scsi_free(sd);
+}
+
+int addscsi(int ch, char *path, int blocksize, int readonly,
+                      char *devname, int sectors, int surfaces, int reserved,
+                      int bootpri, char *filesys)
+{
+    struct hd_hardfiledata *hfd;
+    freescsi(scsis[ch]);
+    scsis[ch] = NULL;
+    hfd = xcalloc(sizeof(struct hd_hardfiledata), 1);
+    if (!hdf_hd_open(hfd, path, blocksize, readonly, devname, sectors, surfaces, reserved, bootpri, filesys))
+       return 0;
+    hfd->ansi_version = 2;
+    scsis[ch] = scsi_alloc(hfd);
+    return scsis[ch] ? 1 : 0;
+}
+
+int a3000_add_scsi_unit(int ch, char *path, int blocksize, int readonly,
+                      char *devname, int sectors, int surfaces, int reserved,
+                      int bootpri, char *filesys)
+{
+    return addscsi(ch, path, blocksize, readonly, devname, sectors, surfaces, reserved, bootpri, filesys);
+}
+
+void a3000scsi_reset(void)
+{
+    map_banks (&mbdmac_a3000_bank, 0xDD, 1, 0);
+}
+
+void a3000scsi_free(void)
+{
+    int i;
+    for (i = 0; i < 7; i++)
+       freescsi(scsis[i]);
+}
+
+int a2091_add_scsi_unit(int ch, char *path, int blocksize, int readonly,
+                      char *devname, int sectors, int surfaces, int reserved,
+                      int bootpri, char *filesys)
+{
+    return addscsi(ch, path, blocksize, readonly, devname, sectors, surfaces, reserved, bootpri, filesys);
+}
+
+
 void a2091_free (void)
 {
+    int i;
+    for (i = 0; i < 7; i++)
+       freescsi(scsis[i]);
+    xfree(rom);
+    rom = NULL;
 }
 
 void a2091_reset (void)
@@ -761,7 +1061,8 @@ void a2091_reset (void)
 void a2091_init (void)
 {
     struct zfile *z;
-    char path[MAX_DPATH];
+    int roms[4];
+    struct romlist *rl;
 
     configured = 0;
     memset (dmacmemory, 0xff, 100);
@@ -774,16 +1075,23 @@ void a2091_init (void)
     /* rom vector */
     ew (0x28, ROM_VECTOR >> 8);
     ew (0x2c, ROM_VECTOR);
-    if (!rom) {
-       fetch_datapath (path, sizeof path);
-       strcat (path, "roms\\a2091_rev7.rom");
-       //strcat (path, "roms\\gururom.rom");
-       write_log("A590/A2091 ROM path: '%s'\n", path);
-       z = zfile_fopen(path, "rb");
+
+    roms[0] = 55;
+    roms[1] = 54;
+    roms[2] = 53;
+    roms[3] = -1;
+
+    rl = getrombyids(roms);
+    if (rl) {
+       write_log("A590/A2091 BOOT ROM '%s' %d.%d ", rl->path, rl->rd->ver, rl->rd->rev);
+       z = zfile_fopen(rl->path, "rb");
        if (z) {
+           write_log("loaded\n");
            rom = xmalloc (ROM_SIZE);
            zfile_fread (rom, ROM_SIZE, 1, z);
            zfile_fclose(z);
+       } else {
+           write_log("failed to load\n");
        }
     }
     map_banks (&dmaca2091_bank, 0xe80000 >> 16, 0x10000 >> 16, 0x10000);
diff --git a/ar.c b/ar.c
index 7e0e210708b3ce09f34f6997433b1f8287b61350..ab8a11ef5512340c8fece1fcdac1dacb5d7f3e4c 100755 (executable)
--- a/ar.c
+++ b/ar.c
   * for the first time it displays all the familiar text. Then unsets 'PRIN'.
   */
 
+ /* Super IV:
+  *
+  * Possible "ROM" addresses ("ROM" is loaded from disk to Amiga memory)
+  * - 0xd00000
+  * - 0xc00000
+  * - 0x080000
+  *
+  * CIA-A: 0xb40000
+  * CIA-B: 0xb40001
+  * Custom: 0xe40000
+  */
 
 #include "sysconfig.h"
 #include "sysdeps.h"
 
 static char *cart_memnames[] = { NULL, "hrtmon", "arhrtmon", "superiv" };
 static char *cart_memnames2[] = { NULL, NULL, NULL, "superiv_2" };
+static char *cart_memnames3[] = { NULL, NULL, NULL, "superiv_3" };
 
 #define ARMODE_FREEZE 0 /* AR2/3 The action replay 'freeze' button has been pressed.  */
 #define ARMODE_BREAKPOINT_AR2 2 /* AR2: The action replay is activated via a breakpoint. */
@@ -187,12 +199,12 @@ uae_u8 ar_ciaa[16], ar_ciab[16];
 int hrtmon_flag = ACTION_REPLAY_INACTIVE;
 static int cart_type;
 
-static uae_u8 *hrtmemory = 0, *hrtmemory2 = 0;
+static uae_u8 *hrtmemory = 0, *hrtmemory2 = 0, *hrtmemory3 = 0;
 static uae_u8 *armemory_rom = 0, *armemory_ram = 0;
 
-static uae_u32 hrtmem_mask, hrtmem2_mask;
+static uae_u32 hrtmem_mask, hrtmem2_mask, hrtmem3_mask;
 static uae_u8 *hrtmon_custom, *hrtmon_ciaa, *hrtmon_ciab;
-uae_u32 hrtmem_start, hrtmem2_start, hrtmem_size, hrtmem2_size;
+uae_u32 hrtmem_start, hrtmem2_start, hrtmem3_start, hrtmem_size, hrtmem2_size, hrtmem3_size;
 static int triggered_once;
 
 static void hrtmon_unmap_banks(void);
@@ -218,6 +230,58 @@ static void cartridge_exit(void)
 #endif
 }
 
+static uae_u32 REGPARAM2 hrtmem3_bget (uaecptr addr)
+{
+    addr -= hrtmem3_start & hrtmem3_mask;
+    addr &= hrtmem3_mask;
+    return hrtmemory3[addr];
+}
+static uae_u32 REGPARAM2 hrtmem3_wget (uaecptr addr)
+{
+    return (hrtmem3_bget (addr) << 8) | hrtmem3_bget (addr + 1);
+}
+static uae_u32 REGPARAM2 hrtmem3_lget (uaecptr addr)
+{
+    return (hrtmem3_wget (addr) << 16) | hrtmem3_wget (addr + 2);
+}
+
+static void REGPARAM2 hrtmem3_lput (uaecptr addr, uae_u32 l)
+{
+    uae_u32 *m;
+    addr -= hrtmem3_start & hrtmem3_mask;
+    addr &= hrtmem3_mask;
+    m = (uae_u32 *)(hrtmemory3 + addr);
+    do_put_mem_long (m, l);
+}
+
+static void REGPARAM2 hrtmem3_wput (uaecptr addr, uae_u32 w)
+{
+    uae_u16 *m;
+    addr -= hrtmem3_start & hrtmem3_mask;
+    addr &= hrtmem3_mask;
+    m = (uae_u16 *)(hrtmemory3 + addr);
+    do_put_mem_word (m, (uae_u16)w);
+}
+static void REGPARAM2 hrtmem3_bput (uaecptr addr, uae_u32 b)
+{
+    addr -= hrtmem3_start & hrtmem3_mask;
+    addr &= hrtmem3_mask;
+    hrtmemory3[addr] = b;
+}
+static int REGPARAM2 hrtmem3_check (uaecptr addr, uae_u32 size)
+{
+    addr -= hrtmem3_start & hrtmem3_mask;
+    addr &= hrtmem3_mask;
+    return (addr + size) <= hrtmem3_size;
+}
+
+static uae_u8 *REGPARAM2 hrtmem3_xlate (uaecptr addr)
+{
+    addr -= hrtmem3_start & hrtmem3_mask;
+    addr &= hrtmem3_mask;
+    return hrtmemory3 + addr;
+}
+
 static uae_u32 REGPARAM2 hrtmem2_bget (uaecptr addr)
 {
     addr -= hrtmem2_start & hrtmem2_mask;
@@ -348,7 +412,12 @@ static addrbank hrtmem2_bank = {
     hrtmem2_xlate, hrtmem2_check, NULL, "Cartridge Bank 2",
     hrtmem2_lget, hrtmem2_wget, ABFLAG_RAM
 };
-
+static addrbank hrtmem3_bank = {
+    hrtmem3_lget, hrtmem3_wget, hrtmem3_bget,
+    hrtmem3_lput, hrtmem3_wput, hrtmem3_bput,
+    hrtmem3_xlate, hrtmem3_check, NULL, "Cartridge Bank 3",
+    hrtmem3_lget, hrtmem3_wget, ABFLAG_RAM
+};
 static void copyfromamiga(uae_u8 *dst,uaecptr src,int len)
 {
 while(len--) {
@@ -878,6 +947,11 @@ static void hrtmon_go (void)
        put_long ((uaecptr)(regs.vbr + 8), get_long (hrtmem_start + 8));
        Exception (2, &regs, 0);
        put_long ((uaecptr)(regs.vbr + 8), old);
+    } else if (cart_type == CART_SUPER4) {
+        old = get_long((uaecptr)(regs.vbr + 0x7c));
+       put_long ((uaecptr)(regs.vbr + 0x7c), get_long (hrtmem_start + 0x7c));
+       Interrupt (7);
+       put_long ((uaecptr)(regs.vbr + 0x7c), old);
     } else {
         old = get_long((uaecptr)(regs.vbr + 0x7c));
        put_long ((uaecptr)(regs.vbr + 0x7c), hrtmem_start + 12 + 2 + get_word (hrtmem_start + 14));
@@ -1394,11 +1468,55 @@ int action_replay_unload(int in_memory_reset)
     return 1;
 }
 
+static int superiv_init(struct zfile *f)
+{
+    uae_u32 chip = currprefs.chipmem_size - 0x10000;
+
+    cart_type = CART_SUPER4;
+    hrtmem_start = 0xd00000;
+    hrtmem_size = 0x40000;
+    hrtmem2_start = 0xb00000;
+    hrtmem2_size = 0xc0000;
+    hrtmem3_start = 0xe00000;
+    hrtmem3_size = 0x80000;
+
+    hrtmemory = mapped_malloc (hrtmem_size, cart_memnames[cart_type]);
+    memset (hrtmemory, 0x00, hrtmem_size);
+    zfile_fseek (f, 0, SEEK_SET);
+    zfile_fread (hrtmemory, hrtmem_size, 1, f);
+    zfile_fclose (f);
+
+    hrtmem_mask = hrtmem_size - 1;
+    hrtmem2_mask = hrtmem2_size - 1;
+    hrtmem3_mask = hrtmem3_size - 1;
+    hrtmemory2 = mapped_malloc (hrtmem2_size, cart_memnames2[cart_type]);
+    memset(hrtmemory2, 0, hrtmem2_size);
+    hrtmemory3 = mapped_malloc (hrtmem3_size, cart_memnames3[cart_type]);
+    memset(hrtmemory3, 0, hrtmem3_size);
+    hrtmem3_bank.baseaddr = hrtmemory3;
+    hrtmem2_bank.baseaddr = hrtmemory2;
+    hrtmem_bank.baseaddr = hrtmemory;
+
+    hrtmon_custom = hrtmemory3 + 0x040000;
+    hrtmon_ciaa = hrtmemory2 + 0x040000;
+    hrtmon_ciab = hrtmemory2 + 0x040001;
+
+    chip += 0x30000;
+    hrtmemory2[0x80] = chip >> 24;
+    hrtmemory2[0x81] = chip >> 16;
+    hrtmemory2[0x82] = chip >> 8;
+    hrtmemory2[0x83] = chip >> 0;
+
+    hrtmon_flag = ACTION_REPLAY_IDLE;
+    write_log("%s installed at %08.8X\n", cart_memnames[cart_type], hrtmem_start);
+    return 1;
+}
 
 int action_replay_load(void)
 {
     struct zfile *f;
     uae_u8 header[8];
+    struct romdata *rd;
 
     armodel = 0;
     action_replay_flag = ACTION_REPLAY_INACTIVE;
@@ -1413,23 +1531,31 @@ int action_replay_load(void)
        return 0;
     f = zfile_fopen(currprefs.cartfile,"rb");
     if (!f) {
-       write_log("failed to load '%s' Action Replay ROM\n", currprefs.cartfile);
+       write_log("failed to load '%s' cartridge ROM\n", currprefs.cartfile);
        return 0;
     }
+    rd = getromdatabyzfile(f);
+    if (!rd) {
+       write_log("Unknown cartridge ROM\n");
+    } else {
+       if (rd->type & ROMTYPE_SUPERIV) {
+           return superiv_init(f);
+       }
+    }
     zfile_fseek(f, 0, SEEK_END);
     ar_rom_file_size = zfile_ftell(f);
     zfile_fseek(f, 0, SEEK_SET);
-    if (ar_rom_file_size != 65536 && ar_rom_file_size != 131072 && ar_rom_file_size != 262144) {
-       write_log("rom size must be 64KB (AR1), 128KB (AR2) or 256KB (AR3)\n");
-       zfile_fclose(f);
-       return 0;
-    }
     zfile_fread (header, 1, sizeof header, f);
     zfile_fseek (f, 0, SEEK_SET);
     if (!memcmp (header, "ATZ!HRT!", 8)) {
        zfile_fclose (f);
        return 0;
     }
+    if (ar_rom_file_size != 65536 && ar_rom_file_size != 131072 && ar_rom_file_size != 262144) {
+       write_log("rom size must be 64KB (AR1), 128KB (AR2) or 256KB (AR3)\n");
+       zfile_fclose(f);
+       return 0;
+    }
     action_replay_flag = ACTION_REPLAY_INACTIVE;
     armemory_rom = xmalloc (ar_rom_file_size);
     zfile_fread (armemory_rom, ar_rom_file_size, 1, f);
@@ -1481,11 +1607,17 @@ void action_replay_cleanup()
        mapped_free (hrtmemory);
     if (hrtmemory2)
        mapped_free (hrtmemory2);
+    if (hrtmemory3)
+       mapped_free (hrtmemory3);
 
     armemory_rom = 0;
     armemory_ram = 0;
     hrtmemory = 0;
     hrtmemory2 = 0;
+    hrtmemory3 = 0;
+    hrtmem_size = 0;
+    hrtmem2_size = 0;
+    hrtmem3_size = 0;
     cart_type = 0;
 }
 
@@ -1569,13 +1701,6 @@ int hrtmon_load(void)
        return 0;
        #endif
         cart_type = CART_HRTMON;
-    } else if (currprefs.cart_internal == 2) {
-       hrtmem_start = 0xd00000;
-       hrtmem_size = 0x40000;
-       hrtmem2_start = 0xb00000;
-       hrtmem2_size = 0xc0000;
-       cart_type = CART_SUPER4;
-       goto end;
     }
     hrtmemory = mapped_malloc (hrtmem_size, cart_memnames[cart_type]);
     memset (hrtmemory, 0xff, 0x80000);
@@ -1586,7 +1711,6 @@ int hrtmon_load(void)
     hrtmon_custom = hrtmemory + 0x08f000;
     hrtmon_ciaa = hrtmemory + 0x08e000;
     hrtmon_ciab = hrtmemory + 0x08d000;
-end:
     if (hrtmem2_size) {
        hrtmem2_mask = hrtmem2_size - 1;
        hrtmemory2 = mapped_malloc (hrtmem2_size, cart_memnames2[cart_type]);
@@ -1606,6 +1730,8 @@ void hrtmon_map_banks()
     map_banks (&hrtmem_bank, hrtmem_start >> 16, hrtmem_size >> 16, 0);
     if (hrtmem2_size)
        map_banks (&hrtmem2_bank, hrtmem2_start >> 16, hrtmem2_size >> 16, 0);
+    if (hrtmem3_size)
+       map_banks (&hrtmem3_bank, hrtmem3_start >> 16, hrtmem3_size >> 16, 0);
 }
 
 static void hrtmon_unmap_banks()
@@ -1615,6 +1741,8 @@ static void hrtmon_unmap_banks()
     map_banks (&dummy_bank, hrtmem_start >> 16, hrtmem_size >> 16, 0);
     if (hrtmem2_size)
        map_banks (&dummy_bank, hrtmem2_start >> 16, hrtmem2_size >> 16, 0);
+    if (hrtmem3_size)
+       map_banks (&dummy_bank, hrtmem3_start >> 16, hrtmem3_size >> 16, 0);
 }
 
 #define AR_VER_STR_OFFSET 0x4 /* offset in the rom where the version string begins. */
index 04b9521fcf5c3acf4c0e9c6de7c34dfe20d805a0..8622976bdfafba3e79b142ff9df3ad5329b5c9a1 100755 (executable)
@@ -248,7 +248,7 @@ volatile int uae_int_requested = 0;
 
 void set_uae_int_flag (void)
 {
-    rtarea[0xFFFB] = uae_int_requested;
+    rtarea[0xFFFB] = uae_int_requested & 1;
 }
 
 void rtarea_setup (void)
diff --git a/cdtv.c b/cdtv.c
index b2490bd89c0f218759fac3d8b645bbf01cee3e39..fbcfeeae1ba2ac0f13e8f9e8dc99dfb7ed24c558 100755 (executable)
--- a/cdtv.c
+++ b/cdtv.c
 #include "threaddep/thread.h"
 #include "a2091.h"
 
+
+/* DMAC CNTR bits. */
+#define CNTR_TCEN               (1<<7)
+#define CNTR_PREST              (1<<6)
+#define CNTR_PDMD               (1<<5)
+#define CNTR_INTEN              (1<<4)
+#define CNTR_DDIR               (1<<3)
+/* ISTR bits. */
+#define ISTR_INTX               (1<<8)
+#define ISTR_INT_F              (1<<7)
+#define ISTR_INTS               (1<<6)  
+#define ISTR_E_INT              (1<<5)
+#define ISTR_INT_P              (1<<4)
+#define ISTR_UE_INT             (1<<3)  
+#define ISTR_OE_INT             (1<<2)
+#define ISTR_FF_FLG             (1<<1)
+#define ISTR_FE_FLG             (1<<0)  
+
 #define AUDIO_STATUS_NOT_SUPPORTED  0x00
 #define AUDIO_STATUS_IN_PROGRESS    0x11
 #define AUDIO_STATUS_PAUSED         0x12
@@ -67,8 +85,9 @@ static void do_stch(void);
 
 static void INT2(void)
 {
-    if (!(intreq & 8))
+    if (!(intreq & 8)) {
        INTREQ_f(0x8000 | 0x0008);
+    }
 }
 
 static int cdrom_command_cnt_out, cdrom_command_size_out;
@@ -522,13 +541,6 @@ static void cdrom_command_thread(uae_u8 b)
     }
 }
 
-#define CNTR_INTEN (1 << 4)
-#define CNTR_PREST (1 << 6)
-#define CNTR_TCEN (1 << 7)
-
-#define ISTR_INT_P (1 << 4)
-#define ISTR_E_INT (1 << 5)
-
 static uae_u8 *read_raw(int sector, int size)
 {
     int osector = sector;
@@ -626,7 +638,6 @@ static void *dev_thread (void *p)
            break;
            case 0x0101:
            {
-               get_qcode();
                if (ismedia() != cd_media) {
                    cd_media = ismedia();
                    get_toc();
@@ -635,6 +646,8 @@ static void *dev_thread (void *p)
                    if (!cd_media)
                        cd_hunt = 1;
                }
+               if (cd_media)
+                   get_qcode();
            }
            break;
            case 0x0102: // pause
@@ -777,7 +790,14 @@ static void REGPARAM3 dmac_bput (uaecptr, uae_u32) REGPARAM;
 
 static void dmac_start_dma(void)
 {
-    write_comm_pipe_u32 (&requests, 0x100, 1);
+    if (!(dmac_cntr & CNTR_PDMD)) { // non-scsi dma
+       write_comm_pipe_u32 (&requests, 0x100, 1);
+    }
+}
+
+void cdtv_getdmadata(int *acr)
+{
+    *acr = dmac_acr;
 }
 
 static void do_hunt(void)
@@ -802,6 +822,20 @@ static void do_hunt(void)
     }
 }
 
+static void checkint(void)
+{
+    int irq = 0;
+    if (currprefs.cs_cdtvscsi && (wdscsi_getauxstatus() & 0x80)) {
+        dmac_istr |= ISTR_INTS;
+        if ((dmac_cntr & CNTR_INTEN) && (dmac_istr & ISTR_INTS))
+           irq = 1;
+    }
+    if ((dmac_cntr & CNTR_INTEN) && (dmac_istr & ISTR_E_INT))
+       irq = 1;
+    if (irq)
+       INT2();
+}
+
 void CDTV_hsync_handler(void)
 {
     static int subqcnt;
@@ -820,8 +854,7 @@ void CDTV_hsync_handler(void)
        dma_finished = 0;
        cdtv_hsync = -1;
     }
-    if (dmac_istr & ISTR_E_INT)
-       INT2();
+    checkint();
 
     if (cdrom_command_done) {
        cdrom_command_done = 0;
@@ -918,6 +951,9 @@ static uae_u32 dmac_bget2 (uaecptr addr)
     {
        case 0x41:
        v = dmac_istr;
+       if (v)
+           v |= ISTR_INT_P;
+       dmac_istr &= ~0xf;
        break;
        case 0x43:
        v = dmac_cntr;
@@ -927,8 +963,10 @@ static uae_u32 dmac_bget2 (uaecptr addr)
            v = wdscsi_getauxstatus();
        break;
        case 0x93:
-       if (currprefs.cs_cdtvscsi)
+       if (currprefs.cs_cdtvscsi) {
            v = wdscsi_get();
+           checkint();
+       }
        break;
        case 0xa1:
        if (cdrom_command_cnt_out >= 0) {
@@ -945,6 +983,16 @@ static uae_u32 dmac_bget2 (uaecptr addr)
            }
        }
        break;
+       case 0xe8:
+       case 0xe9:
+       dmac_istr |= ISTR_FE_FLG;
+       break;
+       /* XT IO */
+       case 0xa3:
+       case 0xa5:
+       case 0xa7:
+       v = 0xff;
+       break;
     }
 
 #ifdef CDTV_DEBUG
@@ -955,48 +1003,6 @@ static uae_u32 dmac_bget2 (uaecptr addr)
     return v;
 }
 
-static uae_u32 REGPARAM2 dmac_lget (uaecptr addr)
-{
-    uae_u32 v;
-#ifdef JIT
-    special_mem |= S_READ;
-#endif
-    addr &= 65535;
-    v = (dmac_bget2 (addr) << 24) | (dmac_bget2 (addr + 1) << 16) |
-       (dmac_bget2 (addr + 2) << 8) | (dmac_bget2 (addr + 3));
-#ifdef CDTV_DEBUG
-    write_log ("dmac_lget %08.8X=%08.8X PC=%08.8X\n", addr, v, M68K_GETPC);
-#endif
-    return v;
-}
-
-static uae_u32 REGPARAM2 dmac_wget (uaecptr addr)
-{
-    uae_u32 v;
-#ifdef JIT
-    special_mem |= S_READ;
-#endif
-    addr &= 65535;
-    v = (dmac_bget2 (addr) << 8) | dmac_bget2 (addr + 1);
-#ifdef CDTV_DEBUG
-    write_log ("dmac_wget %08.8X=%04.4X PC=%08.8X\n", addr, v, M68K_GETPC);
-#endif
-    return v;
-}
-
-static uae_u32 REGPARAM2 dmac_bget (uaecptr addr)
-{
-    uae_u32 v;
-#ifdef JIT
-    special_mem |= S_READ;
-#endif
-    addr &= 65535;
-    v = dmac_bget2 (addr);
-    if (!configured)
-       return v;
-    return v;
-}
-
 static void dmac_bput2 (uaecptr addr, uae_u32 b)
 {
     if (addr >= 0xb0 && addr < 0xc0) {
@@ -1056,12 +1062,16 @@ static void dmac_bput2 (uaecptr addr, uae_u32 b)
        dmac_dawr |= b << 0;
        break;
        case 0x91:
-        if (currprefs.cs_cdtvscsi)
+        if (currprefs.cs_cdtvscsi) {
            wdscsi_sasr (b);
+           checkint();
+       }
        break;
        case 0x93:
-       if (currprefs.cs_cdtvscsi)
+        if (currprefs.cs_cdtvscsi) {
            wdscsi_put (b);
+           checkint();
+       }
        break;
        case 0xa1:
        cdrom_command(b);
@@ -1080,16 +1090,59 @@ static void dmac_bput2 (uaecptr addr, uae_u32 b)
        case 0xe4:
        case 0xe5:
        dmac_istr = 0;
+        checkint();
        break;
        case 0xe8:
        case 0xe9:
-       dmac_dma = 0;
+       dmac_istr |= ISTR_FE_FLG;
        break;
     }
 
     tp_check_interrupts();
 }
 
+static uae_u32 REGPARAM2 dmac_lget (uaecptr addr)
+{
+    uae_u32 v;
+#ifdef JIT
+    special_mem |= S_READ;
+#endif
+    addr &= 65535;
+    v = (dmac_bget2 (addr) << 24) | (dmac_bget2 (addr + 1) << 16) |
+       (dmac_bget2 (addr + 2) << 8) | (dmac_bget2 (addr + 3));
+#ifdef CDTV_DEBUG
+    write_log ("dmac_lget %08.8X=%08.8X PC=%08.8X\n", addr, v, M68K_GETPC);
+#endif
+    return v;
+}
+
+static uae_u32 REGPARAM2 dmac_wget (uaecptr addr)
+{
+    uae_u32 v;
+#ifdef JIT
+    special_mem |= S_READ;
+#endif
+    addr &= 65535;
+    v = (dmac_bget2 (addr) << 8) | dmac_bget2 (addr + 1);
+#ifdef CDTV_DEBUG
+    write_log ("dmac_wget %08.8X=%04.4X PC=%08.8X\n", addr, v, M68K_GETPC);
+#endif
+    return v;
+}
+
+static uae_u32 REGPARAM2 dmac_bget (uaecptr addr)
+{
+    uae_u32 v;
+#ifdef JIT
+    special_mem |= S_READ;
+#endif
+    addr &= 65535;
+    v = dmac_bget2 (addr);
+    if (!configured)
+       return v;
+    return v;
+}
+
 static void REGPARAM2 dmac_lput (uaecptr addr, uae_u32 l)
 {
 #ifdef JIT
@@ -1315,6 +1368,13 @@ uae_u8 cdtv_battram_read (int addr)
     return v;
 }
 
+int cdtv_add_scsi_unit(int ch, char *path, int blocksize, int readonly,
+                      char *devname, int sectors, int surfaces, int reserved,
+                      int bootpri, char *filesys)
+{
+    return addscsi(ch, path, blocksize, readonly, devname, sectors, surfaces, reserved, bootpri, filesys);
+}
+
 void cdtv_free (void)
 {
     if (thread_alive > 0) {
@@ -1342,7 +1402,6 @@ void cdtv_init (void)
     }
     write_comm_pipe_u32 (&requests, 0x0104, 1);
    
-
     configured = 0;
     tp_a = tp_b = tp_c = tp_ad = tp_bd = tp_cd = 0;
     tp_imr = tp_cr = tp_air = 0;
index 0c222efb31dc38642c16ec53e584e41646a1bae7..552f253375e6eee392a9c9bf70a9f6c42bbdd552 100755 (executable)
--- a/cfgfile.c
+++ b/cfgfile.c
@@ -220,7 +220,9 @@ static void write_filesys_config (struct uae_prefs *p, const char *unexpanded,
 {
     int i;
     char tmp[MAX_DPATH];
-    char *hdcontrollers[] = { "uae", "ide0", "ide1", "ide2", "ide3" };
+    char *hdcontrollers[] = { "uae",
+       "ide0", "ide1", "ide2", "ide3",
+       "scsi0", "scsi1", "scsi2", "scsi3", "scsi4", "scsi5", "scsi6" };
 
     for (i = 0; i < p->mountitems; i++) {
        struct uaedev_config_info *uci = &p->mountconfig[i];
@@ -518,7 +520,8 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
     cfgfile_write (f, "scsi_cdtv=%s\n", p->cs_cdtvscsi ? "true" : "false");
     cfgfile_write (f, "scsi_a2091=%s\n", p->cs_a2091 ? "true" : "false");
     cfgfile_write (f, "scsi_a4091=%s\n", p->cs_a4091 ? "true" : "false");
-    cfgfile_write (f, "scsi_a3000=%s\n", p->cs_mbdmac ? "true" : "false");
+    cfgfile_write (f, "scsi_a3000=%s\n", p->cs_mbdmac == 1 ? "true" : "false");
+    cfgfile_write (f, "scsi_a4000t=%s\n", p->cs_mbdmac == 2 ? "true" : "false");
 
     cfgfile_write (f, "fastmem_size=%d\n", p->fastmem_size / 0x100000);
     cfgfile_write (f, "a3000mem_size=%d\n", p->mbresmem_low_size / 0x100000);
@@ -1157,6 +1160,16 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, char *option, char *valu
        return 1;
     }
 
+    if (cfgfile_yesno (option, value, "scsi_a3000", &dummy)) {
+       if (dummy)
+           p->cs_mbdmac = 1;
+       return 1;
+    }
+    if (cfgfile_yesno (option, value, "scsi_a4000t", &dummy)) {
+       if (dummy)
+           p->cs_mbdmac = 2;
+       return 1;
+    }
     if (cfgfile_yesno (option, value, "immediate_blits", &p->immediate_blits)
 
        || cfgfile_yesno (option, value, "cd32cd", &p->cs_cd32cd)
@@ -1168,7 +1181,6 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, char *option, char *valu
        || cfgfile_yesno (option, value, "scsi_cdtv", &p->cs_cdtvscsi)
        || cfgfile_yesno (option, value, "scsi_a4091", &p->cs_a4091)
        || cfgfile_yesno (option, value, "scsi_a2091", &p->cs_a2091)
-       || cfgfile_yesno (option, value, "scsi_a3000", &p->cs_mbdmac)
 
        || cfgfile_yesno (option, value, "kickshifter", &p->kickshifter)
        || cfgfile_yesno (option, value, "ntsc", &p->ntscmode)
@@ -1459,8 +1471,13 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, char *option, char *valu
                    *tmpp++ = 0;
                    hdc = tmpp;
                    if(strlen(hdc) >= 4 && !memcmp(hdc, "ide", 3)) {
-                       hdcv = hdc[3] - '0' + 1;
-                       if (hdcv < 1 || hdcv > 4)
+                       hdcv = hdc[3] - '0' + HD_CONTROLLER_IDE0;
+                       if (hdcv < HD_CONTROLLER_IDE0 || hdcv > HD_CONTROLLER_IDE3)
+                           hdcv = 0;
+                   }
+                   if(strlen(hdc) >= 5 && !memcmp(hdc, "scsi", 4)) {
+                       hdcv = hdc[4] - '0' + HD_CONTROLLER_SCSI0;
+                       if (hdcv < HD_CONTROLLER_SCSI0 || hdcv > HD_CONTROLLER_SCSI6)
                            hdcv = 0;
                    }
                }
index 70fba0c45e519cbbf6e767c0142fd6ec8728b33d..0736c60f7bc80951453c2557935a2fa81868dfde 100755 (executable)
--- a/custom.c
+++ b/custom.c
@@ -2622,6 +2622,11 @@ int intlev (void)
     return -1;
 }
 
+STATIC_INLINE int use_eventmode(void)
+{
+    return currprefs.cpu_cycle_exact != 0;
+}
+
 static void INTENA_f(uae_u32 data)
 {
     doint();
@@ -2634,7 +2639,7 @@ STATIC_INLINE void INTENA (uae_u16 v)
        write_log("INTENA %04.4X (%04.4X) %p\n", intena, v, M68K_GETPC);
 #endif
     if (v & 0x8000) {
-       if (!currprefs.cpu_compatible > 0)
+       if (!use_eventmode())
            INTENA_f(0);
        else
            event2_newevent2 (6, 0, INTENA_f);
@@ -2661,7 +2666,7 @@ void INTREQ_f(uae_u32 data)
 
 static void INTREQ_d (uae_u16 v, int d)
 {
-    if (!currprefs.cpu_compatible || v == 0)
+    if (!use_eventmode() || v == 0)
        INTREQ_f(v);
     else
        event2_newevent2(d, v, INTREQ_f);
@@ -2669,7 +2674,7 @@ static void INTREQ_d (uae_u16 v, int d)
 
 void INTREQ (uae_u16 v)
 {
-    if (!currprefs.cpu_compatible)
+    if (!use_eventmode())
        INTREQ_f(v);
     else
        INTREQ_d(v, 6);
@@ -4421,11 +4426,9 @@ static void hsync_handler (void)
        reset_decisions ();
     }
 
-#ifdef FILESYS
     if (uae_int_requested) {
        INTREQ (0x8000 | 0x0008);
     }
-#endif
 
     {
         extern void bsdsock_fake_int_handler(void);
@@ -4461,6 +4464,7 @@ static void hsync_handler (void)
 
     inputdevice_hsync ();
     gayle_hsync();
+    scsi_hsync();
 
     hsync_counter++;
     //copper_check (2);
index 0777957566fcd153892302c1245798939066d0cb..0f0dd6f38f43daae13b768f3422aa61736dee2fe 100755 (executable)
--- a/filesys.c
+++ b/filesys.c
@@ -46,6 +46,8 @@
 #include "gui.h"
 #include "gayle.h"
 #include "savestate.h"
+#include "a2091.h"
+#include "cdtv.h"
 
 #define TRACING_ENABLED 0
 #if TRACING_ENABLED
@@ -414,16 +416,30 @@ static void initialize_mountinfo(void)
     for (i = 0; i < currprefs.mountitems; i++) {
        int idx;
        uci = &currprefs.mountconfig[i];
-       if (uci->controller == 0) {
+       if (uci->controller == HD_CONTROLLER_UAE) {
            idx = set_filesys_unit_1 (-1, uci->devname, uci->volname, uci->rootdir,
                uci->readonly, uci->sectors, uci->surfaces, uci->reserved,
                uci->blocksize, uci->bootpri, uci->filesys, 0, 0);
            if (idx >= 0)
                uci->configoffset = idx;
-       } else {
-           gayle_add_ide_unit (uci->controller - 1, uci->rootdir, uci->blocksize, uci->readonly,
+       } else if (uci->controller <= HD_CONTROLLER_IDE3 ) {
+           gayle_add_ide_unit (uci->controller - HD_CONTROLLER_IDE0, uci->rootdir, uci->blocksize, uci->readonly,
                uci->devname, uci->sectors, uci->surfaces, uci->reserved,
                uci->bootpri, uci->filesys);
+       } else if (uci->controller <= HD_CONTROLLER_SCSI6) {
+           if (currprefs.cs_mbdmac) {
+               a3000_add_scsi_unit (uci->controller - HD_CONTROLLER_SCSI0, uci->rootdir, uci->blocksize, uci->readonly,
+                   uci->devname, uci->sectors, uci->surfaces, uci->reserved,
+                   uci->bootpri, uci->filesys);
+           } else if (currprefs.cs_a2091) {
+               a2091_add_scsi_unit (uci->controller - HD_CONTROLLER_SCSI0, uci->rootdir, uci->blocksize, uci->readonly,
+                   uci->devname, uci->sectors, uci->surfaces, uci->reserved,
+                   uci->bootpri, uci->filesys);
+           } else if (currprefs.cs_cdtvscsi) {
+               cdtv_add_scsi_unit (uci->controller - HD_CONTROLLER_SCSI0, uci->rootdir, uci->blocksize, uci->readonly,
+                   uci->devname, uci->sectors, uci->surfaces, uci->reserved,
+                   uci->bootpri, uci->filesys);
+           }
        }
     }
     filesys_addexternals();
@@ -3332,7 +3348,7 @@ static uae_u32 REGPARAM2 exter_int_helper (TrapContext *context)
     switch (n) {
      case 0:
        /* Determine whether a given EXTER interrupt is for us. */
-       if (uae_int_requested) {
+       if (uae_int_requested & 1) {
            if (uae_sem_trywait (&singlethread_int_sem) != 0)
                /* Pretend it isn't for us. We might get it again later. */
                return 0;
@@ -3340,7 +3356,7 @@ static uae_u32 REGPARAM2 exter_int_helper (TrapContext *context)
             * That way, we can get too many interrupts, but never not
             * enough. */
            filesys_in_interrupt++;
-           uae_int_requested = 0;
+           uae_int_requested &= ~1;
            unit_no = 0;
            return 1;
        }
diff --git a/gayle.c b/gayle.c
index 8ec62d282aa3f87b1434078adad855d6571b4c05..7fdc78d5b5f3da6b32b35201675c5137a40ecdae 100755 (executable)
--- a/gayle.c
+++ b/gayle.c
@@ -127,11 +127,7 @@ DE0000 to DEFFFF           64 KB Motherboard resources
 
 struct ide_hdf
 {
-    struct hardfiledata hfd;
-    int cyls, heads, secspertrack;
-    int cyls_def, heads_def, secspertrack_def;
-    uae_u64 size;
-    char *path;
+    struct hd_hardfiledata hdhfd;
 
     uae_u8 secbuf[512 * 256];
     int data_offset;
@@ -141,7 +137,6 @@ struct ide_hdf
     uae_u8 status;
     int irq_delay;
     int num;
-    int bootpri; // for fake RDB
 };
 
 static struct ide_hdf idedrive[4];
@@ -191,7 +186,7 @@ static void ide_interrupt_do(struct ide_hdf *ide)
 static void ide_fail(void)
 {
     ide_error |= IDE_ERR_ABRT;
-    if (ide_drv == 1 && idedrive[ide2 + 1].size == 0)
+    if (ide_drv == 1 && idedrive[ide2 + 1].hdhfd.size == 0)
        idedrive[ide2].status |= IDE_STATUS_ERR;
     ide->status |= IDE_STATUS_ERR;
     ide_interrupt();
@@ -221,7 +216,7 @@ static void ide_identify_drive(void)
     int v;
     uae_u8 *buf = ide->secbuf;
 
-    if (ide->size == 0) {
+    if (ide->hdhfd.size == 0) {
        ide_fail();
        return;
     }
@@ -229,11 +224,11 @@ static void ide_identify_drive(void)
        write_log("IDE%d identify drive\n", ide->num);
     ide_data_ready(1);
     pw(0, (1 << 10) | (1 << 6) | (1 << 2) | (1 << 3));
-    pw(1, ide->cyls_def);
-    pw(3, ide->heads_def);
-    pw(4, 512 * ide->secspertrack_def);
+    pw(1, ide->hdhfd.cyls_def);
+    pw(3, ide->hdhfd.heads_def);
+    pw(4, 512 * ide->hdhfd.secspertrack_def);
     pw(5, 512);
-    pw(6, ide->secspertrack_def);
+    pw(6, ide->hdhfd.secspertrack_def);
     ps(10, "68000", 20); /* serial */
     pw(20, 3);
     pw(21, 512);
@@ -244,15 +239,15 @@ static void ide_identify_drive(void)
     pw(49, (1 << 9) | (1 << 8)); /* LBA and DMA supported */
     pw(51, 240 << 8); /* PIO0 to PIO2 supported */
     pw(53, 1 | 2);
-    pw(54, ide->cyls);
-    pw(55, ide->heads);
-    pw(56, ide->secspertrack);
-    totalsecs = ide->cyls * ide->heads * ide->secspertrack;
+    pw(54, ide->hdhfd.cyls);
+    pw(55, ide->hdhfd.heads);
+    pw(56, ide->hdhfd.secspertrack);
+    totalsecs = ide->hdhfd.cyls * ide->hdhfd.heads * ide->hdhfd.secspertrack;
     pw(57, totalsecs);
     pw(58, totalsecs >> 16);
     v = idedrive[ide_drv].multiple_mode;
     pw(59, (v > 0 ? 0x100 : 0) | v);
-    totalsecs = ide->size / 512;
+    totalsecs = ide->hdhfd.size / 512;
     pw(60, totalsecs);
     pw(61, totalsecs >> 16);
     pw(62, 0x0f);
@@ -267,21 +262,21 @@ static void ide_identify_drive(void)
 }
 static void ide_initialize_drive_parameters(void)
 {
-    if (ide->size) {
-       ide->secspertrack = ide_nsector == 0 ? 256 : ide_nsector;
-       ide->heads = (ide_select & 15) + 1;
-       ide->cyls = (ide->size / 512) / (ide->secspertrack * ide->heads);
-       if (ide->heads * ide->cyls * ide->secspertrack > 16515072) {
-           ide->cyls = ide->cyls_def;
-           ide->heads = ide->heads_def;
-           ide->secspertrack = ide->secspertrack_def;
+    if (ide->hdhfd.size) {
+       ide->hdhfd.secspertrack = ide_nsector == 0 ? 256 : ide_nsector;
+       ide->hdhfd.heads = (ide_select & 15) + 1;
+       ide->hdhfd.cyls = (ide->hdhfd.size / 512) / (ide->hdhfd.secspertrack * ide->hdhfd.heads);
+       if (ide->hdhfd.heads * ide->hdhfd.cyls * ide->hdhfd.secspertrack > 16515072) {
+           ide->hdhfd.cyls = ide->hdhfd.cyls_def;
+           ide->hdhfd.heads = ide->hdhfd.heads_def;
+           ide->hdhfd.secspertrack = ide->hdhfd.secspertrack_def;
        }
     } else {
        ide_error |= IDE_ERR_ABRT;
        ide->status |= IDE_STATUS_ERR;
     }
     write_log("IDE%d initialize drive parameters, CYL=%d,SPT=%d,HEAD=%d\n",
-       ide->num, ide->cyls, ide->secspertrack, ide->heads);
+       ide->num, ide->hdhfd.cyls, ide->hdhfd.secspertrack, ide->hdhfd.heads);
     ide_interrupt();
 }
 static void ide_set_multiple_mode(void)
@@ -304,7 +299,7 @@ static void get_lbachs(struct ide_hdf *ide, int *lba, int *cyl, int *head, int *
        *cyl = (ide_hcyl << 8) | ide_lcyl;
        *head = ide_select & 15;
        *sec = ide_sector;
-       *lba = (((*cyl) * ide->heads + (*head)) * ide->secspertrack) + (*sec) - 1;
+       *lba = (((*cyl) * ide->hdhfd.heads + (*head)) * ide->hdhfd.secspertrack) + (*sec) - 1;
     }
 }
 static void put_lbachs(struct ide_hdf *ide, int lba, int cyl, int head, int sec, int inc)
@@ -318,11 +313,11 @@ static void put_lbachs(struct ide_hdf *ide, int lba, int cyl, int head, int sec,
        ide_sector = lba & 0xff;
     } else {
        sec += inc;
-       while (sec >= ide->secspertrack) {
-           sec -= ide->secspertrack;
+       while (sec >= ide->hdhfd.secspertrack) {
+           sec -= ide->hdhfd.secspertrack;
            head++;
-           if (head >= ide->heads) {
-               head -= ide->heads;
+           if (head >= ide->hdhfd.heads) {
+               head -= ide->hdhfd.heads;
                cyl++;
            }
        }
@@ -350,14 +345,22 @@ static void ide_read_sectors(int multi)
        write_log("IDE%d read offset=%d, sectors=%d (%d)\n", ide->num, lba, nsec, ide->multiple_mode);
     if (multi && ide->multiple_mode > nsec)
        nsec = ide->multiple_mode;
-    if (lba * 512 >= ide->size) {
+    if (lba * 512 >= ide->hdhfd.size) {
        ide_fail();
        return;
     }
-    if (nsec * 512 > ide->size - lba * 512)
-       nsec = (ide->size - lba * 512) / 512;
+    if (nsec * 512 > ide->hdhfd.size - lba * 512)
+       nsec = (ide->hdhfd.size - lba * 512) / 512;
     ide_data_ready(nsec);
-    hdf_read (&ide->hfd, ide->secbuf, lba * 512, nsec * 512);
+#if 0
+    {
+       uae_u64 offset = lba * 512;
+       uae_u64 len = nsec * 512;
+       write_log ("cmd_read: %04.4x-%08.8x (%d) %08.8x (%d)\n",
+           (uae_u32)(offset >> 32), (uae_u32)offset, (uae_u32)(offset / 512), (uae_u32)len, (uae_u32)(len / 512));
+    }
+#endif
+    hdf_read (&ide->hdhfd.hfd, ide->secbuf, lba * 512, nsec * 512);
     put_lbachs(ide, lba, cyl, head, sec, nsec);
     ide->data_multi = multi ? ide->multiple_mode : 1;
 }
@@ -372,14 +375,14 @@ static void ide_write_sectors(int multi)
     gui_hd_led (2);
     nsec = ide_nsector == 0 ? 256 : ide_nsector;
     get_lbachs(ide, &lba, &cyl, &head, &sec);
-    if (lba * 512 >= ide->size) {
+    if (lba * 512 >= ide->hdhfd.size) {
        ide_fail();
        return;
     }
     if (IDE_LOG > 0)
        write_log("IDE%d write offset=%d, sectors=%d (%d)\n", ide->num, lba, nsec, ide->multiple_mode);
-    if (nsec * 512 > ide->size - lba * 512)
-       nsec = (ide->size - lba * 512) / 512;
+    if (nsec * 512 > ide->hdhfd.size - lba * 512)
+       nsec = (ide->hdhfd.size - lba * 512) / 512;
     ide_data_ready(nsec);
     ide->data_multi = multi ? ide->multiple_mode : 1;
 }
@@ -427,7 +430,7 @@ static uae_u16 ide_get_data(void)
     if (ide->data_size == 0) {
        if (IDE_LOG > 0)
            write_log("IDE%d DATA read without DRQ!?\n", ide->num);
-       if (ide->size == 0)
+       if (ide->hdhfd.size == 0)
            return 0xffff;
        return 0;
     }
@@ -469,7 +472,7 @@ static void ide_put_data(uae_u16 v)
        get_lbachs(ide, &lba, &cyl, &head, &sec);
        if (IDE_LOG > 0)
            write_log("IDE%d write finished, %d bytes (%d) written\n", ide->num, ide->data_offset, ide->data_offset / 512);
-       hdf_write(&ide->hfd, ide->secbuf, lba * 512, ide->data_offset);
+       hdf_write(&ide->hdhfd.hfd, ide->secbuf, lba * 512, ide->data_offset);
        put_lbachs(ide, lba, cyl, head, sec, nsec);
        irq = 1;
     }
@@ -528,7 +531,7 @@ static uae_u32 ide_read (uaecptr addr)
     }
     ide_reg = get_ide_reg(addr);
     /* Emulated "ide hack". Prevents long KS boot delay if no drives installed */
-    if (idedrive[0].size == 0 && idedrive[2].size == 0)
+    if (idedrive[0].hdhfd.size == 0 && idedrive[2].hdhfd.size == 0)
        return 0xff;
     switch (ide_reg)
     {
@@ -571,7 +574,7 @@ static uae_u32 ide_read (uaecptr addr)
            v = ide_devcon;
        break;
        case IDE_STATUS:
-           if (ide->size == 0) {
+           if (ide->hdhfd.size == 0) {
                v = 0;
                if (ide_error)
                    v |= IDE_STATUS_ERR;
@@ -1112,166 +1115,11 @@ void gayle_free_ide_units(void)
 
     for (i = 0; i < 4; i++) {
        struct ide_hdf *ide = &idedrive[i];
-       if (ide->hfd.handle_valid)
-           hdf_close(&ide->hfd);
-       xfree(ide->path);
+       hdf_hd_close(&ide->hdhfd);
        memset(ide, 0, sizeof (struct ide_hdf));
     }
 }
 
-void getchs2 (struct hardfiledata *hfd, int *pcyl, int *phead, int *psectorspertrack)
-{
-    unsigned int total = (unsigned int)(hfd->size / 512);
-    int i, head , cyl, spt;
-    int sptt[] = { 63, 127, 255, -1 };
-
-    if (total > 16515072) {
-        /* >8G, CHS=16383/16/63 */
-       *pcyl = 16383;
-       *phead = 16;
-       *psectorspertrack = 63;
-       return;
-    }
-
-    for (i = 0; sptt[i] >= 0; i++) {
-       spt = sptt[i];
-       for (head = 4; head <= 16;head++) {
-           cyl = total / (head * spt);
-           if (hfd->size <= 512 * 1024 * 1024) {
-               if (cyl <= 1023)
-                   break;
-           } else {
-               if (cyl < 16383)
-                   break;
-               if (cyl < 32767 && head >= 5)
-                   break;
-               if (cyl <= 65535)
-                   break;
-           }
-       }
-       if (head <= 16)
-           break;
-    }
-    *pcyl = cyl;
-    *phead = head;
-    *psectorspertrack = spt;
-}
-
-static void pl(uae_u8 *p, int off, uae_u32 v)
-{
-    p += off * 4;
-    p[0] = v >> 24;
-    p[1] = v >> 16;
-    p[2] = v >> 8;
-    p[3] = v >> 0;
-}
-
-static void rdb_crc(uae_u8 *p)
-{
-    uae_u32 sum;
-    int i, blocksize;
-    
-    sum =0;
-    blocksize = rl (p + 1 * 4);
-    for (i = 0; i < blocksize; i++)
-       sum += rl (p + i * 4);
-    sum = -sum;
-    pl (p, 2, sum);
-}
-
-static void create_virtual_rdb(struct hardfiledata *hfd, uae_u32 dostype, int bootpri, char *filesys)
-{
-    uae_u8 *rdb, *part, *denv;
-    int cyl = hfd->heads * hfd->secspertrack;
-    int cyls = 262144 / (cyl * 512);
-    int size = cyl * cyls * 512;
-
-    rdb = xcalloc (size, 1);
-    hfd->virtual_rdb = rdb;
-    hfd->virtual_size = size;
-    part = rdb + 512;
-    pl(rdb, 0, 0x5244534b);
-    pl(rdb, 1, 64);
-    pl(rdb, 2, 0); // chksum
-    pl(rdb, 3, 0); // hostid
-    pl(rdb, 4, 512); // blockbytes
-    pl(rdb, 5, 0); // flags
-    pl(rdb, 6, -1); // badblock
-    pl(rdb, 7, 1); // part
-    pl(rdb, 8, -1); // fs
-    pl(rdb, 9, -1); // driveinit
-    pl(rdb, 10, -1); // reserved
-    pl(rdb, 11, -1); // reserved
-    pl(rdb, 12, -1); // reserved
-    pl(rdb, 13, -1); // reserved
-    pl(rdb, 14, -1); // reserved
-    pl(rdb, 15, -1); // reserved
-    pl(rdb, 16, hfd->nrcyls);
-    pl(rdb, 17, hfd->secspertrack);
-    pl(rdb, 18, hfd->heads);
-    pl(rdb, 19, 0); // interleave
-    pl(rdb, 20, 0); // park
-    pl(rdb, 21, -1); // res
-    pl(rdb, 22, -1); // res
-    pl(rdb, 23, -1); // res
-    pl(rdb, 24, 0); // writeprecomp
-    pl(rdb, 25, 0); // reducedwrite
-    pl(rdb, 26, 0); // steprate
-    pl(rdb, 27, -1); // res
-    pl(rdb, 28, -1); // res
-    pl(rdb, 29, -1); // res
-    pl(rdb, 30, -1); // res
-    pl(rdb, 31, -1); // res
-    pl(rdb, 32, 0); // rdbblockslo
-    pl(rdb, 33, cyl * cyls); // rdbblockshi
-    pl(rdb, 34, cyls); // locyl
-    pl(rdb, 35, hfd->nrcyls + cyls); // hicyl
-    pl(rdb, 36, cyl); // cylblocks
-    pl(rdb, 37, 0); // autopark
-    pl(rdb, 38, 2); // highrdskblock
-    pl(rdb, 39, -1); // res
-    strcpy (rdb + 40 * 4, hfd->vendor_id);
-    strcpy (rdb + 42 * 4, hfd->product_id);
-    strcpy (rdb + 46 * 4, "UAE");
-    rdb_crc(rdb);
-
-    pl(part, 0, 0x50415254);
-    pl(part, 1, 64);
-    pl(part, 2, 0);
-    pl(part, 3, 0);
-    pl(part, 4, -1);
-    pl(part, 5, 1); // bootable
-    pl(part, 6, -1);
-    pl(part, 7, -1);
-    pl(part, 8, 0); // devflags
-    part[9 * 4] = strlen(hfd->device_name);
-    strcpy (part + 9 * 4 + 1, hfd->device_name);
-
-    denv = part + 128;
-    pl(denv, 0, 80);
-    pl(denv, 1, 512 / 4);
-    pl(denv, 2, 0); // secorg
-    pl(denv, 3, hfd->heads);
-    pl(denv, 4, hfd->blocksize / 512);
-    pl(denv, 5, hfd->secspertrack);
-    pl(denv, 6, hfd->reservedblocks);
-    pl(denv, 7, 0); // prealloc
-    pl(denv, 8, 0); // interleave
-    pl(denv, 9, cyls); // lowcyl
-    pl(denv, 10, hfd->nrcyls + cyls - 1);
-    pl(denv, 11, 50);
-    pl(denv, 12, 0);
-    pl(denv, 13, 0x00ffffff);
-    pl(denv, 14, 0x7ffffffe);
-    pl(denv, 15, bootpri);
-    pl(denv, 16, dostype);
-    rdb_crc(part);
-
-    hfd->size += size;
-    hfd->size2 += size;
-
-}
-
 int gayle_add_ide_unit(int ch, char *path, int blocksize, int readonly,
                       char *devname, int sectors, int surfaces, int reserved,
                       int bootpri, char *filesys)
@@ -1281,35 +1129,9 @@ int gayle_add_ide_unit(int ch, char *path, int blocksize, int readonly,
     if (ch >= 4)
        return -1;
     ide = &idedrive[ch];
-    ide->hfd.readonly = readonly;
-    ide->hfd.blocksize = blocksize;
-    ide->bootpri = bootpri;
-    ide->size = 0;
-    if (!hdf_open(&ide->hfd, path))
+    if (!hdf_hd_open(&ide->hdhfd, path, blocksize, readonly, devname, sectors, surfaces, reserved, bootpri, filesys))
        return -1;
-    ide->path = my_strdup(path);
-    ide->hfd.heads = surfaces;
-    ide->hfd.reservedblocks = reserved;
-    ide->hfd.secspertrack = sectors;
-    if (devname)
-       strcpy (ide->hfd.device_name, devname);
-    getchs2(&ide->hfd, &ide->cyls, &ide->heads, &ide->secspertrack);
-    ide->cyls_def = ide->cyls;
-    ide->secspertrack_def = ide->secspertrack;
-    ide->heads_def = ide->heads;
-    if (ide->hfd.heads && ide->hfd.secspertrack) {
-       uae_u8 buf[512] = { 0 };
-        hdf_read(&ide->hfd, buf, 0, 512);
-       if (buf[0] != 0 && memcmp(buf, "RDSK", 4)) {
-           ide->hfd.nrcyls = (ide->hfd.size / blocksize) / (sectors * surfaces);
-           create_virtual_rdb(&ide->hfd, rl (buf), ide->bootpri, filesys);
-           while (ide->hfd.nrcyls * surfaces * sectors > ide->cyls_def * ide->secspertrack_def * ide->heads_def) {
-               ide->cyls_def++;
-           }
-       }
-    }
-    ide->size = ide->hfd.size;
-    write_log("IDE%d ('%s'), CHS=%d,%d,%d\n", ch, path, ide->cyls, ide->heads, ide->secspertrack);
+    write_log("IDE%d ('%s'), CHS=%d,%d,%d\n", ch, path, ide->hdhfd.cyls, ide->hdhfd.heads, ide->hdhfd.secspertrack);
     ide->status = 0;
     ide->data_offset = 0;
     ide->data_size = 0;
@@ -1328,7 +1150,7 @@ static void initide(void)
     ide_lcyl = ide_hcyl = ide_devcon = ide_feat = 0;
     ide_drv = 0;
     ide_splitter = 0;
-    if (idedrive[2].size) {
+    if (idedrive[2].hdhfd.size) {
        ide_splitter = 1;
        write_log("IDE splitter enabled\n");
     }
@@ -1388,18 +1210,18 @@ uae_u8 *save_ide (int num, int *len)
 
     if (currprefs.cs_ide <= 0)
        return NULL;
-    if (ide->size == 0)
+    if (ide->hdhfd.size == 0)
        return NULL;
     dstbak = dst = malloc (1000);
     save_u32(num);
-    save_u64(ide->size);
-    save_string(ide->path);
-    save_u32(ide->hfd.blocksize);
-    save_u32(ide->hfd.readonly);
+    save_u64(ide->hdhfd.size);
+    save_string(ide->hdhfd.path);
+    save_u32(ide->hdhfd.hfd.blocksize);
+    save_u32(ide->hdhfd.hfd.readonly);
     save_u8(ide->multiple_mode);
-    save_u32(ide->cyls);
-    save_u32(ide->heads);
-    save_u32(ide->secspertrack);
+    save_u32(ide->hdhfd.cyls);
+    save_u32(ide->hdhfd.heads);
+    save_u32(ide->hdhfd.secspertrack);
     save_u8(ide_select);
     save_u8(ide_nsector);
     save_u8(ide_nsector2);
@@ -1413,11 +1235,11 @@ uae_u8 *save_ide (int num, int *len)
     save_u8(ide_feat2);
     save_u8(ide_error);
     save_u8(ide_devcon);
-    save_u64(ide->hfd.virtual_size);
-    save_u32(ide->hfd.secspertrack);
-    save_u32(ide->hfd.heads);
-    save_u32(ide->hfd.reservedblocks);
-    save_u32(ide->bootpri);
+    save_u64(ide->hdhfd.hfd.virtual_size);
+    save_u32(ide->hdhfd.hfd.secspertrack);
+    save_u32(ide->hdhfd.hfd.heads);
+    save_u32(ide->hdhfd.hfd.reservedblocks);
+    save_u32(ide->hdhfd.bootpri);
     *len = dst - dstbak;
     return dstbak;
 }
@@ -1436,9 +1258,9 @@ uae_u8 *restore_ide (uae_u8 *src)
     blocksize = restore_u32();
     readonly = restore_u32();
     ide->multiple_mode = restore_u8();
-    ide->cyls = restore_u32();
-    ide->heads = restore_u32();
-    ide->secspertrack = restore_u32();
+    ide->hdhfd.cyls = restore_u32();
+    ide->hdhfd.heads = restore_u32();
+    ide->hdhfd.secspertrack = restore_u32();
     ide_select = restore_u8();
     ide_nsector = restore_u8();
     ide_sector = restore_u8();
@@ -1452,14 +1274,14 @@ uae_u8 *restore_ide (uae_u8 *src)
     ide_feat2 = restore_u8();
     ide_error = restore_u8();
     ide_devcon = restore_u8();
-    ide->hfd.virtual_size = restore_u64();
-    ide->hfd.secspertrack = restore_u32();
-    ide->hfd.heads = restore_u32();
-    ide->hfd.reservedblocks = restore_u32();
-    ide->bootpri = restore_u32();
-    if (ide->hfd.virtual_size)
-       gayle_add_ide_unit (num, path, blocksize, readonly, ide->hfd.device_name,
-           ide->hfd.secspertrack, ide->hfd.heads, ide->hfd.reservedblocks, ide->bootpri, NULL);
+    ide->hdhfd.hfd.virtual_size = restore_u64();
+    ide->hdhfd.hfd.secspertrack = restore_u32();
+    ide->hdhfd.hfd.heads = restore_u32();
+    ide->hdhfd.hfd.reservedblocks = restore_u32();
+    ide->hdhfd.bootpri = restore_u32();
+    if (ide->hdhfd.hfd.virtual_size)
+       gayle_add_ide_unit (num, path, blocksize, readonly, ide->hdhfd.hfd.device_name,
+           ide->hdhfd.hfd.secspertrack, ide->hdhfd.hfd.heads, ide->hdhfd.hfd.reservedblocks, ide->hdhfd.bootpri, NULL);
     else
         gayle_add_ide_unit (num, path, blocksize, readonly, 0, 0, 0, 0, 0, 0);
     xfree(path);
index ef12ab73715a3b88591d35ba0be9e2f9773066b1..cae446b210713ba40144f0c486efcdc1e20d551b 100755 (executable)
@@ -23,6 +23,7 @@
 #include "native2amiga.h"
 #include "gui.h"
 #include "uae.h"
+#include "scsi.h"
 
 #define CMD_INVALID    0
 #define CMD_RESET      1
 #define NSCMD_TD_FORMAT64 0xc003
 
 #undef DEBUGME
+#define hf_log
+#define hf_log2
+#define scsi_log
+#define hf_log3
+
 //#define DEBUGME
 #ifdef DEBUGME
+#undef hf_log
 #define hf_log write_log
+#undef hf_log2
 #define hf_log2 write_log
+#undef scsi_log
 #define scsi_log write_log
-#else
-#define hf_log
-#define hf_log2
-#define scsi_log
 #endif
 
 #define MAX_ASYNC_REQUESTS 50
@@ -102,62 +107,255 @@ static void wl (uae_u8 *p, int v)
     p[2] = v >> 8;
     p[3] = v;
 }
+static void ww (uae_u8 *p, int v)
+{
+    p[0] = v >> 8;
+    p[1] = v;
+}
 static int rl (uae_u8 *p)
 {
     return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | (p[3]);
 }
 
+
+void getchshd (struct hardfiledata *hfd, int *pcyl, int *phead, int *psectorspertrack)
+{
+    unsigned int total = (unsigned int)(hfd->size / 512);
+    int i, head , cyl, spt;
+    int sptt[] = { 63, 127, 255, -1 };
+
+    if (total > 16515072) {
+        /* >8G, CHS=16383/16/63 */
+       *pcyl = 16383;
+       *phead = 16;
+       *psectorspertrack = 63;
+       return;
+    }
+
+    for (i = 0; sptt[i] >= 0; i++) {
+       spt = sptt[i];
+       for (head = 4; head <= 16;head++) {
+           cyl = total / (head * spt);
+           if (hfd->size <= 512 * 1024 * 1024) {
+               if (cyl <= 1023)
+                   break;
+           } else {
+               if (cyl < 16383)
+                   break;
+               if (cyl < 32767 && head >= 5)
+                   break;
+               if (cyl <= 65535)
+                   break;
+           }
+       }
+       if (head <= 16)
+           break;
+    }
+    *pcyl = cyl;
+    *phead = head;
+    *psectorspertrack = spt;
+}
+
+static void pl(uae_u8 *p, int off, uae_u32 v)
+{
+    p += off * 4;
+    p[0] = v >> 24;
+    p[1] = v >> 16;
+    p[2] = v >> 8;
+    p[3] = v >> 0;
+}
+
+static void rdb_crc(uae_u8 *p)
+{
+    uae_u32 sum;
+    int i, blocksize;
+    
+    sum =0;
+    blocksize = rl (p + 1 * 4);
+    for (i = 0; i < blocksize; i++)
+       sum += rl (p + i * 4);
+    sum = -sum;
+    pl (p, 2, sum);
+}
+
+static void create_virtual_rdb(struct hardfiledata *hfd, uae_u32 dostype, int bootpri, char *filesys)
+{
+    uae_u8 *rdb, *part, *denv;
+    int cyl = hfd->heads * hfd->secspertrack;
+    int cyls = 262144 / (cyl * 512);
+    int size = cyl * cyls * 512;
+
+    rdb = xcalloc (size, 1);
+    hfd->virtual_rdb = rdb;
+    hfd->virtual_size = size;
+    part = rdb + 512;
+    pl(rdb, 0, 0x5244534b);
+    pl(rdb, 1, 64);
+    pl(rdb, 2, 0); // chksum
+    pl(rdb, 3, 0); // hostid
+    pl(rdb, 4, 512); // blockbytes
+    pl(rdb, 5, 0); // flags
+    pl(rdb, 6, -1); // badblock
+    pl(rdb, 7, 1); // part
+    pl(rdb, 8, -1); // fs
+    pl(rdb, 9, -1); // driveinit
+    pl(rdb, 10, -1); // reserved
+    pl(rdb, 11, -1); // reserved
+    pl(rdb, 12, -1); // reserved
+    pl(rdb, 13, -1); // reserved
+    pl(rdb, 14, -1); // reserved
+    pl(rdb, 15, -1); // reserved
+    pl(rdb, 16, hfd->nrcyls);
+    pl(rdb, 17, hfd->secspertrack);
+    pl(rdb, 18, hfd->heads);
+    pl(rdb, 19, 0); // interleave
+    pl(rdb, 20, 0); // park
+    pl(rdb, 21, -1); // res
+    pl(rdb, 22, -1); // res
+    pl(rdb, 23, -1); // res
+    pl(rdb, 24, 0); // writeprecomp
+    pl(rdb, 25, 0); // reducedwrite
+    pl(rdb, 26, 0); // steprate
+    pl(rdb, 27, -1); // res
+    pl(rdb, 28, -1); // res
+    pl(rdb, 29, -1); // res
+    pl(rdb, 30, -1); // res
+    pl(rdb, 31, -1); // res
+    pl(rdb, 32, 0); // rdbblockslo
+    pl(rdb, 33, cyl * cyls); // rdbblockshi
+    pl(rdb, 34, cyls); // locyl
+    pl(rdb, 35, hfd->nrcyls + cyls); // hicyl
+    pl(rdb, 36, cyl); // cylblocks
+    pl(rdb, 37, 0); // autopark
+    pl(rdb, 38, 2); // highrdskblock
+    pl(rdb, 39, -1); // res
+    strcpy (rdb + 40 * 4, hfd->vendor_id);
+    strcpy (rdb + 42 * 4, hfd->product_id);
+    strcpy (rdb + 46 * 4, "UAE");
+    rdb_crc(rdb);
+
+    pl(part, 0, 0x50415254);
+    pl(part, 1, 64);
+    pl(part, 2, 0);
+    pl(part, 3, 0);
+    pl(part, 4, -1);
+    pl(part, 5, 1); // bootable
+    pl(part, 6, -1);
+    pl(part, 7, -1);
+    pl(part, 8, 0); // devflags
+    part[9 * 4] = strlen(hfd->device_name);
+    strcpy (part + 9 * 4 + 1, hfd->device_name);
+
+    denv = part + 128;
+    pl(denv, 0, 80);
+    pl(denv, 1, 512 / 4);
+    pl(denv, 2, 0); // secorg
+    pl(denv, 3, hfd->heads);
+    pl(denv, 4, hfd->blocksize / 512);
+    pl(denv, 5, hfd->secspertrack);
+    pl(denv, 6, hfd->reservedblocks);
+    pl(denv, 7, 0); // prealloc
+    pl(denv, 8, 0); // interleave
+    pl(denv, 9, cyls); // lowcyl
+    pl(denv, 10, hfd->nrcyls + cyls - 1);
+    pl(denv, 11, 50);
+    pl(denv, 12, 0);
+    pl(denv, 13, 0x00ffffff);
+    pl(denv, 14, 0x7ffffffe);
+    pl(denv, 15, bootpri);
+    pl(denv, 16, dostype);
+    rdb_crc(part);
+
+    hfd->size += size;
+    hfd->size2 += size;
+
+}
+
+void hdf_hd_close(struct hd_hardfiledata *hfd)
+{
+    if (!hfd)
+       return;
+    if (hfd->hfd.handle_valid)
+       hdf_close(&hfd->hfd);
+       xfree(hfd->path);
+}
+
+int hdf_hd_open(struct hd_hardfiledata *hfd, char *path, int blocksize, int readonly,
+                      char *devname, int sectors, int surfaces, int reserved,
+                      int bootpri, char *filesys)
+{
+    hfd->bootpri = bootpri;
+    hfd->hfd.blocksize = blocksize;
+    if (!hdf_open(&hfd->hfd, path))
+       return -1;
+    hfd->path = my_strdup(path);
+    hfd->hfd.heads = surfaces;
+    hfd->hfd.reservedblocks = reserved;
+    hfd->hfd.secspertrack = sectors;
+    if (devname)
+       strcpy (hfd->hfd.device_name, devname);
+    getchshd(&hfd->hfd, &hfd->cyls, &hfd->heads, &hfd->secspertrack);
+    hfd->cyls_def = hfd->cyls;
+    hfd->secspertrack_def = hfd->secspertrack;
+    hfd->heads_def = hfd->heads;
+    if (hfd->hfd.heads && hfd->hfd.secspertrack) {
+       uae_u8 buf[512] = { 0 };
+        hdf_read(&hfd->hfd, buf, 0, 512);
+       if (buf[0] != 0 && memcmp(buf, "RDSK", 4)) {
+           hfd->hfd.nrcyls = (hfd->hfd.size / blocksize) / (sectors * surfaces);
+           create_virtual_rdb(&hfd->hfd, rl (buf), hfd->bootpri, filesys);
+           while (hfd->hfd.nrcyls * surfaces * sectors > hfd->cyls_def * hfd->secspertrack_def * hfd->heads_def) {
+               hfd->cyls_def++;
+           }
+       }
+    }
+    hfd->size = hfd->hfd.size;
+    return 1;
+}
+
+static uae_u64 cmd_readx (struct hardfiledata *hfd, uae_u8 *dataptr, uae_u64 offset, uae_u64 len)
+{
+    gui_hd_led (1);
+    hf_log3 ("cmd_read: %p %04.4x-%08.8x (%d) %08.8x (%d)\n",
+       dataptr, (uae_u32)(offset >> 32), (uae_u32)offset, (uae_u32)(offset / hfd->blocksize), (uae_u32)len, (uae_u32)(len / hfd->blocksize));
+    return hdf_read (hfd, dataptr, offset, len);
+}
 static uae_u64 cmd_read (struct hardfiledata *hfd, uaecptr dataptr, uae_u64 offset, uae_u64 len)
 {
     addrbank *bank_data = &get_mem_bank (dataptr);
-    gui_hd_led (1);
-    hf_log2 ("cmd_read: %p %04.4x-%08.8x %08.8x\n", dataptr, (uae_u32)(offset >> 32), (uae_u32)offset, (uae_u32)len);
     if (!bank_data || !bank_data->check (dataptr, len))
        return 0;
-    return hdf_read (hfd, bank_data->xlateaddr (dataptr), offset, len);
+    return cmd_readx (hfd, bank_data->xlateaddr (dataptr), offset, len);
 }
+static uae_u64 cmd_writex (struct hardfiledata *hfd, uae_u8 *dataptr, uae_u64 offset, uae_u64 len)
+{
+    gui_hd_led (2);
+    hf_log3 ("cmd_write: %p %04.4x-%08.8x (%d) %08.8x (%d)\n",
+       dataptr, (uae_u32)(offset >> 32), (uae_u32)offset, (uae_u32)(offset / hfd->blocksize), (uae_u32)len, (uae_u32)(len / hfd->blocksize));
+    return hdf_write (hfd, dataptr, offset, len);
+}
+
 static uae_u64 cmd_write (struct hardfiledata *hfd, uaecptr dataptr, uae_u64 offset, uae_u64 len)
 {
     addrbank *bank_data = &get_mem_bank (dataptr);
-    gui_hd_led (1);
-    hf_log2 ("cmd_write: %p %04.4x-%08.8x %08.8x\n", dataptr, (uae_u32)(offset >> 32), (uae_u32)offset, (uae_u32)len);
     if (!bank_data || !bank_data->check (dataptr, len))
        return 0;
-    return hdf_write (hfd, bank_data->xlateaddr (dataptr), offset, len);
+    return cmd_writex (hfd, bank_data->xlateaddr (dataptr), offset, len);
 }
 
-static int handle_scsi (uaecptr request, struct hardfiledata *hfd)
+int scsi_emulate(struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, uae_u8 *cmdbuf, int scsi_cmd_len,
+               uae_u8 *scsi_data, int *data_len, uae_u8 *r, int *reply_len, uae_u8 *s, int *sense_len)
 {
-    uae_u32 acmd = get_long (request + 40);
-    uaecptr scsi_data = get_long (acmd + 0);
-    uae_u32 scsi_len = get_long (acmd + 4);
-    uaecptr scsi_cmd = get_long (acmd + 12);
-    uae_u16 scsi_cmd_len = get_word (acmd + 16);
-    uae_u8 scsi_flags = get_byte (acmd + 20);
-    uaecptr scsi_sense = get_long (acmd + 22);
-    uae_u16 scsi_sense_len = get_word (acmd + 26);
-    uae_u8 cmd = get_byte (scsi_cmd);
-    uae_u8 cmdbuf[256];
-    int status, ret = 0, lr, ls;
-    uae_u32 i;
-    uae_u8 r[256], s[256];
     uae_u64 len, offset;
+    int lr = 0, ls = 0;
+    int scsi_len = -1;
+    int status = 0;
+    int i;
 
-    scsi_sense_len  = (scsi_flags & 4) ? 4 : /* SCSIF_OLDAUTOSENSE */
-       (scsi_flags & 2) ? scsi_sense_len : /* SCSIF_AUTOSENSE */
-       32;
-    status = 0;
-    memset (r, 0, sizeof (r));
-    lr = 0; ls = 0;
-    scsi_log ("hdf scsiemu: cmd=%02.2X,%d flags=%02.2X sense=%p,%d data=%p,%d\n",
-       cmd, scsi_cmd_len, scsi_flags, scsi_sense, scsi_sense_len, scsi_data, scsi_len);
-    for (i = 0; i < scsi_cmd_len; i++) {
-       cmdbuf[i] = get_byte (scsi_cmd + i);
-       scsi_log ("%02.2X%c", get_byte (scsi_cmd + i), i < scsi_cmd_len - 1 ? '.' : ' ');
-    }
-    scsi_log ("\n");
-
-    switch (cmd)
+    *reply_len = *sense_len = 0;
+    memset(r, 0, 256);
+    memset(s, 0, 256);
+    switch (cmdbuf[0])
     {
        case 0x00: /* TEST UNIT READY */
        break;
@@ -167,7 +365,7 @@ static int handle_scsi (uaecptr request, struct hardfiledata *hfd)
        len = cmdbuf[4];
        if (!len) len = 256;
        len *= hfd->blocksize;
-       scsi_len = (uae_u32)cmd_read (hfd, scsi_data, offset, len);
+       scsi_len = (uae_u32)cmd_readx (hfd, scsi_data, offset, len);
        break;
        case 0x0a: /* WRITE (6) */
        offset = ((cmdbuf[1] & 31) << 16) | (cmdbuf[2] << 8) | cmdbuf[3];
@@ -175,13 +373,18 @@ static int handle_scsi (uaecptr request, struct hardfiledata *hfd)
        len = cmdbuf[4];
        if (!len) len = 256;
        len *= hfd->blocksize;
-       scsi_len = (uae_u32)cmd_write (hfd, scsi_data, offset, len);
+       scsi_len = (uae_u32)cmd_writex (hfd, scsi_data, offset, len);
        break;
        case 0x12: /* INQUIRY */
        len = cmdbuf[4];
        r[2] = 2; /* supports SCSI-2 */
        r[3] = 2; /* response data format */
        r[4] = 32; /* additional length */
+       scsi_len = lr = len < 36 ? (uae_u32)len : 36;
+       if (hdhfd) {
+           r[2] = (hdhfd->iso_version << 6) | (hdhfd->ecma_version << 3) | hdhfd->ansi_version;
+           r[3] = hdhfd->ansi_version >= 2 ? 2 : 0;
+       }
        r[7] = 0x20; /* 16 bit bus */
        i = 0; /* vendor id */
        while (i < 8 && hfd->vendor_id[i]) {
@@ -210,7 +413,37 @@ static int handle_scsi (uaecptr request, struct hardfiledata *hfd)
            r[32 + i] = 32;
            i++;
        }
-       scsi_len = lr = len < 36 ? (uae_u32)len : 36;
+       break;
+       case 0x1a: /* MODE SENSE(6) */
+       {
+           uae_u8 *p;
+           int pc = cmdbuf[2] >> 6;
+           int pcode = cmdbuf[2] & 0x3f;
+           int dbd = cmdbuf[1] & 8;
+           write_log("MODE SENSE PC=%d CODE=%d DBD=%d\n", pc, pcode, dbd);
+           p = r;
+           p[0] = 4 - 1;
+           p[1] = 0;
+           p[2] = 0;
+           p[3] = 0;
+           p += 4;
+           if (pcode == 0) {
+               p[0] = 0;
+               p[1] = 0;
+               p[2] = 0x20;
+               p[3] = 0;
+               r[0] += 4;
+           } else if (pcode == 4) {
+               p[0] = 4;
+               wl(p + 1, hdhfd->cyls);
+               p[1] = 0x16;
+               p[5] = hdhfd->heads;
+               ww(p + 20, 5400);
+               r[0] += p[1];
+           }
+           scsi_len = lr = r[0] + 1;
+           break;
+       }
        break;
        case 0x25: /* READ_CAPACITY */
        wl (r, (uae_u32)(hfd->size / hfd->blocksize - 1));
@@ -222,28 +455,30 @@ static int handle_scsi (uaecptr request, struct hardfiledata *hfd)
        offset *= hfd->blocksize;
        len = rl (cmdbuf + 7 - 2) & 0xffff;
        len *= hfd->blocksize;
-       scsi_len = (uae_u32)cmd_read (hfd, scsi_data, offset, len);
+       scsi_len = (uae_u32)cmd_readx (hfd, scsi_data, offset, len);
        break;
        case 0x2a: /* WRITE (10) */
        offset = rl (cmdbuf + 2);
        offset *= hfd->blocksize;
        len = rl (cmdbuf + 7 - 2) & 0xffff;
        len *= hfd->blocksize;
-       scsi_len = (uae_u32)cmd_write (hfd, scsi_data, offset, len);
+       scsi_len = (uae_u32)cmd_writex (hfd, scsi_data, offset, len);
+       break;
+       case 0x35: /* SYNCRONIZE CACHE (10) */
        break;
        case 0xa8: /* READ (12) */
        offset = rl (cmdbuf + 2);
        offset *= hfd->blocksize;
        len = rl (cmdbuf + 6);
        len *= hfd->blocksize;
-       scsi_len = (uae_u32)cmd_read (hfd, scsi_data, offset, len);
+       scsi_len = (uae_u32)cmd_readx (hfd, scsi_data, offset, len);
        break;
        case 0xaa: /* WRITE (12) */
        offset = rl (cmdbuf + 2);
        offset *= hfd->blocksize;
        len = rl (cmdbuf + 6);
        len *= hfd->blocksize;
-       scsi_len = (uae_u32)cmd_write (hfd, scsi_data, offset, len);
+       scsi_len = (uae_u32)cmd_writex (hfd, scsi_data, offset, len);
        break;
        case 0x37: /* READ DEFECT DATA */
        write_log ("UAEHF: READ DEFECT DATA\n");
@@ -255,7 +490,7 @@ static int handle_scsi (uaecptr request, struct hardfiledata *hfd)
        break;
        default:
         lr = -1;
-       write_log ("UAEHF: unsupported scsi command 0x%02.2X\n", cmd);
+       write_log ("UAEHF: unsupported scsi command 0x%02.2X\n", cmdbuf[0]);
        status = 2; /* CHECK CONDITION */
        s[0] = 0x70;
        s[2] = 5; /* ILLEGAL REQUEST */
@@ -263,23 +498,65 @@ static int handle_scsi (uaecptr request, struct hardfiledata *hfd)
        ls = 12;
        break;
     }
+    *data_len = scsi_len;
+    *reply_len = lr;
+    *sense_len = ls;
+    return status;
+}
+
+static int handle_scsi (uaecptr request, struct hardfiledata *hfd)
+{
+    uae_u32 acmd = get_long (request + 40);
+    uaecptr scsi_data = get_long (acmd + 0);
+    uae_u32 scsi_len = get_long (acmd + 4);
+    uaecptr scsi_cmd = get_long (acmd + 12);
+    uae_u16 scsi_cmd_len = get_word (acmd + 16);
+    uae_u8 scsi_flags = get_byte (acmd + 20);
+    uaecptr scsi_sense = get_long (acmd + 22);
+    uae_u16 scsi_sense_len = get_word (acmd + 26);
+    uae_u8 cmd = get_byte (scsi_cmd);
+    uae_u8 cmdbuf[256];
+    int status, ret = 0, reply_len, sense_len;
+    uae_u32 i;
+    uae_u8 reply[256], sense[256];
+    uae_u8 *scsi_data_ptr = NULL;
+    addrbank *bank_data = &get_mem_bank (scsi_data);
+
+    if (bank_data  && bank_data->check (scsi_data, scsi_len))
+       scsi_data_ptr = bank_data->xlateaddr (scsi_data);
+    scsi_sense_len  = (scsi_flags & 4) ? 4 : /* SCSIF_OLDAUTOSENSE */
+       (scsi_flags & 2) ? scsi_sense_len : /* SCSIF_AUTOSENSE */
+       32;
+    status = 0;
+    memset (reply, 0, sizeof reply);
+    reply_len = 0; sense_len = 0;
+    scsi_log ("hdf scsiemu: cmd=%02.2X,%d flags=%02.2X sense=%p,%d data=%p,%d\n",
+       cmd, scsi_cmd_len, scsi_flags, scsi_sense, scsi_sense_len, scsi_data, scsi_len);
+    for (i = 0; i < scsi_cmd_len; i++) {
+       cmdbuf[i] = get_byte (scsi_cmd + i);
+       scsi_log ("%02.2X%c", get_byte (scsi_cmd + i), i < scsi_cmd_len - 1 ? '.' : ' ');
+    }
+    scsi_log ("\n");
+
+    status = scsi_emulate(hfd, NULL, cmdbuf, scsi_cmd_len, scsi_data_ptr, &scsi_len, reply, &reply_len, sense, &sense_len);
+
     put_word (acmd + 18, status != 0 ? 0 : scsi_cmd_len); /* fake scsi_CmdActual */
     put_byte (acmd + 21, status); /* scsi_Status */
-    if (lr > 0) {
+    if (reply_len > 0) {
        scsi_log ("RD:");
        i = 0;
-       while (i < lr && i < scsi_len) {
+       while (i < reply_len) {
            if (i < 24)
-               scsi_log ("%02.2X%c", r[i], i < scsi_len - 1 ? '.' : ' ');
-           put_byte (scsi_data + i, r[i]);
+               scsi_log ("%02.2X%c", reply[i], i < reply_len - 1 ? '.' : ' ');
+           put_byte (scsi_data + i, reply[i]);
            i++;
        }
        scsi_log ("\n");
     }
     i = 0;
-    if (ls > 0 && scsi_sense) {
-       while (i < ls && i < scsi_sense_len) {
-           put_byte (scsi_sense + i, s[i]);
+    if (scsi_sense) {
+       while (i < sense_len && i < scsi_sense_len) {
+           put_byte (scsi_sense + i, sense[i]);
            i++;
        }
     }
@@ -287,7 +564,7 @@ static int handle_scsi (uaecptr request, struct hardfiledata *hfd)
        put_byte (scsi_sense + i, 0);
        i++;
     }
-    if (lr < 0) {
+    if (scsi_len < 0) {
        put_long (acmd + 8, 0); /* scsi_Actual */
        ret = 20;
     } else {
index cddf3b7c587ce966ed3fe6ede3191f026db98118..186cf26c23d1d12f4f50fc5a5ddef97fbf7bca50 100755 (executable)
@@ -6,10 +6,33 @@ extern void a2091_init (void);
 extern void a2091_free (void);
 extern void a2091_reset (void);
 
+extern void a3000scsi_init (void);
+extern void a3000scsi_free (void);
+extern void a3000scsi_reset (void);
 extern void rethink_a2091 (void);
 
 extern void wdscsi_put(uae_u8);
 extern uae_u8 wdscsi_get(void);
 extern uae_u8 wdscsi_getauxstatus(void);
 extern void wdscsi_sasr(uae_u8);
+
+extern void scsi_hsync(void);
+
+extern uae_u8 wdregs[32];
+extern struct scsi_data *scsis[8];
+
+#define WD33C93 "WD33C93"
+#define SCSIID (scsis[wdregs[WD_DESTINATION_ID]])
+
+extern int a2091_add_scsi_unit(int ch, char *path, int blocksize, int readonly,
+                      char *devname, int sectors, int surfaces, int reserved,
+                      int bootpri, char *filesys);
+extern int a3000_add_scsi_unit(int ch, char *path, int blocksize, int readonly,
+                      char *devname, int sectors, int surfaces, int reserved,
+                      int bootpri, char *filesys);
+
+extern int addscsi(int ch, char *path, int blocksize, int readonly,
+                      char *devname, int sectors, int surfaces, int reserved,
+                      int bootpri, char *filesys);
+
 #endif
index e44df5c08bb7e23e7bb6bdd40a22cc1b43a08863..23d1fa083c0f935bc11f70c565d2a333e5d67cb7 100755 (executable)
@@ -16,5 +16,11 @@ uae_u8 cdtv_battram_read (int addr);
 extern void cdtv_loadcardmem(uae_u8*, int);
 extern void cdtv_savecardmem(uae_u8*, int);
 
+int cdtv_add_scsi_unit(int ch, char *path, int blocksize, int readonly,
+                      char *devname, int sectors, int surfaces, int reserved,
+                      int bootpri, char *filesys);
+
+extern void cdtv_getdmadata(int *);
+
 #endif
 
index fa6b1f6b3cf02823340b95c4625e3478854f03e1..686a082765579e8262ebb5899b3bba64eada374c 100755 (executable)
@@ -36,6 +36,33 @@ struct hardfiledata {
     uae_u64 virtual_size;
 };
 
+struct hd_hardfiledata {
+    struct hardfiledata hfd;
+    int bootpri;
+    uae_u64 size;
+    int cyls;
+    int heads;
+    int secspertrack;
+    int cyls_def;
+    int secspertrack_def;
+    int heads_def;
+    char *path;
+    int iso_version, ecma_version, ansi_version;
+};
+
+#define HD_CONTROLLER_UAE 0
+#define HD_CONTROLLER_IDE0 1
+#define HD_CONTROLLER_IDE1 2
+#define HD_CONTROLLER_IDE2 3
+#define HD_CONTROLLER_IDE3 4
+#define HD_CONTROLLER_SCSI0 5
+#define HD_CONTROLLER_SCSI1 6
+#define HD_CONTROLLER_SCSI2 7
+#define HD_CONTROLLER_SCSI3 8
+#define HD_CONTROLLER_SCSI4 9
+#define HD_CONTROLLER_SCSI5 10
+#define HD_CONTROLLER_SCSI6 11
+
 #define FILESYS_VIRTUAL 0
 #define FILESYS_HARDFILE 1
 #define FILESYS_HARDFILE_RDB 2
@@ -58,3 +85,8 @@ extern char *hdf_getnameharddrive (int index, int flags);
 extern int hdf_init (void);
 extern int isspecialdrive(const char *name);
 extern int get_native_path(uae_u32 lock, char *out);
+
+void hdf_hd_close(struct hd_hardfiledata *hfd);
+int hdf_hd_open(struct hd_hardfiledata *hfd, char *path, int blocksize, int readonly,
+                      char *devname, int sectors, int surfaces, int reserved,
+                      int bootpri, char *filesys);
index c4a68a9b9ca10db61eb5d364f93024f46d44785b..eb4d5f18a261f4d640722aaec06ae254389db3a5 100755 (executable)
@@ -113,7 +113,6 @@ extern addrbank gayle2_bank;
 extern addrbank gayle_attr_bank;
 extern addrbank mbres_bank;
 extern addrbank akiko_bank;
-extern addrbank mbdmac_a3000_bank;
 extern addrbank cardmem_bank;
 
 extern void rtarea_init (void);
@@ -332,10 +331,13 @@ extern void init_shm(void);
 #define ROMTYPE_KICKCD32 2
 #define ROMTYPE_EXTCD32 4
 #define ROMTYPE_EXTCDTV 8
-#define ROMTYPE_AR 16
-#define ROMTYPE_KEY 32
-#define ROMTYPE_ARCADIABIOS 64
-#define ROMTYPE_ARCADIAGAME 128
+#define ROMTYPE_A2091BOOT 16
+#define ROMTYPE_A4091BOOT 32
+#define ROMTYPE_AR 64
+#define ROMTYPE_SUPERIV 128
+#define ROMTYPE_KEY 256
+#define ROMTYPE_ARCADIABIOS 512
+#define ROMTYPE_ARCADIAGAME 1024
 
 struct romdata {
     char *name;
@@ -364,6 +366,7 @@ extern struct romdata *getarcadiarombyname (char *name);
 extern struct romlist **getrombyident(int ver, int rev, int subver, int subrev, char *model, int all);
 extern void getromname (struct romdata*, char*);
 extern struct romdata *getromdatabyname (char*);
+extern struct romlist *getrombyids(int *ids);
 extern void romlist_add (char *path, struct romdata *rd);
 extern char *romlist_get (struct romdata *rd);
 extern void romlist_clear (void);
index 043e08bf1db52d7bb9f8caf42a0c00e6cf0f6066..ff08885da4f93148bcb7f839a7bafeeee2805137 100755 (executable)
@@ -57,6 +57,6 @@ extern smp_comm_pipe native2amiga_pending;
 
 STATIC_INLINE void do_uae_int_requested (void)
 {
-    uae_int_requested = 1;
+    uae_int_requested |= 1;
     set_uae_int_flag ();
 }
diff --git a/include/scsi.h b/include/scsi.h
new file mode 100755 (executable)
index 0000000..db81a08
--- /dev/null
@@ -0,0 +1,33 @@
+
+struct scsi_data
+{
+    int len;
+    uae_u8 *data;
+    int data_len;
+    int status;
+    uae_u8 sense[256];
+    int sense_len;
+    uae_u8 reply[256];
+    uae_u8 cmd[16];
+    int reply_len;
+    int direction;
+
+    int offset;
+    uae_u8 buffer[256 * 512];
+    struct hd_hardfiledata *hfd;
+};
+
+extern struct scsi_data *scsi_alloc(struct hd_hardfiledata*);
+extern void scsi_free(struct scsi_data*);
+
+extern void scsi_start_transfer(struct scsi_data*,int);
+extern int scsi_send_data(struct scsi_data*, uae_u8);
+extern int scsi_receive_data(struct scsi_data*, uae_u8*);
+extern void scsi_emulate_cmd(struct scsi_data *sd);
+extern int scsi_data_dir(struct scsi_data *sd);
+
+
+extern int scsi_emulate(struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, uae_u8 *cmdbuf, int scsi_cmd_len,
+               uae_u8 *scsi_data, int *data_len, uae_u8 *r, int *reply_len, uae_u8 *s, int *sense_len);
+
+
index e6ec4e8855c81a2644fbd2b8a758738b41a54c36..e5a6c7f7a496dd13c56aade6b6f6d47f2ecf31e5 100755 (executable)
--- a/memory.c
+++ b/memory.c
@@ -26,6 +26,7 @@
 #include "akiko.h"
 #include "arcadia.h"
 #include "enforcer.h"
+#include "a2091.h"
 
 int canbang;
 #ifdef JIT
@@ -97,6 +98,7 @@ static struct romdata roms[] = {
     { "KS ROM v1.2 (A500,A1000,A2000)", 1, 2, 33, 180, "A500\0A1000\0A2000\0", 0xa6ce1636, 262144, 5, 0, 0, ROMTYPE_KICK },
     { "KS ROM v1.3 (A500,A1000,A2000)", 1, 3, 34, 5, "A500\0A1000\0A2000\0", 0xc4f0f55f, 262144, 6, 0, 0, ROMTYPE_KICK },
     { "KS ROM v1.3 (A3000)", 1, 3, 34, 5, "A3000\0", 0xe0f37258, 262144, 32, 0, 0, ROMTYPE_KICK },
+    { "KS ROM v1.4b (A3000)", 1, 4, 36, 16, "A3000\0", 0xbc0ec13f, 524288, 59, 0, 0, ROMTYPE_KICK },
 
     { "KS ROM v2.04 (A500+)", 2, 4, 37, 175, "A500+\0", 0xc3bdb240, 524288, 7, 0, 0, ROMTYPE_KICK },
     { "KS ROM v2.05 (A600)", 2, 5, 37, 299, "A600\0", 0x83028fb5, 524288, 8, 0, 0, ROMTYPE_KICK },
@@ -131,6 +133,14 @@ static struct romdata roms[] = {
     { "Action Replay Mk III v3.09", 3, 9, 3, 9, "AR\0", 0x0ed9b5aa, 262144, 29, 0, 0, ROMTYPE_AR },
     { "Action Replay Mk III v3.17", 3, 17, 3, 17, "AR\0", 0xc8a16406, 262144, 30, 0, 0, ROMTYPE_AR },
     { "Action Replay 1200", 0, 0, 0, 0, "AR\0", 0x8d760101, 262144, 47, 0, 0, ROMTYPE_AR },
+    { "Action Cartridge Super IV Pro", 4, 3, 4, 3, "SUPERIV\0", 0xe668a0be, 170368, 60, 0, 0, ROMTYPE_SUPERIV },
+
+    { "A590/A2091 Boot ROM", 6, 0, 6, 0, "A2091BOOT\0", 0x8396cf4e, 16384, 53, 0, 0, ROMTYPE_A2091BOOT },
+    { "A590/A2091 Boot ROM", 6, 6, 6, 6, "A2091BOOT\0", 0x33e00a7a, 16384, 54, 0, 0, ROMTYPE_A2091BOOT },
+    { "A590/A2091 Boot ROM", 7, 0, 7, 0, "A2091BOOT\0", 0x714a97a2, 16384, 55, 0, 0, ROMTYPE_A2091BOOT },
+    { "A590/A2091 Guru Boot ROM", 6, 14, 6, 14, "A2091BOOT\0", 0x04e52f93, 32768, 56, 0, 0, ROMTYPE_A2091BOOT },
+    { "A4091 Boot ROM", 40, 9, 40, 9, "A4091BOOT\0", 0x00000000, 32768, 57, 0, 0, ROMTYPE_A4091BOOT },
+    { "A4091 Boot ROM", 40, 13, 40, 13, "A4091BOOT\0", 0x54cb9e85, 32768, 58, 0, 0, ROMTYPE_A4091BOOT },
 
     { "Arcadia OnePlay 2.11", 0, 0, 0, 0, "ARCADIA\0", 0, 0, 49, 0, 0, ROMTYPE_ARCADIABIOS },
     { "Arcadia TenPlay 2.11", 0, 0, 0, 0, "ARCADIA\0", 0, 0, 50, 0, 0, ROMTYPE_ARCADIABIOS },
@@ -581,6 +591,25 @@ void getromname    (struct romdata *rd, char *name)
        sprintf (name + strlen (name), " (%dk)", (rd->size + 1023) / 1024);
 }
 
+struct romlist *getrombyids(int *ids)
+{
+    struct romdata *rd;
+    int i, j;
+
+    i = 0;
+    while (ids[i] >= 0) {
+       rd = getromdatabyid (ids[i]);
+       if (rd) {
+           for (j = 0; j < romlist_cnt; j++) {
+               if (rl[j].rd == rd)
+                   return &rl[j];
+           }
+       }
+       i++;
+    }
+    return NULL;
+}
+
 addrbank *mem_banks[MEMORY_BANKS];
 
 /* This has two functions. It either holds a host address that, when added
@@ -1805,6 +1834,8 @@ static int patch_residents (uae_u8 *kickmemory, int size)
     // "scsi.device", "carddisk.device", "card.resource" };
     uaecptr base = size == 524288 ? 0xf80000 : 0xfc0000;
 
+    if (currprefs.cs_mbdmac == 2)
+       residents[0] = NULL;
     for (i = 0; i < size - 100; i++) {
        if (kickmemory[i] == 0x4a && kickmemory[i + 1] == 0xfc) {
            uaecptr addr;
@@ -2340,7 +2371,8 @@ void memory_reset (void)
     if (currprefs.cs_cd32c2p || currprefs.cs_cd32cd || currprefs.cs_cd32nvram)
        map_banks (&akiko_bank, AKIKO_BASE >> 16, 1, 0);
     if (currprefs.cs_mbdmac == 1)
-       map_banks (&mbdmac_a3000_bank, 0xDD, 1, 0);
+       a3000scsi_reset();
+
     if (a3000lmemory != 0)
         map_banks (&a3000lmem_bank, a3000lmem_start >> 16, allocated_a3000lmem >> 16, 0);
     if (a3000hmemory != 0)
index f319cec07992c4b2ea547da8517dc2f9d6357f5c..c54d23c5da454d728a676c01861860fa16132fbd 100755 (executable)
@@ -143,6 +143,9 @@ void ncr_bput2(uaecptr addr, uae_u32 val)
        return;
     switch (addr)
     {
+       case 0x08:
+       ncrregs[0x22] |= 2;
+       break;
        case 0x02: // SCNTL1
        break;
        case 0x22 : // ISTAT
@@ -164,11 +167,14 @@ uae_u32 ncr_bget2(uaecptr addr)
     v = ncrregs[addr];
     switch (addr)
     {
+       case 0x0c: // SSTAT2
+       v &= ~7;
+       v |= ncrregs[8] & 7;
+       break;
+       case 0x0e: // SSTAT0
+       v |= 0x20;
+       break;
         case 0x22: // ISTAT
-       if (ncrregs[0x02] & 0x08)
-           v |= 0x02; // SIP
-       if (ncrregs[0x07]) // have ID?
-           v |= 0x08; // CONNECTED
        ncrregs[addr] &= 0x40;
        break;
        case 0x21: // CTEST8
@@ -275,7 +281,7 @@ static void REGPARAM2 ncr_bput (uaecptr addr, uae_u32 b)
        return;
     }
     if (addr == 0x4c) {
-       write_log ("A4091 DMAC AUTOCONFIG SHUT-UP!\n");
+       write_log ("A4091 AUTOCONFIG SHUT-UP!\n");
        configured = 1;
        expamem_next();
        return;
@@ -338,7 +344,8 @@ void ncr_reset (void)
 void ncr_init (void)
 {
     struct zfile *z;
-    char path[MAX_DPATH];
+    int roms[3];
+    struct romlist *rl;
 
     configured = 0;
     memset (acmemory, 0xff, 100);
@@ -351,15 +358,22 @@ void ncr_init (void)
     /* rom vector */
     ew (0x28, ROM_VECTOR >> 8);
     ew (0x2c, ROM_VECTOR);
-    if (!rom) {
-       fetch_datapath (path, sizeof path);
-       strcat (path, "roms\\a4091.rom");
-       write_log("A4091 ROM path: '%s'\n", path);
-       z = zfile_fopen(path, "rb");
+
+    roms[0] = 57;
+    roms[1] = 56;
+    roms[2] = -1;
+
+    rl = getrombyids(roms);
+    if (rl) {
+       write_log("A4091 BOOT ROM '%s' %d.%d ", rl->path, rl->rd->ver, rl->rd->rev);
+       z = zfile_fopen(rl->path, "rb");
        if (z) {
+           write_log("loaded\n");
            rom = xmalloc (ROM_SIZE);
            zfile_fread (rom, ROM_SIZE, 1, z);
            zfile_fclose(z);
+       } else {
+           write_log("failed to load\n");
        }
     }
     map_banks (&ncr_bank, 0xe80000 >> 16, 0x10000 >> 16, 0x10000);
index eb37259c28026561dd9b2dc705027912cff629ff..853869e73f13875ec730b275f14dafc5f9299363 100755 (executable)
--- a/newcpu.c
+++ b/newcpu.c
@@ -1116,8 +1116,9 @@ void REGPARAM2 Exception (int nr, struct regstruct *regs, uaecptr oldpc)
 STATIC_INLINE void do_interrupt(int nr, struct regstruct *regs)
 {
 #if 0
-    if (nr == 4)
-       write_log("irq %d at %x (%04.4X)\n", nr, m68k_getpc(), intena & intreq);
+    if (nr == 2)
+       write_log(".");
+       //write_log("irq %d at %x (%04.4X) ", nr, m68k_getpc(regs), intena & intreq);
 #endif
     regs->stopped = 0;
     unset_special (regs, SPCFLAG_STOP);
index 9b66c732c999ff1a7e63ca035ea1e40cc2d9af92..873d2763e8e13428ff69b387dc34276250222d0d 100755 (executable)
@@ -314,6 +314,10 @@ void *shmat(int shmid, void *shmaddr, int shmflg)
            shmaddr=natmem_offset + 0x00b00000;
            got = TRUE;
        }
+       if(!strcmp(shmids[shmid].name,"superiv_3")) {
+           shmaddr=natmem_offset + 0x00e00000;
+           got = TRUE;
+       }
 }
 #endif
     
index 7bc3a3888620b881f27d291a67a0c38108783e99..6451ef805e4ba6dedc62727e87acff4cabebb863 100755 (executable)
 #define IDS_SCREEN_WINDOWED             195
 #define IDS_SCREEN_FULLSCREEN           196
 #define IDS_SCREEN_FULLWINDOW           197
-#define IDS_SCREEN_FULLSCREENVSYNC      198
+#define IDS_SCREEN_VSYNC                198
 #define IDS_SOUND_MONO                  200
 #define IDS_SOUND_MIXED                 201
 #define IDI_QUICKSTART                  201
 #define IDS_FLOPPYTYPE35DDESCOM         255
 #define IDS_SOUND_STEREO2               256
 #define IDS_INPUT_CUSTOMEVENT           257
+#define IDS_DEFAULT_NEWWINUAE           258
 #define IDS_NUMSG_NEEDEXT2              300
 #define IDS_NUMSG_NOROMKEY              301
 #define IDS_NUMSG_KSROMCRCERROR         302
 #define IDC_BLIT32                      1173
 #define IDC_BLITIMM                     1174
 #define IDC_LORES                       1176
-#define IDC_VSYNC                       1177
 #define IDC_LORES_SMOOTHED              1179
 #define IDC_FRAMERATE                   1185
 #define IDC_RATETEXT                    1186
 #define IDC_HDF_CONTROLLER              1504
 #define IDC_RESETAMIGA                  1504
 #define IDC_QUITEMU                     1505
-#define IDC_TEST16BIT                   1506
 #define IDC_MAPDRIVES                   1507
 #define IDC_CPUTEXT                     1508
 #define IDC_MAPDRIVES_NET               1508
 #define IDC_CS_A2091                    1768
 #define IDC_CS_DMAC2                    1769
 #define IDC_CS_A4091                    1770
+#define IDC_CS_CDTVSCSI                 1771
 #define ID__FLOPPYDRIVES                40004
 #define ID_FLOPPYDRIVES_DF0             40005
 #define ID_ST_CONFIGURATION             40010
index db641e508e057d0d98c7d472c422be16512104e1..fe40a84c253f6616b986c73961f7fda8dfaa4db9 100755 (executable)
 #define IDC_CS_A2091                    1768
 #define IDC_CS_DMAC2                    1769
 #define IDC_CS_A4091                    1770
-
+#define IDC_CS_CDTVSCSI                 1771
 #define ID__FLOPPYDRIVES                40004
 #define ID_FLOPPYDRIVES_DF0             40005
 #define ID_ST_CONFIGURATION             40010
 #define _APS_3D_CONTROLS                     1
 #define _APS_NEXT_RESOURCE_VALUE        253
 #define _APS_NEXT_COMMAND_VALUE         40029
-#define _APS_NEXT_CONTROL_VALUE         1771
+#define _APS_NEXT_CONTROL_VALUE         1772
 #define _APS_NEXT_SYMED_VALUE           101
 #endif
 #endif
index fd732573562d1e612b4a65362980c3d64b295d33..ca91ebb8152bb619bbd2e3c06e0a17a6c5672bad 100755 (executable)
@@ -574,9 +574,10 @@ BEGIN
     EDITTEXT        IDC_CS_DENISEREV,235,226,45,13,ES_AUTOHSCROLL\r
     CONTROL         "A590/A2091 SCSI",IDC_CS_A2091,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,175,76,10\r
     CONTROL         "A4000T SCSI",IDC_CS_DMAC2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,193,175,88,10\r
-    LTEXT           "SCSI not yet implemented.",IDC_STATIC,25,161,224,8,SS_CENTERIMAGE\r
+    LTEXT           "A4000/A4000T SCSI not yet implemented.",IDC_STATIC,25,161,224,8,SS_CENTERIMAGE\r
     CONTROL         "PCMCIA",IDC_CS_PCMCIA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,193,146,92,10\r
     CONTROL         "A4091 SCSI",IDC_CS_A4091,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,187,76,10\r
+    CONTROL         "CDTV SCSI",IDC_CS_CDTVSCSI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,100,187,76,10\r
 END\r
 \r
 IDD_AVIOUTPUT DIALOGEX 0, 0, 288, 203\r
index 825e9a125112d726514cfe3df36b508732605ba8..7c81ed3588d610fc29a624eadd27b92a9052ffd2 100755 (executable)
@@ -15,9 +15,9 @@
 #define GETBDM(x) (((x) - ((x / 10000) * 10000)) / 100)
 #define GETBDD(x) ((x) % 100)
 
-#define WINUAEBETA 1
+#define WINUAEBETA 2
 #define WINUAEPUBLICBETA 1
-#define WINUAEDATE MAKEBD(2007, 5, 17)
+#define WINUAEDATE MAKEBD(2007, 5, 20)
 #define WINUAEEXTRA ""
 #define WINUAEREV ""
 
index 4003789d2661092c50ac8c70a1c9e4c52220befe..3de607ab9929cf629b4c664e6127430f45996a55 100755 (executable)
@@ -534,16 +534,31 @@ static int listrom (int *roms)
 static void show_rom_list (void)
 {
     char *p;
-    int roms[6], ok;
-    char unavail[MAX_DPATH], avail[MAX_DPATH], tmp1[MAX_DPATH];
+    char unavail[MAX_DPATH], avail[MAX_DPATH];
     char *p1, *p2;
-    
+    int *rp;
+    int romtable[] = {
+       5, 4, -1, -1, // A500 1.2
+       6, 32, -1, -1, // A500 1.3
+       7, -1, -1, // A500+
+       8, 9, 10, -1, -1, // A600
+       23, 24, -1, -1, // A1000
+       11, 31, 15, -1, -1, // A1200
+       32, 58, -1, -1, // A3000
+       53, 54, 55, -1, -1, // A2091
+       56, 57, -1, -1, // A4091
+       18, -1, 19, -1, -1, // CD32
+       20, 21, 22, -1, 6, 32, -1, -1, // CDTV
+       49, 50, 51, -1, 5, 4, -1, -1, // ARCADIA
+       46, -1, -1, // highend
+       0, 0, 0
+    };
+
     WIN32GUI_LoadUIString (IDS_ROM_AVAILABLE, avail, sizeof (avail));
     WIN32GUI_LoadUIString (IDS_ROM_UNAVAILABLE, unavail, sizeof (avail));
     strcat (avail, "\n");
     strcat (unavail, "\n");
-    WIN32GUI_LoadUIString (IDS_QS_MODELS, tmp1, sizeof (tmp1));
-    p1 = tmp1;
+    p1 = "A500 Boot ROM 1.2\0A500 Boot ROM 1.3\0A500+\0A600\0A1000\0A1200\0A3000\0A590/A2091 SCSI Boot ROM\0A4091 SCSI Boot ROM\0CD32\0CDTV\0Arcadia Multi Select\0High end WinUAE\0\0";
     
     p = malloc (100000);
     if (!p)
@@ -551,104 +566,29 @@ static void show_rom_list (void)
     WIN32GUI_LoadUIString (IDS_ROMSCANEND, p, 100);
     strcat (p, "\n\n");
 
-    /* A500 */
-    p2 = strchr (p1, '\n');
-    if (!p2)
-       goto end;
-    *p2++= 0; strcat (p, p1); strcat (p, " Boot ROM v1.2:");
-    roms[0] = 5; roms[1] = 4; roms[2] = -1;
-    if (listrom (roms)) strcat (p, avail); else strcat (p, unavail);
-    strcat (p, p1); strcat (p, " Boot ROM v1.3:");
-    roms[0] = 6; roms[1] = 32; roms[2] = -1;
-    if (listrom (roms)) strcat (p, avail); else strcat (p, unavail);
-    p1 = p2;
-   
-    /* A500+ */
-    p2 = strchr (p1, '\n');
-    if (!p2)
-       goto end;
-    *p2++= 0; strcat (p, p1); strcat (p, ": ");
-    roms[0] = 7; roms[1] = -1;
-    if (listrom (roms)) strcat (p, avail); else strcat (p, unavail);
-    p1 = p2;
-
-    /* A600 */
-    p2 = strchr (p1, '\n');
-    if (!p2)
-       goto end;
-    *p2++= 0; strcat (p, p1); strcat (p, ": ");
-    roms[0] = 8; roms[1] = 9; roms[2] = 10; roms[3] = -1;
-    if (listrom (roms)) strcat (p, avail); else strcat (p, unavail);
-    p1 = p2;
-
-    /* A1000 */
-    p2 = strchr (p1, '\n');
-    if (!p2)
-       goto end;
-    *p2++= 0; strcat (p, p1); strcat (p, ": ");
-    roms[0] = 23; roms[1] = 24; roms[2] = -1;
-    if (listrom (roms)) strcat (p, avail); else strcat (p, unavail);
-    p1 = p2;
-
-    /* A1200 */
-    p2 = strchr (p1, '\n');
-    if (!p2)
-       goto end;
-    *p2++= 0; strcat (p, p1); strcat (p, ": ");
-    roms[0] = 11; roms[1] = 31; roms[2] = 15; roms[3] = -1;
-    if (listrom (roms)) strcat (p, avail); else strcat (p, unavail);
-    p1 = p2;
-
-    /* CD32 */
-    ok = 0;
-    p2 = strchr (p1, '\n');
-    if (!p2)
-       goto end;
-    *p2++= 0; strcat (p, p1); strcat (p, ": ");
-    roms[0] = 18; roms[1] = -1;
-    if (listrom (roms)) {
-       roms[0] = 19;
-       if (listrom (roms))
-           ok = 1;
-    }
-    if (ok) strcat (p, avail); else strcat (p, unavail);
-    p1 = p2;
-
-    /* CDTV */
-    ok = 0;
-    p2 = strchr (p1, '\n');
-    if (!p2)
-       goto end;
-    *p2++= 0; strcat (p, p1); strcat (p, ": ");
-    roms[0] = 20; roms[1] = 21; roms[2] = 22; roms[3] = -1;
-    if (listrom (roms)) {
-       roms[0] = 6; roms[1] = 32; roms[2] = -1;
-       if (listrom (roms))
-           ok = 1;
-    }
-    if (ok) strcat (p, avail); else strcat (p, unavail);
-    p1 = p2;
-
-    /* Arcadia */
-    ok = 0;
-    p2 = strchr (p1, '\n');
-    if (!p2)
-       goto end;
-    *p2++= 0;
-    roms[0] = 49; roms[1] = 50; roms[2] = 51; roms[3] = -1;
-    if (listrom (roms)) {
-       roms[0] = 5; roms[1] = 4; roms[2] = -1;
-       if (listrom (roms))
-           ok = 1;
-    }
-    if (ok) {
+    rp = romtable;
+    while(rp[0]) {
+       int ok = 0;
+       p2 = p1 + strlen(p1) + 1;
+       strcat (p, " ");
        strcat (p, p1); strcat (p, ": ");
-       strcat (p, avail);
+       if (listrom (rp))
+           ok = 1;
+        while(*rp++ != -1)
+        rp++;
+        if (*rp != -1) {
+           ok = 0;
+           if (listrom (rp))
+               ok = 1;
+           while(*rp++ != -1);
+               rp++;
+       }
+       if (ok)
+           strcat (p, avail); else strcat (p, unavail);
+       p1 = p2;
     }
-    p1 = p2;
 
     pre_gui_message (p);
-end:
     free (p);
 }
 
@@ -1981,9 +1921,14 @@ void InitializeListView (HWND hDlg)
            else
                sprintf (size_str, "%.1fM", ((double)(uae_u32)(mi.size / (1024))) / 1024.0);
 
-           if (uci->controller) {
+           if (uci->controller >= HD_CONTROLLER_IDE0 && uci->controller <= HD_CONTROLLER_IDE3) {
+               sprintf (blocksize_str, "%d", uci->blocksize);
+               sprintf (devname_str, "*IDE%d*", uci->controller - HD_CONTROLLER_IDE0);
+               strcpy (volname_str, "n/a");
+               strcpy (bootpri_str, "n/a");
+           } else if (uci->controller >= HD_CONTROLLER_SCSI0 && uci->controller <= HD_CONTROLLER_SCSI6) {
                sprintf (blocksize_str, "%d", uci->blocksize);
-               sprintf (devname_str, "*IDE%d*", uci->controller - 1);
+               sprintf (devname_str, "*SCSI%d*", uci->controller - HD_CONTROLLER_SCSI0);
                strcpy (volname_str, "n/a");
                strcpy (bootpri_str, "n/a");
            } else if (type == FILESYS_HARDFILE) {
@@ -4214,6 +4159,7 @@ static void values_to_chipsetdlg2 (HWND hDlg)
     CheckDlgButton (hDlg, IDC_CS_DMAC2, workprefs.cs_mbdmac == 2);
     CheckDlgButton (hDlg, IDC_CS_A2091, workprefs.cs_a2091 > 0);
     CheckDlgButton (hDlg, IDC_CS_A4091, workprefs.cs_a4091 > 0);
+    CheckDlgButton (hDlg, IDC_CS_CDTVSCSI, workprefs.cs_cdtvscsi > 0);
     CheckDlgButton (hDlg, IDC_CS_PCMCIA, workprefs.cs_pcmcia > 0);
     CheckDlgButton (hDlg, IDC_CS_IDE1, workprefs.cs_ide > 0 && (workprefs.cs_ide & 1));
     CheckDlgButton (hDlg, IDC_CS_IDE2, workprefs.cs_ide > 0 && (workprefs.cs_ide & 2));
@@ -4280,6 +4226,7 @@ static void values_from_chipsetdlg2 (HWND hDlg, UINT msg, WPARAM wParam, LPARAM
        workprefs.cs_mbdmac = IsDlgButtonChecked (hDlg, IDC_CS_DMAC2) ? 2 : 0;
     workprefs.cs_a2091 = IsDlgButtonChecked (hDlg, IDC_CS_A2091) ? 1 : 0;
     workprefs.cs_a4091 = IsDlgButtonChecked (hDlg, IDC_CS_A4091) ? 1 : 0;
+    workprefs.cs_cdtvscsi = IsDlgButtonChecked (hDlg, IDC_CS_CDTVSCSI) ? 1 : 0;
     workprefs.cs_pcmcia = IsDlgButtonChecked (hDlg, IDC_CS_PCMCIA) ? 1 : 0;
     workprefs.cs_ide = IsDlgButtonChecked (hDlg, IDC_CS_IDE1) ? 1 : (IsDlgButtonChecked (hDlg, IDC_CS_IDE2) ? 2 : 0);
     workprefs.cs_ciaatod = IsDlgButtonChecked (hDlg, IDC_CS_CIAA_TOD1) ? 0
@@ -4341,6 +4288,7 @@ static void enable_for_chipsetdlg2 (HWND hDlg)
     ew (hDlg, IDC_CS_DMAC2, e);
     ew (hDlg, IDC_CS_A2091, e);
     ew (hDlg, IDC_CS_A4091, e);
+    ew (hDlg, IDC_CS_CDTVSCSI, e);
     ew (hDlg, IDC_CS_PCMCIA, e);
     ew (hDlg, IDC_CS_CD32CD, e);
     ew (hDlg, IDC_CS_CD32NVRAM, e);
@@ -4663,8 +4611,7 @@ static void values_to_kickstartdlg (HWND hDlg)
        load_keyring(&workprefs, NULL);
        addromfiles (fkey, hDlg, IDC_ROMFILE, workprefs.romfile, ROMTYPE_KICK | ROMTYPE_KICKCD32);
        addromfiles (fkey, hDlg, IDC_ROMFILE2, workprefs.romextfile, ROMTYPE_EXTCD32 | ROMTYPE_EXTCDTV | ROMTYPE_ARCADIABIOS);
-       addromfiles (fkey, hDlg, IDC_CARTFILE, workprefs.cartfile, ROMTYPE_AR | ROMTYPE_ARCADIAGAME);
-       //SendDlgItemMessage(hDlg, IDC_CARTFILE, CB_ADDSTRING, 0, (LPARAM)CART_SUPERIV);
+       addromfiles (fkey, hDlg, IDC_CARTFILE, workprefs.cartfile, ROMTYPE_AR | ROMTYPE_SUPERIV | ROMTYPE_ARCADIAGAME);
        if (fkey)
            RegCloseKey (fkey);
     }
@@ -6033,6 +5980,13 @@ static void inithardfile (HWND hDlg)
     SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_ADDSTRING, 0, (LPARAM)"IDE1");
     SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_ADDSTRING, 0, (LPARAM)"IDE2");
     SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_ADDSTRING, 0, (LPARAM)"IDE3");
+    SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_ADDSTRING, 0, (LPARAM)"SCSI0");
+    SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_ADDSTRING, 0, (LPARAM)"SCSI1");
+    SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_ADDSTRING, 0, (LPARAM)"SCSI2");
+    SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_ADDSTRING, 0, (LPARAM)"SCSI3");
+    SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_ADDSTRING, 0, (LPARAM)"SCSI4");
+    SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_ADDSTRING, 0, (LPARAM)"SCSI5");
+    SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_ADDSTRING, 0, (LPARAM)"SCSI6");
     SendDlgItemMessage (hDlg, IDC_HDF_CONTROLLER, CB_SETCURSEL, 0, 0);
     SendDlgItemMessage(hDlg, IDC_HF_TYPE, CB_RESETCONTENT, 0, 0);
     WIN32GUI_LoadUIString (IDS_HF_FS_CUSTOM, tmp, sizeof (tmp));
index 6fb94ac1da798132d125d3a6b87884a3e05e51d6..9b2ca217efd46a5e86128602c572b1b557bb80b7 100755 (executable)
                                RelativePath="..\..\savestate.c"
                                >
                        </File>
+                       <File
+                               RelativePath="..\..\scsi.c"
+                               >
+                       </File>
                        <File
                                RelativePath="..\..\scsiemul.c"
                                >
index 4bfafa0b26088fe0e0056e00e43a880272dab7ec..2d6c50eb92dc43f51b3a775ba20b4ccea31a5b9d 100755 (executable)
@@ -1,4 +1,34 @@
 
+Beta 2:
+
+- WD33C93 + (Super)DMAC based SCSI HDF emulation. A590/A2091, A3000 and
+  CDTV with SCSI expansion. Current implementation is very minimal.
+  A590/A2091 Boot ROMs 6.0, 6.6 and 7.0 tested and confirmed working.
+  A3000 random KS ROMs (including "1.4") also confirmed working.
+  CDTV with 1.0 extended ROM freezes during standard WB 1.3
+  startup-sequence (works if run manually..) Newer extended ROMs work
+  without freezes.
+  NOTE: disconnect/reconnect not emulated (yet?), SCSI Message out +
+  Command + Data in/out + Status + Message in phases emulated. Most
+  WD33C93 registers are not emulated. Non-tested drivers (KS versions)
+  most likely won't work yet. Check the log!
+
+- A3000 KS "1.4" added to ROM list (yes, it is beta but it came with
+  some A3000s) Need confirmed official A3000 and A4000(T) information
+  before more A3000/A4000(T) ROMs will be added. (Note A3000 ROMs,
+  not SuperKickstart images!)
+- A590/A2091 6.0, 6.6 and 7.0 added to ROM list. A590/A2091 ROM is
+  automatically selected, manual rom selection is not possible.
+- A590/A2091 Guru ROM added to ROM list (not yet supported, I need
+  A590/A2091 autoconfig er_InitDiagVec value first, Scout shows it)
+- A4091 40.9 (no CRC available yet) and 40.13 ROM added to ROM list.
+  NCR SCSI (A4091 and A4000T) is not yet emulated.
+
+- Action Cartridge Super IV Professional emulated partially, also added
+  support for Super IV "ROM version" (Super IV cartridge does not have
+  any ROM chips, "ROM" is loaded from disk) Loader disk does not work
+  yet! Interface is very different compared to Action Replay series.
 Beta 1:
 
 - use Segoe UI font only if running on Vista
diff --git a/scsi.c b/scsi.c
new file mode 100755 (executable)
index 0000000..4030002
--- /dev/null
+++ b/scsi.c
@@ -0,0 +1,99 @@
+ /*
+  * UAE - The Un*x Amiga Emulator
+  *
+  * SCSI emulation (not uaescsi.device)
+  *
+  * Copyright 2007 Toni Wilen
+  *
+  */
+
+#include "sysconfig.h"
+#include "sysdeps.h"
+
+#include "options.h"
+#include "scsi.h"
+#include "filesys.h"
+
+static int outcmd[] = { 0x0a, 0x2a, 0xaa, -1 };
+static int incmd[] = { 0x08, 0x12, 0x1a, 0x25, 0x28, 0xa8, 0x37, -1 };
+
+int scsi_data_dir(struct scsi_data *sd)
+{
+    int i;
+    uae_u8 cmd;
+
+    cmd = sd->cmd[0];
+    for (i = 0; outcmd[i] >= 0; i++) {
+       if (cmd == outcmd[i]) {
+           return 1;
+       }
+    }
+    for (i = 0; incmd[i] >= 0; i++) {
+       if (cmd == incmd[i]) {
+           return -1;
+       }
+    }
+    return 0;
+}
+
+void scsi_emulate_cmd(struct scsi_data *sd)
+{
+    sd->status = 0;
+    if (sd->cmd[0] == 0x03) { /* REQUEST SENSE */
+       int len = sd->buffer[4];
+       memset (sd->buffer, 0, len);
+       memcpy (sd->buffer, sd->sense, sd->sense_len > len ? len : sd->sense_len);
+    } else {
+       sd->status = scsi_emulate(&sd->hfd->hfd, sd->hfd,
+           sd->cmd, sd->len, sd->buffer, &sd->data_len, sd->reply, &sd->reply_len, sd->sense, &sd->sense_len);
+       if (sd->status == 0) {
+           if (sd->reply_len > 0) {
+               memset(sd->buffer, 0, 256);
+               memcpy(sd->buffer, sd->reply, sd->reply_len);
+           }
+       }
+    }
+    sd->offset = 0;
+}
+
+struct scsi_data *scsi_alloc(struct hd_hardfiledata *hfd)
+{
+    struct scsi_data *sd = xcalloc(sizeof (struct scsi_data), 1);
+    sd->hfd = hfd;
+    return sd;
+}
+
+void scsi_free(struct scsi_data *sd)
+{
+    xfree(sd);
+}
+
+void scsi_start_transfer(struct scsi_data *sd, int len)
+{
+    sd->len = len;
+    sd->offset = 0;
+}
+
+int scsi_send_data(struct scsi_data *sd, uae_u8 b)
+{
+    if (sd->direction) {
+       sd->buffer[sd->offset++] = b;
+    } else {
+       if (sd->offset >= 16) {
+           write_log("SCSI command buffer overflow!\n");
+           return 0;
+       }
+       sd->cmd[sd->offset++] = b;
+    }
+    if (sd->offset == sd->len)
+       return 1;
+    return 0;
+}
+
+int scsi_receive_data(struct scsi_data *sd, uae_u8 *b)
+{
+    *b = sd->buffer[sd->offset++];
+    if (sd->offset == sd->len)
+       return 1;
+    return 0;
+}
index b663d3ec60f7bfc5f48e1578fb8452cef037f60f..b6539620692918628bc2162d5e7be3b50e573d7b 100755 (executable)
@@ -158,8 +158,7 @@ static char *getdevname (int type)
        case UAEDEV_DISK_ID:
        return UAEDEV_DISK;
        default:
-       abort ();
-       return NULL;
+       return "NULL";
     }
 }