From: Toni Wilen Date: Sun, 20 May 2007 10:10:03 +0000 (+0300) Subject: imported winuaesrc1430b2.zip X-Git-Tag: 2100~220 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=9740a6ccee5cee301fa15a40e71f6a801a42be19;p=francis%2Fwinuae.git imported winuaesrc1430b2.zip --- diff --git a/a2091.c b/a2091.c index d44eba7f..7084ed3a 100755 --- 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" @@ -22,11 +20,14 @@ #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 @@ -58,59 +59,85 @@ #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 7e0e2107..ab8a11ef 100755 --- a/ar.c +++ b/ar.c @@ -145,6 +145,17 @@ * 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" @@ -169,6 +180,7 @@ 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, ®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)); @@ -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. */ diff --git a/autoconf.c b/autoconf.c index 04b9521f..8622976b 100755 --- a/autoconf.c +++ b/autoconf.c @@ -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 b2490bd8..fbcfeeae 100755 --- a/cdtv.c +++ b/cdtv.c @@ -28,6 +28,24 @@ #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; diff --git a/cfgfile.c b/cfgfile.c index 0c222efb..552f2533 100755 --- 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; } } diff --git a/custom.c b/custom.c index 70fba0c4..0736c60f 100755 --- 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); diff --git a/filesys.c b/filesys.c index 07779575..0f0dd6f3 100755 --- 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 8ec62d28..7fdc78d5 100755 --- 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); diff --git a/hardfile.c b/hardfile.c index ef12ab73..cae446b2 100755 --- a/hardfile.c +++ b/hardfile.c @@ -23,6 +23,7 @@ #include "native2amiga.h" #include "gui.h" #include "uae.h" +#include "scsi.h" #define CMD_INVALID 0 #define CMD_RESET 1 @@ -62,15 +63,19 @@ #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 { diff --git a/include/a2091.h b/include/a2091.h index cddf3b7c..186cf26c 100755 --- a/include/a2091.h +++ b/include/a2091.h @@ -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 diff --git a/include/cdtv.h b/include/cdtv.h index e44df5c0..23d1fa08 100755 --- a/include/cdtv.h +++ b/include/cdtv.h @@ -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 diff --git a/include/filesys.h b/include/filesys.h index fa6b1f6b..686a0827 100755 --- a/include/filesys.h +++ b/include/filesys.h @@ -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); diff --git a/include/memory.h b/include/memory.h index c4a68a9b..eb4d5f18 100755 --- a/include/memory.h +++ b/include/memory.h @@ -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); diff --git a/include/native2amiga.h b/include/native2amiga.h index 043e08bf..ff08885d 100755 --- a/include/native2amiga.h +++ b/include/native2amiga.h @@ -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 index 00000000..db81a08d --- /dev/null +++ b/include/scsi.h @@ -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); + + diff --git a/memory.c b/memory.c index e6ec4e88..e5a6c7f7 100755 --- 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) diff --git a/ncr_scsi.c b/ncr_scsi.c index f319cec0..c54d23c5 100755 --- a/ncr_scsi.c +++ b/ncr_scsi.c @@ -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); diff --git a/newcpu.c b/newcpu.c index eb37259c..853869e7 100755 --- 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); diff --git a/od-win32/mman.c b/od-win32/mman.c index 9b66c732..873d2763 100755 --- a/od-win32/mman.c +++ b/od-win32/mman.c @@ -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 diff --git a/od-win32/resources/resource b/od-win32/resources/resource index 7bc3a388..6451ef80 100755 --- a/od-win32/resources/resource +++ b/od-win32/resources/resource @@ -180,7 +180,7 @@ #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 @@ -248,6 +248,7 @@ #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 @@ -344,7 +345,6 @@ #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 @@ -523,7 +523,6 @@ #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 @@ -897,6 +896,7 @@ #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 diff --git a/od-win32/resources/resource.h b/od-win32/resources/resource.h index db641e50..fe40a84c 100755 --- a/od-win32/resources/resource.h +++ b/od-win32/resources/resource.h @@ -896,7 +896,7 @@ #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 @@ -926,7 +926,7 @@ #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 diff --git a/od-win32/resources/winuae.rc b/od-win32/resources/winuae.rc index fd732573..ca91ebb8 100755 --- a/od-win32/resources/winuae.rc +++ b/od-win32/resources/winuae.rc @@ -574,9 +574,10 @@ BEGIN EDITTEXT IDC_CS_DENISEREV,235,226,45,13,ES_AUTOHSCROLL CONTROL "A590/A2091 SCSI",IDC_CS_A2091,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,175,76,10 CONTROL "A4000T SCSI",IDC_CS_DMAC2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,193,175,88,10 - LTEXT "SCSI not yet implemented.",IDC_STATIC,25,161,224,8,SS_CENTERIMAGE + LTEXT "A4000/A4000T SCSI not yet implemented.",IDC_STATIC,25,161,224,8,SS_CENTERIMAGE CONTROL "PCMCIA",IDC_CS_PCMCIA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,193,146,92,10 CONTROL "A4091 SCSI",IDC_CS_A4091,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,187,76,10 + CONTROL "CDTV SCSI",IDC_CS_CDTVSCSI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,100,187,76,10 END IDD_AVIOUTPUT DIALOGEX 0, 0, 288, 203 diff --git a/od-win32/win32.h b/od-win32/win32.h index 825e9a12..7c81ed35 100755 --- a/od-win32/win32.h +++ b/od-win32/win32.h @@ -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 "" diff --git a/od-win32/win32gui.c b/od-win32/win32gui.c index 4003789d..3de607ab 100755 --- a/od-win32/win32gui.c +++ b/od-win32/win32gui.c @@ -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)); diff --git a/od-win32/winuae_msvc/winuae_msvc.vcproj b/od-win32/winuae_msvc/winuae_msvc.vcproj index 6fb94ac1..9b2ca217 100755 --- a/od-win32/winuae_msvc/winuae_msvc.vcproj +++ b/od-win32/winuae_msvc/winuae_msvc.vcproj @@ -1769,6 +1769,10 @@ RelativePath="..\..\savestate.c" > + + diff --git a/od-win32/winuaechangelog.txt b/od-win32/winuaechangelog.txt index 4bfafa0b..2d6c50eb 100755 --- a/od-win32/winuaechangelog.txt +++ b/od-win32/winuaechangelog.txt @@ -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 index 00000000..40300022 --- /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; +} diff --git a/scsiemul.c b/scsiemul.c index b663d3ec..b6539620 100755 --- a/scsiemul.c +++ b/scsiemul.c @@ -158,8 +158,7 @@ static char *getdevname (int type) case UAEDEV_DISK_ID: return UAEDEV_DISK; default: - abort (); - return NULL; + return "NULL"; } }