]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Comspec SA-1000 (partial), California Access Malibu.
authorToni Wilen <twilen@winuae.net>
Sun, 16 Apr 2017 19:07:50 +0000 (22:07 +0300)
committerToni Wilen <twilen@winuae.net>
Sun, 16 Apr 2017 19:07:50 +0000 (22:07 +0300)
a2091.cpp
include/a2091.h
include/rommgr.h
include/scsi.h
rommgr.cpp
scsi.cpp

index af480f3a2a10fbc32eac103774184455c7239f7e..4b5d922c2e6d058d2010ac64e799a622c264904b 100644 (file)
--- a/a2091.cpp
+++ b/a2091.cpp
@@ -17,6 +17,7 @@
 #define XT_DEBUG 0
 #define A3000_DEBUG 0
 #define A3000_DEBUG_IO 0
+
 #define WD33C93_DEBUG 0
 #define WD33C93_DEBUG_PIO 0
 
@@ -270,6 +271,7 @@ static struct wd_state *wd_a3000;
 static struct wd_state *wd_gvps1[MAX_DUPLICATE_EXPANSION_BOARDS];
 static struct wd_state *wd_gvps2[MAX_DUPLICATE_EXPANSION_BOARDS];
 static struct wd_state *wd_gvps2accel;
+static struct wd_state *wd_comspec[MAX_DUPLICATE_EXPANSION_BOARDS];
 struct wd_state *wd_cdtv;
 
 static struct wd_state *scsi_units[MAX_SCSI_UNITS + 1];
@@ -398,6 +400,12 @@ static bool isirq(struct wd_state *wd)
                if ((wd->cdmac.dmac_cntr & CNTR_INTEN) && (wd->cdmac.dmac_istr & ISTR_INTS))
                        return true;
                break;
+               case COMSPEC_CHIP:
+#if 0
+               if (wd->wc.auxstatus & ASR_INT)
+                       return true;
+#endif
+               break;
        }
        return false;
 }
@@ -555,7 +563,7 @@ static bool decreasetc(struct wd_chip_state *wd)
        return tc == 0;
 }
 
-static bool canwddma(struct wd_state *wds)
+static int canwddma(struct wd_state *wds)
 {
        struct wd_chip_state *wd = &wds->wc;
        uae_u8 mode = wd->wdregs[WD_CONTROL] >> 5;
@@ -578,8 +586,10 @@ static bool canwddma(struct wd_state *wds)
                        write_log (_T("%s weird DMA mode %d!!\n"), WD33C93, mode);
                }
                return mode == 2;
+               case COMSPEC_CHIP:
+               return -1;
                default:
-               return false;
+               return 0;
        }
 }
 
@@ -987,6 +997,22 @@ static bool wd_do_transfer_in (struct wd_chip_state *wd, struct scsi_data *scsi,
        return true;
 }
 
+static void set_pio_data_irq(struct wd_chip_state *wd, struct wd_state *wds)
+{
+       if (!wd->wd_data_avail)
+               return;
+       switch(wds->dmac_type)
+       {
+               case COMSPEC_CHIP:
+               if (wds->comspec.status & 0x10) {
+                       wds->comspec.status |= 0x08;
+                       INTREQ_0(0x8000 | 0x2000);
+               }
+               break;
+       }
+}
+
+
 static void wd_cmd_sel_xfer (struct wd_chip_state *wd, struct wd_state *wds, bool atn)
 {
        int i, tmp_tc;
@@ -1100,7 +1126,7 @@ static void wd_cmd_sel_xfer (struct wd_chip_state *wd, struct wd_state *wds, boo
                                set_status (wd, wd->wd_phase, 1);
                                return;
                        }
-                       if (canwddma (wds)) {
+                       if (canwddma (wds) > 0) {
                                if (scsi->direction <= 0) {
                                        do_dma(wds);
                                        if (scsi->offset < scsi->data_len) {
@@ -1130,6 +1156,11 @@ static void wd_cmd_sel_xfer (struct wd_chip_state *wd, struct wd_state *wds, boo
                                                scsi_emulate_cmd (scsi);
                                        }
                                }
+                       } else if (canwddma (wds) < 0) {
+                               // pio
+                               wd->wd_data_avail = 1;
+                               set_pio_data_irq(wd, wds);
+                               return;
                        } else {
                                // no dma = Service Request
                                wd->wd_phase = CSR_SRV_REQ;
@@ -1219,7 +1250,7 @@ static void wd_cmd_trans_info (struct wd_state *wds, struct scsi_data *scsi, boo
                wd->scsi->direction = 0;
                wd->wd_data_avail = 0;
        } else {
-               if (canwddma (wds)) {
+               if (canwddma (wds) > 0) {
                        wd->wd_data_avail = -1;
                } else {
                        wd->wd_data_avail = 1;
@@ -1310,7 +1341,8 @@ static void wd_cmd_reset (struct wd_chip_state *wd, bool irq)
        wd->auxstatus = 0;
        wd->wd_data_avail = 0;
        if (irq) {
-               set_status (wd, (wd->wdregs[0] & 0x08) ? 1 : 0, 50);
+               uae_u8 status = (wd->wdregs[0] & 0x08) ? 1 : 0;
+               set_status (wd, status, 50);
        }
 }
 
@@ -1402,6 +1434,13 @@ static void scsi_hsync2_gvp (struct wd_state *wds)
        wd_check_interrupt(wds, false);
 }
 
+static void scsi_hsync2_comspec(struct wd_state *wds)
+{
+       if (!wds || !wds->enabled)
+               return;
+       wd_check_interrupt(wds, false);
+}
+
 void scsi_hsync (void)
 {
        for (int i = 0; i < MAX_DUPLICATE_EXPANSION_BOARDS; i++) {
@@ -1409,6 +1448,7 @@ void scsi_hsync (void)
                scsi_hsync2_a2091(wd_a2090[i]);
                scsi_hsync2_gvp(wd_gvps1[i]);
                scsi_hsync2_gvp(wd_gvps2[i]);
+               scsi_hsync2_comspec(wd_comspec[i]);
        }
        scsi_hsync2_gvp(wd_gvps2accel);
        scsi_hsync2_a2091(wd_a3000);
@@ -1487,15 +1527,29 @@ void wdscsi_put (struct wd_chip_state *wd, struct wd_state *wds, uae_u8 d)
                        wd->wd_data_avail = 0;
                        write_comm_pipe_u32 (&wds->requests, makecmd (wd->scsi, 2, 0), 1);
                }
+               set_pio_data_irq(wd, wds);
        } else if (wd->sasr == WD_COMMAND) {
                wd->wd_busy = true;
-               write_comm_pipe_u32(&wds->requests, makecmd(wds->scsis[wd->wdregs[WD_DESTINATION_ID] & 7], 0, d), 1);
+               if (wd->resetnodelay && d == WD_CMD_RESET) {
+                       // stupid cpu loops that fail if CPU is too fast..
+                       wd_master_reset(wds, true);
+               } else {
+                       write_comm_pipe_u32(&wds->requests, makecmd(wds->scsis[wd->wdregs[WD_DESTINATION_ID] & 7], 0, d), 1);
+               }
                if (wd->scsi && wd->scsi->cd_emu_unit >= 0)
                        gui_flicker_led (LED_CD, wd->scsi->id, 1);
        }
        incsasr (wd, 1);
 }
 
+static void wdscsi_put_data(struct wd_chip_state *wd, struct wd_state *wds, uae_u8 v)
+{
+       uae_u8 sasr = wd->sasr;
+       wd->sasr = WD_DATA;
+       wdscsi_put(wd, wds, v);
+       wd->sasr = sasr;
+}
+
 void wdscsi_sasr (struct wd_chip_state *wd, uae_u8 b)
 {
        wd->sasr = b;
@@ -1532,6 +1586,7 @@ uae_u8 wdscsi_get (struct wd_chip_state *wd, struct wd_state *wds)
                        wd->wd_data_avail = 0;
                        write_comm_pipe_u32 (&wds->requests, makecmd (wd->scsi, 3, 0), 1);
                }
+               set_pio_data_irq(wd, wds);
        } else if (wd->sasr == WD_SCSI_STATUS) {
                wd->auxstatus &= ~0x80;
                if (wds->cdtv)
@@ -1556,6 +1611,15 @@ uae_u8 wdscsi_get (struct wd_chip_state *wd, struct wd_state *wds)
        return v;
 }
 
+uae_u8 wdscsi_get_data(struct wd_chip_state *wd, struct wd_state *wds)
+{
+       uae_u8 sasr = wd->sasr;
+       wd->sasr = WD_DATA;
+       uae_u8 v = wdscsi_get(wd, wds);
+       wd->sasr = sasr;
+       return v;
+}
+
 /* A590 XT */
 
 static void xt_default_geometry(struct wd_state *wds)
@@ -2452,6 +2516,243 @@ static const addrbank dmaca2091_bank = {
        ABFLAG_IO | ABFLAG_SAFE | ABFLAG_PPCIOSPACE, S_READ, S_WRITE
 };
 
+static bool comspec_wd_aux(uaecptr addr)
+{
+       return addr == 0xc1;
+}
+static bool comspec_wd_data(uaecptr addr)
+{
+       return addr == 0xc3;
+}
+static uae_u8 comspec_status(struct wd_state *wd)
+{
+       uae_u8 v = wd->comspec.status;
+       v &= ~0x80;
+       if (wd->wc.wd_data_avail)
+               v |= 0x80;
+       return v;
+}
+
+static uae_u8 comspec_read_byte(struct wd_state *wd, uaecptr addr)
+{
+       uae_u8 v = 0;
+       addr &= 65535;
+       if (!(addr & 0x8000)) {
+               v = wd->rom[addr];
+       } else {
+               addr &= 0x7fff;
+               if ((addr & 0xf1) == 0x80) {
+                       v = comspec_status(wd);
+               } else if ((addr & 0xf1) == 0x81) {
+                       v = wdscsi_get_data(&wd->wc, wd);
+               } else {
+                       if (comspec_wd_aux(addr)) {
+                               v = wdscsi_getauxstatus(&wd->wc);
+                       } else if (comspec_wd_data(addr)) {
+                               v = wdscsi_get (&wd->wc, wd);
+                       }
+               }
+               //write_log(_T("COMSPEC BGET %08x %02x %08x\n"), addr, v, M68K_GETPC);
+       }
+       return v;
+}
+static void comspec_write_byte(struct wd_state *wd, uaecptr addr, uae_u8 v)
+{
+       if (addr & 0x8000) {
+               addr &= 0x7fff;
+               if ((addr & 0xf0) == 0x80) {
+                       wd->comspec.status = v & 0x7f;
+                       if (!(v & 0x40)) {
+                               wd_master_reset(wd, true);
+                       }
+               } else if ((addr & 0xf1) == 0xe1) {
+                       wdscsi_put_data(&wd->wc, wd, v);
+               } else {
+                       if (comspec_wd_aux(addr)) {
+                               wdscsi_sasr(&wd->wc, v);
+                       } else if (comspec_wd_data(addr)) {
+                               wdscsi_put(&wd->wc, wd, v);
+                       }
+               }
+       }
+       write_log(_T("COMSPEC BPUT %08x %02x %08x\n"), addr, v, M68K_GETPC);
+}
+
+static uae_u16 comspec_read_word(struct wd_state *wd, uaecptr addr)
+{
+       uae_u16 v = 0;
+       addr &= 65535;
+       if (!(addr & 0x8000)) {
+               v = (wd->rom[addr] << 8) | wd->rom[addr + 1];
+       } else {
+               addr &= 0x7fff;
+               if ((addr & 0xf0) == 0x80) {
+                       v = comspec_status(wd) << 8;
+                       v |= wdscsi_get_data(&wd->wc, wd);
+               }
+               //write_log(_T("COMSPEC WGET %08x %04x %08x\n"), addr, v, M68K_GETPC);
+       }
+       return v;
+}
+static void comspec_write_word(struct wd_state *wd, uaecptr addr, uae_u16 v)
+{
+       if (addr & 0x8000) {
+               write_log(_T("COMSPEC BWUT %08x %04x %08x\n"), addr, v, M68K_GETPC);
+       }
+}
+
+static int REGPARAM2 comspec_check(struct wd_state *wd, uaecptr addr, uae_u32 size)
+{
+       return 1;
+}
+
+static uae_u8 *REGPARAM2 comspec_xlate(struct wd_state *wd, uaecptr addr)
+{
+       addr &= 0xffff;
+       return wd->rom + addr;
+}
+
+static uae_u32 REGPARAM2 comspec_lget (struct wd_state *wd, uaecptr addr)
+{
+       uae_u32 v;
+       addr &= 65535;
+       v = comspec_read_word(wd, addr) << 16;
+       v |= comspec_read_word(wd, addr + 2) & 0xffff;
+       return v;
+}
+
+static uae_u32 REGPARAM2 comspec_wget(struct wd_state *wd, uaecptr addr)
+{
+       uae_u32 v;
+       addr &= 65535;
+       v = comspec_read_word(wd, addr);
+       return v;
+}
+
+static uae_u32 REGPARAM2 comspec_bget(struct wd_state *wd, uaecptr addr)
+{
+       uae_u32 v;
+       addr &= 65535;
+       v = comspec_read_byte(wd, addr);
+       return v;
+}
+
+static void REGPARAM2 comspec_lput(struct wd_state *wd, uaecptr addr, uae_u32 l)
+{
+       addr &= 65535;
+       comspec_write_word(wd, addr + 0, l >> 16);
+       comspec_write_word(wd, addr + 2, l);
+}
+
+static void REGPARAM2 comspec_wput(struct wd_state *wd, uaecptr addr, uae_u32 w)
+{
+       addr &= 65535;
+       comspec_write_word(wd, addr, w);
+}
+
+extern const addrbank dmaca2091_bank;
+
+static void REGPARAM2 comspec_bput(struct wd_state *wd, uaecptr addr, uae_u32 b)
+{
+       b &= 0xff;
+       addr &= 65535;
+       comspec_write_byte(wd, addr, b);
+}
+
+static uae_u32 REGPARAM2 comspec_wgeti(struct wd_state *wd, uaecptr addr)
+{
+       uae_u32 v = 0xffff;
+       addr &= 65535;
+       if (!(addr & 0x8000))
+               v = (wd->rom[addr] << 8) | wd->rom[addr + 1];
+       return v;
+}
+static uae_u32 REGPARAM2 comspec_lgeti(struct wd_state *wd, uaecptr addr)
+{
+       uae_u32 v;
+       addr &= 65535;
+       v = comspec_wgeti(wd, addr) << 16;
+       v |= comspec_wgeti(wd, addr + 2);
+       return v;
+}
+
+
+static uae_u8 *REGPARAM2 comspec_xlate (uaecptr addr)
+{
+       struct wd_state *wd = getscsiboard(addr);
+       if (wd)
+               return comspec_xlate(wd, addr);
+       return default_xlate(0);
+}
+static int REGPARAM2 comspec_check (uaecptr addr, uae_u32 size)
+{
+       struct wd_state *wd = getscsiboard(addr);
+       if (wd)
+               return comspec_check(wd, addr, size);
+       return 0;
+}
+static uae_u32 REGPARAM2 comspec_lgeti (uaecptr addr)
+{
+       struct wd_state *wd = getscsiboard(addr);
+       if (wd)
+               return comspec_lgeti(wd, addr);
+       return 0;
+}
+static uae_u32 REGPARAM2 comspec_wgeti (uaecptr addr)
+{
+       struct wd_state *wd = getscsiboard(addr);
+       if (wd)
+               return comspec_wgeti(wd, addr);
+       return 0;
+}
+static uae_u32 REGPARAM2 comspec_bget (uaecptr addr)
+{
+       struct wd_state *wd = getscsiboard(addr);
+       if (wd)
+               return comspec_bget(wd, addr);
+       return 0;
+}
+static uae_u32 REGPARAM2 comspec_wget (uaecptr addr)
+{
+       struct wd_state *wd = getscsiboard(addr);
+       if (wd)
+               return comspec_wget(wd, addr);
+       return 0;
+}
+static uae_u32 REGPARAM2 comspec_lget (uaecptr addr)
+{
+       struct wd_state *wd = getscsiboard(addr);
+       if (wd)
+               return comspec_lget(wd, addr);
+       return 0;
+}
+static void REGPARAM2 comspec_bput (uaecptr addr, uae_u32 b)
+{
+       struct wd_state *wd = getscsiboard(addr);
+       if (wd)
+               comspec_bput(wd, addr, b);
+}
+static void REGPARAM2 comspec_wput (uaecptr addr, uae_u32 b)
+{
+       struct wd_state *wd = getscsiboard(addr);
+       if (wd)
+               comspec_wput(wd, addr, b);
+}
+static void REGPARAM2 comspec_lput (uaecptr addr, uae_u32 b)
+{
+       struct wd_state *wd = getscsiboard(addr);
+       if (wd)
+               comspec_lput(wd, addr, b);
+}
+
+static const addrbank comspec_bank = {
+       comspec_lget, comspec_wget, comspec_bget,
+       comspec_lput, comspec_wput, comspec_bput,
+       comspec_xlate, comspec_check, NULL, _T("*"), _T("COMSPEC"),
+       comspec_lgeti, comspec_wgeti,
+       ABFLAG_IO | ABFLAG_SAFE | ABFLAG_PPCIOSPACE, S_READ, S_WRITE
+};
+
 
 /* GVP Series I and II */
 
@@ -3760,6 +4061,71 @@ void cdtv_add_scsi_unit (int ch, struct uaedev_config_info *ci, struct romconfig
        add_scsi_device(&wd_cdtv->scsis[ch], ch, ci, rc);
 }
 
+bool comspec_init (struct autoconfig_info *aci)
+{
+       ew(aci->autoconfig_raw, 0x00, 0xc0 | 0x01 | 0x10);
+       ew(aci->autoconfig_raw, 0x04, 0x11);
+       ew(aci->autoconfig_raw, 0x10, 0x03);
+       ew(aci->autoconfig_raw, 0x14, 0xee);
+       /* rom vector */
+       ew(aci->autoconfig_raw, 0x28, 0x00);
+       ew(aci->autoconfig_raw, 0x2c, 0x10);
+       /* serial number */
+       ew(aci->autoconfig_raw, 0x18, 0x00);
+       ew(aci->autoconfig_raw, 0x1c, 0x00);
+       ew(aci->autoconfig_raw, 0x20, 0x00);
+       ew(aci->autoconfig_raw, 0x24, 0x00);
+
+       aci->label = _T("COMSPEC");
+       if (!aci->doinit)
+               return true;
+
+       struct wd_state *wd = getscsi(aci->rc);
+       int slotsize;
+
+       if (!wd)
+               return false;
+
+       init_wd_scsi(wd);
+
+       wd->configured = 0;
+       wd->dmac_type = COMSPEC_CHIP;
+       wd->autoconfig = true;
+       wd->board_mask = 65535;
+       wd->wc.resetnodelay = true;
+       memcpy(&wd->bank, &comspec_bank, sizeof addrbank);
+       memcpy(wd->dmacmemory, aci->autoconfig_raw, sizeof wd->dmacmemory);
+
+       alloc_expansion_bank(&wd->bank, aci);
+
+       wd->rombank = 0;
+       wd->rom_size = 16384;
+       slotsize = 65536;
+       wd->rom = xcalloc(uae_u8, slotsize);
+       memset(wd->rom, 0xff, slotsize);
+       wd->rom_mask = wd->rom_size - 1;
+       struct zfile *z = read_device_from_romconfig(aci->rc, ROMTYPE_COMSPEC);
+       if (z) {
+               wd->rom_size = zfile_size (z);
+               zfile_fread (wd->rom, wd->rom_size, 1, z);
+               zfile_fclose (z);
+               wd->rom_mask = wd->rom_size - 1;
+       }
+
+       if (!aci->rc->autoboot_disabled)
+               map_banks(&wd->bank, 0xf00000 >> 16, 1, 0);
+
+       return true;
+}
+
+void comspec_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
+{
+       struct wd_state *wd = allocscsi(&wd_comspec[ci->controller_type_unit], rc, ch);
+       if (!wd || ch < 0)
+               return;
+       add_scsi_device(&wd->scsis[ch], ch, ci, rc);
+}
+
 
 #if 0
 uae_u8 *save_scsi_dmac (int wdtype, int *len, uae_u8 *dstptr)
index d26bf498c05f8625f883a4dd699c63fcaf1ee4a4..7a844b702aec6c5f0a10537787dde88ae061dd30 100644 (file)
@@ -19,6 +19,7 @@ struct wd_chip_state {
        volatile int scsidelay_irq[WD_STATUS_QUEUE];
        struct scsi_data *scsi;
        int wd33c93_ver;// 0 or 1
+       bool resetnodelay;
 };
 
 #define COMMODORE_8727 0
@@ -26,6 +27,7 @@ struct wd_chip_state {
 #define COMMODORE_SDMAC 2
 #define GVP_DMAC_S2 3
 #define GVP_DMAC_S1 4
+#define COMSPEC_CHIP 6
 
 struct commodore_dmac
 {
@@ -69,6 +71,11 @@ struct gvp_dmac
        int bufoffset;
 };
 
+struct comspec_chip
+{
+       uae_u8 status;
+};
+
 struct wd_state {
        bool enabled;
        int configured;
@@ -95,6 +102,7 @@ struct wd_state {
        struct wd_chip_state wc;
        struct commodore_dmac cdmac;
        struct gvp_dmac gdmac;
+       struct comspec_chip comspec;
        addrbank bank;
 };
 extern wd_state *wd_cdtv;
@@ -115,6 +123,8 @@ extern bool gvp_init_accelerator(struct autoconfig_info *aci);
 extern void gvp_free(void);
 extern void gvp_reset (void);
 
+extern bool comspec_init (struct autoconfig_info *aci);
+
 extern bool a3000scsi_init(struct autoconfig_info *aci);
 extern void a3000scsi_free (void);
 extern void rethink_a2091 (void);
@@ -140,6 +150,7 @@ extern void gvp_s1_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct r
 extern void gvp_s2_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 extern void gvp_s2_add_accelerator_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 extern void a3000_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
+extern void comspec_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 
 extern int add_wd_scsi_hd (struct wd_state *wd, int ch, struct hd_hardfiledata *hfd, struct uaedev_config_info *ci, int scsi_level);
 extern int add_wd_scsi_cd (struct wd_state *wd, int ch, int unitnum);
index 0a81e22fade6d72574c320a3008197d64e4aebc5..d0230cae97270ee8896b97ad1450e1955191f93e 100644 (file)
@@ -148,6 +148,8 @@ extern int decode_cloanto_rom_do (uae_u8 *mem, int size, int real_size);
 #define ROMTYPE_HARDFRAME      0x0010005e
 #define ROMTYPE_ATEAM          0x0010005f
 #define ROMTYPE_PMX                    0x00100060
+#define ROMTYPE_COMSPEC                0x00100061
+#define ROMTYPE_MALIBU         0x00100062
 
 #define ROMTYPE_NOT                    0x00800000
 #define ROMTYPE_QUAD           0x01000000
index 4baf06a8c430515900b6c395b8b8548b9f8bf4e9..2012db586da83d29205b195eadd966d765d2293f 100644 (file)
@@ -261,6 +261,9 @@ void ossi_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig
 bool hardframe_init(struct autoconfig_info*);
 void hardframe_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
 
+bool malibu_init(struct autoconfig_info*);
+void malibu_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
+
 uae_u8 idescsi_scsi_get(uaecptr addr);
 void idescsi_scsi_put(uaecptr addr, uae_u8 v);
 
index 52c283a357f7e2498361594b49f34530ecca4403..f57ce5b9c130fad5d37e9aabf6f7ea845858c877 100644 (file)
@@ -95,7 +95,7 @@ struct romdata *getromdatabypath (const TCHAR *path)
        return NULL;
 }
 
-#define NEXT_ROM_ID 200
+#define NEXT_ROM_ID 202
 
 #define ALTROM(id,grp,num,size,flags,crc32,a,b,c,d,e) \
 { _T("X"), 0, 0, 0, 0, 0, size, id, 0, 0, flags, (grp << 16) | num, 0, NULL, crc32, a, b, c, d, e },
@@ -481,6 +481,12 @@ static struct romdata roms[] = {
        0x4fe08a5d, 0x007e5c61, 0x4048f598, 0x6d14011d, 0x23a41435, 0x5e0a2259, NULL, NULL },
        { _T("M-Tec AT500 Megabody v1.33"), 1, 33, 1, 33, _T("MTECAT\0"), 32768, 199, 0, 0, ROMTYPE_MTEC, 0, 0, NULL,
        0x19715a2f, 0x124f9d10, 0x19f1b285, 0x16f33f4e, 0x2bf03ca0, 0x2f9ad772, NULL, NULL },
+       { _T("Comspec SA-1000 v34.805"), 34, 805, 34, 805, _T("COMSPEC\0"), 16384, 200, 0, 0, ROMTYPE_COMSPEC, 0, 0, NULL,
+       0x44458e28, 0x048b8232, 0xfe54252b, 0xb81e0d06, 0x83c9e92d, 0x880f3cbf, NULL, NULL },
+       ALTROMPN(200, 1, 1, 8192, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0xd5838a35, 0xb3d83657, 0x661a9fe1, 0xd54e6e69, 0xc8b13878, 0x0960a107)
+       ALTROMPN(200, 1, 2, 8192, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x098c5529, 0x6f51827d, 0x40a79438, 0x69e2d0fb, 0x6e2e46e9, 0xb65c1244)
+       { _T("California Access Malibu v1.0"), 1, 0, 1, 0, _T("MALIBU\0"), 8192, 201, 0, 0, ROMTYPE_MALIBU, 0, 0, NULL,
+       0xe60b1ce6, 0xa7c4b709, 0x494f4034, 0x42b8ec11, 0x090dc1d0, 0x18098ebc, NULL, NULL },
 
        { _T("CyberStorm MK I 68040"), 0, 0, 0, 0, _T("CSMKI\0"), 32768, 95, 0, 0, ROMTYPE_CB_CSMK1, 0, 0, NULL,
          0, 0, 0, 0, 0, 0, NULL, _T("cyberstormmk1_040.rom") },
@@ -1712,8 +1718,9 @@ static struct zfile *rom_fopen2(const TCHAR *name, const TCHAR *mode, int mask)
                        uae_u8 *newrom = NULL;
                        uae_u8 *tmp1 = xcalloc(uae_u8, 524288 * 2);
                        uae_u8 *tmp2 = xcalloc(uae_u8, 524288 * 2);
-                       zfile_fread(tmp1, 1, size, f);
                        for (;;) {
+                               if (zfile_fread(tmp1, 1, size, f) != size)
+                                       break;
                                if (size == 524288 * 2) {
                                        // Perhaps it is 1M interleaved ROM image?
                                        mergecd32(tmp2, tmp1, 524288 * 2);
@@ -1762,15 +1769,17 @@ static struct zfile *rom_fopen2(const TCHAR *name, const TCHAR *mode, int mask)
                zfile_fclose(f);
                f = f2;
        }
+       if (f) {
+               zfile_fseek(f, 0, SEEK_SET);
+       }
        return f;
 }
 
 struct zfile *read_rom_name (const TCHAR *filename)
 {
-       int i;
        struct zfile *f;
 
-       for (i = 0; i < romlist_cnt; i++) {
+       for (int i = 0; i < romlist_cnt; i++) {
                if (my_issamepath(filename, rl[i].path)) {
                        struct romdata *rd = rl[i].rd;
                        f = read_rom (rd);
@@ -1780,7 +1789,7 @@ struct zfile *read_rom_name (const TCHAR *filename)
        }
        f = rom_fopen2(filename, _T("rb"), ZFD_NORMAL);
        if (f) {
-               uae_u8 tmp[11];
+               uae_u8 tmp[11] = { 0 };
                zfile_fread (tmp, sizeof tmp, 1, f);
                if (!memcmp (tmp, "AMIROMTYPE1", sizeof tmp)) {
                        struct zfile *df;
index 0176dad42974193619df862c2048a64f6fbb8481..40b5c97275c596c803915d004e73943fae837727 100644 (file)
--- a/scsi.cpp
+++ b/scsi.cpp
@@ -60,7 +60,8 @@
 #define NCR5380_OSSI 29
 #define NCR5380_DATAFLYERPLUS 30
 #define NONCR_HARDFRAME 31
-#define NCR_LAST 32
+#define NCR5380_MALIBU 32
+#define NCR_LAST 33
 
 extern int log_scsiemu;
 
@@ -2435,6 +2436,20 @@ static int dataflyerplus_reg(uaecptr addr)
        return (addr >> 1) & 7;
 }
 
+static int malibureg(uaecptr addr)
+{
+       if ((addr & 0xc000) == 0x8000)
+               return 8; // long read port
+       if ((addr & 0xc000) == 0xc000)
+               return 8; // long write port
+       if (!(addr & 1))
+               return -1;
+       if (addr & 0x4000)
+               return -1;
+       int reg = (addr & 0x0f) >> 1;
+       return reg;
+}
+
 static uae_u8 read_684xx_dma(struct soft_scsi *ncr, uaecptr addr)
 {
        uae_u8 val = 0;
@@ -2579,7 +2594,18 @@ static uae_u32 ncr80_bget2(struct soft_scsi *ncr, uaecptr addr, int size)
 
        addr &= ncr->board_mask;
 
-       if (ncr->type == NONCR_HARDFRAME) {
+       if (ncr->type == NCR5380_MALIBU) {
+
+               if ((addr & 0xc000) == 0x4000) {
+                       v = ncr->rom[addr & 0x3fff];
+               } else {
+                       reg = malibureg(addr);
+                       if (reg >= 0) {
+                               v = ncr5380_bget(ncr, reg);
+                       }
+               }
+
+       } else if (ncr->type == NONCR_HARDFRAME) {
 
                if (addr == 0xc0) {
                        v = aic_bget_reg(ncr);
@@ -3030,7 +3056,7 @@ static uae_u32 ncr80_bget2(struct soft_scsi *ncr, uaecptr addr, int size)
        }
 
 #if NCR5380_DEBUG > 1
-       if (origaddr < 0x100)
+       if (origaddr < 0x4000 || origaddr >= 0x8000)
                write_log(_T("GET %08x %02x %d %08x %d\n"), origaddr, v, reg, M68K_GETPC, regs.intmask);
 #endif
 
@@ -3045,7 +3071,14 @@ static void ncr80_bput2(struct soft_scsi *ncr, uaecptr addr, uae_u32 val, int si
 
        addr &= ncr->board_mask;
 
-       if (ncr->type == NONCR_HARDFRAME) {
+       if (ncr->type == NCR5380_MALIBU) {
+
+               reg = malibureg(addr);
+               if (reg >= 0) {
+                       ncr5380_bput(ncr, reg, val);
+               }
+
+       } else if (ncr->type == NONCR_HARDFRAME) {
                
                if (addr == 0xc0) {
                        aic_bput_reg(ncr, val);
@@ -4462,3 +4495,31 @@ void hardframe_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romco
 {
        generic_soft_scsi_add(ch, ci, rc, NONCR_HARDFRAME, 65536, 65536, ROMTYPE_HARDFRAME);
 }
+
+bool malibu_init(struct autoconfig_info *aci)
+{
+       const struct expansionromtype *ert = get_device_expansion_rom(ROMTYPE_MALIBU);
+       if (!aci->doinit) {
+               aci->autoconfigp = ert->autoconfig;
+               return true;
+       }
+
+       struct soft_scsi *scsi = getscsi(aci->rc);
+       if (!scsi)
+               return false;
+
+       load_rom_rc(aci->rc, ROMTYPE_MALIBU, 8192, 0, scsi->rom, 65536, LOADROM_EVENONLY_ODDONE);
+       for (int i = 0; i < 16; i++) {
+               uae_u8 b = ert->autoconfig[i];
+               if (aci->rc->autoboot_disabled && i == 0)
+                       b = 0xc1;
+               ew(scsi, i * 4, b);
+       }
+       aci->addrbank = scsi->bank;
+       return true;
+}
+
+void malibu_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
+{
+       generic_soft_scsi_add(ch, ci, rc, NCR5380_MALIBU, 65536, 16384, ROMTYPE_MALIBU);
+}