From 4def31b0b10d3eeb4ba1896230ae8386faa4de82 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sun, 16 Apr 2017 22:07:50 +0300 Subject: [PATCH] Comspec SA-1000 (partial), California Access Malibu. --- a2091.cpp | 378 ++++++++++++++++++++++++++++++++++++++++++++++- include/a2091.h | 11 ++ include/rommgr.h | 2 + include/scsi.h | 3 + rommgr.cpp | 19 ++- scsi.cpp | 69 ++++++++- 6 files changed, 467 insertions(+), 15 deletions(-) diff --git a/a2091.cpp b/a2091.cpp index af480f3a..4b5d922c 100644 --- 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) diff --git a/include/a2091.h b/include/a2091.h index d26bf498..7a844b70 100644 --- a/include/a2091.h +++ b/include/a2091.h @@ -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); diff --git a/include/rommgr.h b/include/rommgr.h index 0a81e22f..d0230cae 100644 --- a/include/rommgr.h +++ b/include/rommgr.h @@ -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 diff --git a/include/scsi.h b/include/scsi.h index 4baf06a8..2012db58 100644 --- a/include/scsi.h +++ b/include/scsi.h @@ -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); diff --git a/rommgr.cpp b/rommgr.cpp index 52c283a3..f57ce5b9 100644 --- a/rommgr.cpp +++ b/rommgr.cpp @@ -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; diff --git a/scsi.cpp b/scsi.cpp index 0176dad4..40b5c972 100644 --- 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); +} -- 2.47.3