#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];
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)
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)
#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();
}
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;
}
v = dmac_istr;
if (v)
v |= ISTR_INT_P;
+ dmac_istr &= ~0xf;
break;
case 0x43:
v = dmac_cntr;
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
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:
break;
case 0xe8:
case 0xe9:
- dmac_dma = 0;
+ /* FLUSH */
+ dmac_istr |= ISTR_FE_FLG;
break;
}
#if A2091_DEBUG > 0
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;
{
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;
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:
dmac_dma = 0;
dmac_stop_dma();
break;
+ case 0x41:
case 0x49:
sasr = val;
break;
case 0x05:
case 0x06:
case 0x07:
- v = dmacreg_read(dmac_wtc, addr - 0x04, 4);
+ v = 0xff;
break;
case 0x0a:
case 0x0b:
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;
#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)
{
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)
void a2091_init (void)
{
struct zfile *z;
- char path[MAX_DPATH];
+ int roms[4];
+ struct romlist *rl;
configured = 0;
memset (dmacmemory, 0xff, 100);
/* 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);
* 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. */
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);
#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;
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--) {
put_long ((uaecptr)(regs.vbr + 8), get_long (hrtmem_start + 8));
Exception (2, ®s, 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));
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;
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);
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;
}
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);
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]);
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()
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. */
void set_uae_int_flag (void)
{
- rtarea[0xFFFB] = uae_int_requested;
+ rtarea[0xFFFB] = uae_int_requested & 1;
}
void rtarea_setup (void)
#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
static void INT2(void)
{
- if (!(intreq & 8))
+ if (!(intreq & 8)) {
INTREQ_f(0x8000 | 0x0008);
+ }
}
static int cdrom_command_cnt_out, cdrom_command_size_out;
}
}
-#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;
break;
case 0x0101:
{
- get_qcode();
if (ismedia() != cd_media) {
cd_media = ismedia();
get_toc();
if (!cd_media)
cd_hunt = 1;
}
+ if (cd_media)
+ get_qcode();
}
break;
case 0x0102: // pause
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)
}
}
+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;
dma_finished = 0;
cdtv_hsync = -1;
}
- if (dmac_istr & ISTR_E_INT)
- INT2();
+ checkint();
if (cdrom_command_done) {
cdrom_command_done = 0;
{
case 0x41:
v = dmac_istr;
+ if (v)
+ v |= ISTR_INT_P;
+ dmac_istr &= ~0xf;
break;
case 0x43:
v = dmac_cntr;
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) {
}
}
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
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) {
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);
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
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) {
}
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;
{
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];
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);
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)
|| 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)
*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;
}
}
return -1;
}
+STATIC_INLINE int use_eventmode(void)
+{
+ return currprefs.cpu_cycle_exact != 0;
+}
+
static void INTENA_f(uae_u32 data)
{
doint();
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);
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);
void INTREQ (uae_u16 v)
{
- if (!currprefs.cpu_compatible)
+ if (!use_eventmode())
INTREQ_f(v);
else
INTREQ_d(v, 6);
reset_decisions ();
}
-#ifdef FILESYS
if (uae_int_requested) {
INTREQ (0x8000 | 0x0008);
}
-#endif
{
extern void bsdsock_fake_int_handler(void);
inputdevice_hsync ();
gayle_hsync();
+ scsi_hsync();
hsync_counter++;
//copper_check (2);
#include "gui.h"
#include "gayle.h"
#include "savestate.h"
+#include "a2091.h"
+#include "cdtv.h"
#define TRACING_ENABLED 0
#if TRACING_ENABLED
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();
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;
* 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;
}
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;
uae_u8 status;
int irq_delay;
int num;
- int bootpri; // for fake RDB
};
static struct ide_hdf idedrive[4];
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();
int v;
uae_u8 *buf = ide->secbuf;
- if (ide->size == 0) {
+ if (ide->hdhfd.size == 0) {
ide_fail();
return;
}
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);
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);
}
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)
*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)
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++;
}
}
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;
}
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;
}
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;
}
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;
}
}
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)
{
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;
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)
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;
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");
}
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);
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;
}
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();
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);
#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
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;
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];
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]) {
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));
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");
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 */
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++;
}
}
put_byte (scsi_sense + i, 0);
i++;
}
- if (lr < 0) {
+ if (scsi_len < 0) {
put_long (acmd + 8, 0); /* scsi_Actual */
ret = 20;
} else {
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
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
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
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);
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);
#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;
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);
STATIC_INLINE void do_uae_int_requested (void)
{
- uae_int_requested = 1;
+ uae_int_requested |= 1;
set_uae_int_flag ();
}
--- /dev/null
+
+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);
+
+
#include "akiko.h"
#include "arcadia.h"
#include "enforcer.h"
+#include "a2091.h"
int canbang;
#ifdef JIT
{ "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 },
{ "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 },
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
// "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;
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)
return;
switch (addr)
{
+ case 0x08:
+ ncrregs[0x22] |= 2;
+ break;
case 0x02: // SCNTL1
break;
case 0x22 : // ISTAT
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
return;
}
if (addr == 0x4c) {
- write_log ("A4091 DMAC AUTOCONFIG SHUT-UP!\n");
+ write_log ("A4091 AUTOCONFIG SHUT-UP!\n");
configured = 1;
expamem_next();
return;
void ncr_init (void)
{
struct zfile *z;
- char path[MAX_DPATH];
+ int roms[3];
+ struct romlist *rl;
configured = 0;
memset (acmemory, 0xff, 100);
/* 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);
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);
shmaddr=natmem_offset + 0x00b00000;
got = TRUE;
}
+ if(!strcmp(shmids[shmid].name,"superiv_3")) {
+ shmaddr=natmem_offset + 0x00e00000;
+ got = TRUE;
+ }
}
#endif
#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
#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
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
#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 ""
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)
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);
}
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) {
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));
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
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);
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);
}
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));
RelativePath="..\..\savestate.c"
>
</File>
+ <File
+ RelativePath="..\..\scsi.c"
+ >
+ </File>
<File
RelativePath="..\..\scsiemul.c"
>
+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
--- /dev/null
+ /*
+ * 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;
+}
case UAEDEV_DISK_ID:
return UAEDEV_DISK;
default:
- abort ();
- return NULL;
+ return "NULL";
}
}