*
*/
-#define GVP_DEBUG_IO 0
+#define GVP_S1_DEBUG_IO 0
+#define GVP_S2_DEBUG_IO 0
#define A2091_DEBUG 0
#define A2091_DEBUG_IO 0
#define XT_DEBUG 0
#include "autoconf.h"
#include "cdtv.h"
#include "savestate.h"
+#include "cpuboard.h"
#define CDMAC_ROM_VECTOR 0x2000
#define CDMAC_ROM_OFFSET 0x2000
#define GVP_ROM_OFFSET 0x8000
+#define GVP_SERIES_I_RAM_OFFSET 0x4000
+#define GVP_SERIES_I_RAM_MASK 16383
/* SuperDMAC CNTR bits. */
#define SCNTR_TCEN (1<<5)
{
switch (wd->dmac_type)
{
- case GVP_DMAC:
+ case GVP_DMAC_S1:
+ case GVP_DMAC_S2:
wd->gdmac.cntr = 0;
wd->gdmac.dma_on = 0;
break;
return false;
switch (wd->dmac_type)
{
- case GVP_DMAC:
+ case GVP_DMAC_S1:
+ return wd->gdmac.cntr && (wd->wc.auxstatus & ASR_INT) != 0;
+ case GVP_DMAC_S2:
if (wd->wc.auxstatus & ASR_INT)
wd->gdmac.cntr |= 2;
if ((wd->gdmac.cntr & (2 | 8)) == 10)
{
switch (wds->dmac_type)
{
- case GVP_DMAC:
+ case GVP_DMAC_S1:
+ case GVP_DMAC_S2:
wds->gdmac.dma_on = -1;
break;
case COMMODORE_SDMAC:
{
switch (wds->dmac_type)
{
- case GVP_DMAC:
+ case GVP_DMAC_S1:
+ return true;
+ case GVP_DMAC_S2:
return wds->gdmac.dma_on > 0;
case COMMODORE_SDMAC:
case COMMODORE_DMAC:
return tc == 0;
}
-static bool canwddma(struct wd_chip_state *wd)
+static bool canwddma(struct wd_state *wds)
{
+ struct wd_chip_state *wd = &wds->wc;
uae_u8 mode = wd->wdregs[WD_CONTROL] >> 5;
- if (mode != 0 && mode != 4 && mode != 1) {
- write_log (_T("%s weird DMA mode %d!!\n"), WD33C93, mode);
+ switch(wds->dmac_type)
+ {
+ case COMMODORE_DMAC:
+ case COMMODORE_SDMAC:
+ case GVP_DMAC_S2:
+ if (mode != 0 && mode != 4 && mode != 1) {
+ write_log (_T("%s weird DMA mode %d!!\n"), WD33C93, mode);
+ }
+ return mode == 4 || mode == 1;
+ case GVP_DMAC_S1:
+ if (mode != 0 && mode != 2) {
+ write_log (_T("%s weird DMA mode %d!!\n"), WD33C93, mode);
+ }
+ return mode == 2;
+ default:
+ return false;
}
- return mode == 4 || mode == 1;
}
#if WD33C93_DEBUG > 0
return false;
}
-static bool do_dma_gvp(struct wd_state *wd, struct scsi_data *scsi)
+static bool do_dma_gvp_s1(struct wd_state *wd, struct scsi_data *scsi)
+{
+ if (scsi->direction < 0) {
+ for (;;) {
+ uae_u8 v;
+ int status = scsi_receive_data (scsi, &v);
+ wd->gdmac.buffer[wd->wc.wd_dataoffset++] = v;
+ wd->wc.wd_dataoffset &= GVP_SERIES_I_RAM_MASK;
+ if (decreasetc (&wd->wc))
+ break;
+ if (status)
+ break;
+ }
+#if WD33C93_DEBUG > 0
+ write_log (_T("%s Done DMA from WD, %d/%d\n"), WD33C93, scsi->offset, scsi->data_len);
+#endif
+ return true;
+ } else if (scsi->direction > 0) {
+ for (;;) {
+ int status;
+ uae_u8 v = wd->gdmac.buffer[wd->wc.wd_dataoffset++];
+ wd->wc.wd_dataoffset &= GVP_SERIES_I_RAM_MASK;
+ status = scsi_send_data (scsi, v);
+ wd->gdmac.addr++;
+ if (decreasetc (&wd->wc))
+ break;
+ if (status)
+ break;
+ }
+#if WD33C93_DEBUG > 0
+ write_log (_T("%s Done DMA to WD, %d/%d\n"), WD33C93, scsi->offset, scsi->data_len);
+#endif
+ return true;
+ }
+ return false;
+}
+
+
+static bool do_dma_gvp_s2(struct wd_state *wd, struct scsi_data *scsi)
{
#if WD33C93_DEBUG > 0
uae_u32 dmaptr = wd->gdmac.addr;
#endif
if (!is_dma_enabled(wd))
return false;
+
if (scsi->direction < 0) {
if (wd->gdmac.cntr & 0x10) {
write_log(_T("GVP DMA: mismatched direction when reading!\n"));
case COMMODORE_DMAC:
case COMMODORE_SDMAC:
return do_dma_commodore(wd, scsi);
- case GVP_DMAC:
- return do_dma_gvp(wd, scsi);
+ case GVP_DMAC_S2:
+ return do_dma_gvp_s2(wd, scsi);
+ case GVP_DMAC_S1:
+ return do_dma_gvp_s1(wd, scsi);
}
return false;
}
}
if (wd->scsi->direction) {
- if (canwddma (wd)) {
+ if (canwddma (wds)) {
if (scsi->direction <= 0) {
do_dma(wds);
if (scsi->offset < scsi->data_len) {
wd->wd_selected = 0;
}
-static void wd_cmd_trans_info (struct wd_chip_state *wd, struct scsi_data *scsi)
+static void wd_cmd_trans_info (struct wd_state *wds, struct scsi_data *scsi)
{
+ struct wd_chip_state *wd = &wds->wc;
if (wd->wdregs[WD_COMMAND_PHASE] == 0x20) {
wd->wdregs[WD_COMMAND_PHASE] = 0x30;
scsi->status = 0;
scsi->data_len = gettc (wd);
}
- if (canwddma (wd)) {
+ if (canwddma (wds)) {
wd->wd_data_avail = -1;
} else {
wd->wd_data_avail = 1;
dmac_a20912_lgeti, dmac_a20912_wgeti, ABFLAG_IO | ABFLAG_SAFE
};
-/* GVP Series II */
+/* GVP Series I and II */
extern addrbank gvp_bank;
extern addrbank gvp_2_bank;
uae_u32 v = 0;
addr &= 0xffff;
- if (addr < 0x40) {
+ if (addr < 0x3e) {
v = wd->dmacmemory[addr];
} else if (addr >= GVP_ROM_OFFSET) {
- if (addr & 1) {
- v = wd->gdmac.version;
+ if (wd->gdmac.series2) {
+ if (addr & 1) {
+ v = wd->gdmac.version;
+ } else {
+ if (wd->rom) {
+ if (wd->rombankswitcher && (addr & 0xffe0) == GVP_ROM_OFFSET)
+ wd->rombank = (addr & 0x02) >> 1;
+ v = wd->rom[(addr - GVP_ROM_OFFSET) / 2 + wd->rombank * 16384];
+ }
+ }
} else {
if (wd->rom) {
- if (wd->rombankswitcher && (addr & 0xffe0) == GVP_ROM_OFFSET)
- wd->rombank = (addr & 0x02) >> 1;
- v = wd->rom[(addr - GVP_ROM_OFFSET) / 2 + wd->rombank * 16384];
+ v = wd->rom[addr - GVP_ROM_OFFSET];
}
}
+ } else if (addr >= GVP_SERIES_I_RAM_OFFSET && !wd->gdmac.series2) {
+ v = wd->gdmac.buffer[wd->gdmac.bufoffset++];
+ wd->gdmac.bufoffset &= GVP_SERIES_I_RAM_MASK;
} else if (wd->configured) {
- switch (addr)
- {
- case 0x40:
- v = wd->gdmac.cntr >> 8;
- break;
- case 0x41:
- v = wd->gdmac.cntr;
- break;
- case 0x61: // SASR
- v = wdscsi_getauxstatus(&wd->wc);
- break;
- case 0x63: // SCMD
- v = wdscsi_get(&wd->wc, wd);
- break;
- default:
- write_log(_T("gvp_bget_unk %04X PC=%08X\n"), addr, M68K_GETPC);
- break;
+ if (wd->gdmac.series2) {
+ switch (addr)
+ {
+ case 0x40:
+ v = wd->gdmac.cntr >> 8;
+ break;
+ case 0x41:
+ v = wd->gdmac.cntr;
+ break;
+ case 0x61: // SASR
+ v = wdscsi_getauxstatus(&wd->wc);
+ break;
+ case 0x63: // SCMD
+ v = wdscsi_get(&wd->wc, wd);
+ break;
+ default:
+ write_log(_T("gvp_s2_bget_unk %04X PC=%08X\n"), addr, M68K_GETPC);
+ break;
+ }
+ } else {
+ switch (addr)
+ {
+ case 0x3e:
+ v = wd->wc.auxstatus & ASR_INT;
+ break;
+ case 0x60: // SASR
+ v = wdscsi_getauxstatus(&wd->wc);
+ break;
+ case 0x62: // SCMD
+ v = wdscsi_get(&wd->wc, wd);
+ break;
+ default:
+ write_log(_T("gvp_s1_bget_unk %04X PC=%08X\n"), addr, M68K_GETPC);
+ break;
+ }
}
} else {
v = 0xff;
}
-#if GVP_DEBUG_IO > 0
+#if GVP_S2_DEBUG_IO > 0
write_log(_T("gvp_bget %04X=%02X PC=%08X\n"), addr, v, M68K_GETPC);
#endif
uae_u32 v = 0;
addr &= 0xffff;
- if (addr < 0x40) {
+ if (addr < 0x3e) {
v = (wd->dmacmemory[addr] << 8) | wd->dmacmemory[addr + 1];
} else if (addr >= GVP_ROM_OFFSET) {
- if (wd->rom) {
- if (wd->rombankswitcher && (addr & 0xffe0) == GVP_ROM_OFFSET)
- wd->rombank = (addr & 0x02) >> 1;
- v = (wd->rom[(addr - GVP_ROM_OFFSET) / 2 + wd->rombank * 16384] << 8) | wd->gdmac.version;
+ if (wd->gdmac.series2) {
+ if (wd->rom) {
+ if (wd->rombankswitcher && (addr & 0xffe0) == GVP_ROM_OFFSET)
+ wd->rombank = (addr & 0x02) >> 1;
+ v = (wd->rom[(addr - GVP_ROM_OFFSET) / 2 + wd->rombank * 16384] << 8) | wd->gdmac.version;
+ } else {
+ v = wd->gdmac.version;
+ }
} else {
- v = wd->gdmac.version;
+ if (wd->rom) {
+ v = (wd->rom[addr - GVP_ROM_OFFSET] << 8) | (wd->rom[addr - GVP_ROM_OFFSET + 1]);
+ }
}
+ } else if (addr >= GVP_SERIES_I_RAM_OFFSET && !wd->gdmac.series2) {
+#if GVP_S1_DEBUG_IO > 1
+ int off = wd->gdmac.bufoffset;
+#endif
+ v = wd->gdmac.buffer[wd->gdmac.bufoffset++] << 8;
+ wd->gdmac.bufoffset &= GVP_SERIES_I_RAM_MASK;
+ v |= wd->gdmac.buffer[wd->gdmac.bufoffset++] << 0;
+ wd->gdmac.bufoffset &= GVP_SERIES_I_RAM_MASK;
+#if GVP_S1_DEBUG_IO > 1
+ write_log(_T("gvp_s1_wget sram %d %04x\n"), off, v);
+#endif
} else if (wd->configured) {
- switch (addr)
- {
- case 0x40:
- v = wd->gdmac.cntr;
- break;
- case 0x68:
- v = wd->gdmac.bank;
- break;
- case 0x70:
- v = wd->gdmac.addr >> 16;
- break;
- case 0x72:
- v = wd->gdmac.addr;
- break;
- default:
- write_log(_T("gvp_wget_unk %04X PC=%08X\n"), addr, M68K_GETPC);
- break;
+ if (wd->gdmac.series2) {
+ switch (addr)
+ {
+ case 0x40:
+ v = wd->gdmac.cntr;
+ break;
+ case 0x68:
+ v = wd->gdmac.bank;
+ break;
+ case 0x70:
+ v = wd->gdmac.addr >> 16;
+ break;
+ case 0x72:
+ v = wd->gdmac.addr;
+ break;
+ default:
+ write_log(_T("gvp_s2_wget_unk %04X PC=%08X\n"), addr, M68K_GETPC);
+ break;
+ }
+#if GVP_S2_DEBUG_IO > 0
+ write_log(_T("gvp_s2_wget %04X=%04X PC=%08X\n"), addr, v, M68K_GETPC);
+#endif
+ } else {
+#if GVP_S1_DEBUG_IO > 0
+ write_log(_T("gvp_s1_wget %04X=%04X PC=%08X\n"), addr, v, M68K_GETPC);
+#endif
}
} else {
v = 0xffff;
}
-#if GVP_DEBUG_IO > 0
- write_log(_T("gvp_wget %04X=%04X PC=%08X\n"), addr, v, M68K_GETPC);
-#endif
-
return v;
}
if (addr >= GVP_ROM_OFFSET)
return;
-#if GVP_DEBUG_IO > 0
- write_log(_T("gvp_wput %04X=%04X PC=%08X\n"), addr, b & 65535, M68K_GETPC);
+ if (addr >= GVP_SERIES_I_RAM_OFFSET && !wd->gdmac.series2) {
+#if GVP_S1_DEBUG_IO > 1
+ int off = wd->gdmac.bufoffset;
+#endif
+ wd->gdmac.buffer[wd->gdmac.bufoffset++] = b >> 8;
+ wd->gdmac.bufoffset &= GVP_SERIES_I_RAM_MASK;
+ wd->gdmac.buffer[wd->gdmac.bufoffset++] = b;
+ wd->gdmac.bufoffset &= GVP_SERIES_I_RAM_MASK;
+#if GVP_S1_DEBUG_IO > 1
+ write_log(_T("gvp_s1_wput sram %d %04x\n"), off, b);
+#endif
+ return;
+ }
+
+ if (wd->gdmac.series2) {
+#if GVP_S2_DEBUG_IO > 0
+ write_log(_T("gvp_s2_wput %04X=%04X PC=%08X\n"), addr, b & 65535, M68K_GETPC);
+#endif
+ switch (addr)
+ {
+ case 0x40:
+ b &= ~(1 | 2);
+ wd->gdmac.cntr = b;
+ break;
+ case 0x70: // ACR
+ wd->gdmac.addr &= 0x0000ffff;
+ wd->gdmac.addr |= (b & 0xff) << 16;
+ wd->gdmac.addr &= wd->gdmac.addr_mask;
+ break;
+ case 0x72: // ACR
+ wd->gdmac.addr &= 0xffff0000;
+ wd->gdmac.addr |= b;
+ wd->gdmac.addr &= wd->gdmac.addr_mask;
+ break;
+ case 0x76: // START DMA
+ wd->gdmac.dma_on = 1;
+ break;
+ case 0x78: // STOP DMA
+ wd->gdmac.dma_on = 0;
+ break;
+ case 0x74: // "secret1"
+ case 0x7a: // "secret2"
+ case 0x7c: // "secret3"
+ write_log(_T("gvp_s2_wput_config %04X=%04X PC=%08X\n"), addr, b & 65535, M68K_GETPC);
+ break;
+ default:
+ write_log(_T("gvp_s2_wput_unk %04X=%04X PC=%08X\n"), addr, b & 65535, M68K_GETPC);
+ break;
+ }
+ } else {
+#if GVP_S1_DEBUG_IO > 0
+ write_log(_T("gvp_s1_wput %04X=%04X PC=%08X\n"), addr, b & 65535, M68K_GETPC);
#endif
- switch (addr)
- {
- case 0x40:
- b &= ~(1 | 2);
- wd->gdmac.cntr = b;
- break;
- case 0x70: // ACR
- wd->gdmac.addr &= 0x0000ffff;
- wd->gdmac.addr |= (b & 0xff) << 16;
- wd->gdmac.addr &= wd->gdmac.addr_mask;
- break;
- case 0x72: // ACR
- wd->gdmac.addr &= 0xffff0000;
- wd->gdmac.addr |= b;
- wd->gdmac.addr &= wd->gdmac.addr_mask;
- break;
- case 0x76: // START DMA
- wd->gdmac.dma_on = 1;
- break;
- case 0x78: // STOP DMA
- wd->gdmac.dma_on = 0;
- break;
- case 0x74: // "secret1"
- case 0x7a: // "secret2"
- case 0x7c: // "secret3"
- write_log(_T("gvp_wput_config %04X=%04X PC=%08X\n"), addr, b & 65535, M68K_GETPC);
- break;
- default:
- write_log(_T("gvp_wput_unk %04X=%04X PC=%08X\n"), addr, b & 65535, M68K_GETPC);
- break;
}
}
if (addr >= GVP_ROM_OFFSET)
return;
-#if GVP_DEBUG_IO > 0
- write_log(_T("gvp_bput %04X=%02X PC=%08X\n"), addr, b & 255, M68K_GETPC);
+ if (addr >= GVP_SERIES_I_RAM_OFFSET && !wd->gdmac.series2) {
+ wd->gdmac.buffer[wd->gdmac.bufoffset++] = b;
+ wd->gdmac.bufoffset &= GVP_SERIES_I_RAM_MASK;
+ return;
+ }
+
+ if (wd->gdmac.series2) {
+#if GVP_S2_DEBUG_IO > 0
+ write_log(_T("gvp_s2_bput %04X=%02X PC=%08X\n"), addr, b & 255, M68K_GETPC);
#endif
- switch (addr)
- {
- case 0x40:
- wd->gdmac.cntr &= 0x00ff;
- wd->gdmac.cntr |= b << 8;
- break;
- case 0x41:
- b &= ~(1 | 2);
- wd->gdmac.cntr &= 0xff00;
- wd->gdmac.cntr |= b << 0;
- break;
- case 0x61: // SASR
- wdscsi_sasr(&wd->wc, b);
- break;
- case 0x63: // SCMD
- wdscsi_put(&wd->wc, wd, b);
- break;
- case 0x74: // "secret1"
- case 0x75:
- case 0x7a: // "secret2"
- case 0x7b:
- case 0x7c: // "secret3"
- case 0x7d:
- write_log(_T("gvp_bput_config %04X=%04X PC=%08X\n"), addr, b & 255, M68K_GETPC);
- break;
- default:
- write_log(_T("gvp_bput_unk %04X=%02X PC=%08X\n"), addr, b & 255, M68K_GETPC);
- break;
+ switch (addr)
+ {
+ case 0x40:
+ wd->gdmac.cntr &= 0x00ff;
+ wd->gdmac.cntr |= b << 8;
+ break;
+ case 0x41:
+ b &= ~(1 | 2);
+ wd->gdmac.cntr &= 0xff00;
+ wd->gdmac.cntr |= b << 0;
+ break;
+ case 0x61: // SASR
+ wdscsi_sasr(&wd->wc, b);
+ break;
+ case 0x63: // SCMD
+ wdscsi_put(&wd->wc, wd, b);
+ break;
+
+ case 0x74: // "secret1"
+ case 0x75:
+ case 0x7a: // "secret2"
+ case 0x7b:
+ case 0x7c: // "secret3"
+ case 0x7d:
+ write_log(_T("gvp_s2_bput_config %04X=%04X PC=%08X\n"), addr, b & 255, M68K_GETPC);
+ break;
+ default:
+ write_log(_T("gvp_s2_bput_unk %04X=%02X PC=%08X\n"), addr, b & 255, M68K_GETPC);
+ break;
+ }
+ } else {
+#if GVP_S1_DEBUG_IO > 0
+ write_log(_T("gvp_s1_bput %04X=%02X PC=%08X\n"), addr, b & 255, M68K_GETPC);
+#endif
+ switch (addr)
+ {
+ case 0x60: // SASR
+ wdscsi_sasr(&wd->wc, b);
+ break;
+ case 0x62: // SCMD
+ wdscsi_put(&wd->wc, wd, b);
+ break;
+
+ // 68:
+ // 00 CPU SRAM access
+ // ff WD SRAM access
+
+ // 6c:
+ // 28 0010 startup reset?
+ // b8 1011 before CPU reading from SRAM
+ // a8 1100 before CPU writing to SRAM
+ // e8 1110 before starting WD write DMA
+ // f8 1111 access done/start WD read DMA
+ // 08 = intena?
+
+ case 0x68:
+#if GVP_S1_DEBUG_IO > 0
+ write_log(_T("gvp_s1_bput_s1 %04X=%04X PC=%08X\n"), addr, b & 255, M68K_GETPC);
+#endif
+ wd->gdmac.bufoffset = 0;
+ break;
+ case 0x6c:
+#if GVP_S1_DEBUG_IO > 0
+ write_log(_T("gvp_s1_bput_s1 %04X=%04X PC=%08X\n"), addr, b & 255, M68K_GETPC);
+#endif
+ wd->gdmac.cntr = b & 8;
+ break;
+
+ default:
+ write_log(_T("gvp_s1_bput_unk %04X=%02X PC=%08X\n"), addr, b & 255, M68K_GETPC);
+ break;
+ }
}
+
}
static uae_u32 REGPARAM2 dmac_gvp_lget(struct wd_state *wd, uaecptr addr)
special_mem |= S_READ;
#endif
addr &= 65535;
- if (addr >= GVP_ROM_OFFSET)
+ if (addr >= GVP_ROM_OFFSET) {
+ addr -= GVP_ROM_OFFSET;
v = (wd->rom[addr & wd->rom_mask] << 8) | wd->rom[(addr + 1) & wd->rom_mask];
- else
+ } else {
write_log(_T("Invalid GVP instruction access %08x\n"), addr);
+ }
return v;
}
static uae_u32 REGPARAM2 dmac_gvp_lgeti(struct wd_state *wd, uaecptr addr)
dmac_gvp_xlate, dmac_gvp_check, NULL, NULL, _T("GVP"),
dmac_gvp_lgeti, dmac_gvp_wgeti, ABFLAG_IO | ABFLAG_SAFE
};
+
+static uae_u8 *REGPARAM2 dmac_gvp_2_xlate(uaecptr addr)
+{
+ return dmac_gvp_xlate(&wd_gvp_2, addr);
+}
+static int REGPARAM2 dmac_gvp_2_check(uaecptr addr, uae_u32 size)
+{
+ return dmac_gvp_check(&wd_gvp_2, addr, size);
+}
+static uae_u32 REGPARAM2 dmac_gvp_2_lgeti(uaecptr addr)
+{
+ return dmac_gvp_lgeti(&wd_gvp_2, addr);
+}
+static uae_u32 REGPARAM2 dmac_gvp_2_wgeti(uaecptr addr)
+{
+ return dmac_gvp_wgeti(&wd_gvp_2, addr);
+}
+static uae_u32 REGPARAM2 dmac_gvp_2_bget(uaecptr addr)
+{
+ return dmac_gvp_bget(&wd_gvp_2, addr);
+}
+static uae_u32 REGPARAM2 dmac_gvp_2_wget(uaecptr addr)
+{
+ return dmac_gvp_wget(&wd_gvp_2, addr);
+}
+static uae_u32 REGPARAM2 dmac_gvp_2_lget(uaecptr addr)
+{
+ return dmac_gvp_lget(&wd_gvp_2, addr);
+}
+static void REGPARAM2 dmac_gvp_2_bput(uaecptr addr, uae_u32 b)
+{
+ dmac_gvp_bput(&wd_gvp_2, addr, b);
+}
+static void REGPARAM2 dmac_gvp_2_wput(uaecptr addr, uae_u32 b)
+{
+ dmac_gvp_wput(&wd_gvp_2, addr, b);
+}
+static void REGPARAM2 dmac_gvp_2_lput(uaecptr addr, uae_u32 b)
+{
+ dmac_gvp_lput(&wd_gvp_2, addr, b);
+}
+
addrbank gvp_2_bank = {
- dmac_gvp_lget, dmac_gvp_wget, dmac_gvp_bget,
- dmac_gvp_lput, dmac_gvp_wput, dmac_gvp_bput,
- dmac_gvp_xlate, dmac_gvp_check, NULL, NULL, _T("GVP #2"),
- dmac_gvp_lgeti, dmac_gvp_wgeti, ABFLAG_IO | ABFLAG_SAFE
+ dmac_gvp_2_lget, dmac_gvp_2_wget, dmac_gvp_2_bget,
+ dmac_gvp_2_lput, dmac_gvp_2_wput, dmac_gvp_2_bput,
+ dmac_gvp_2_xlate, dmac_gvp_2_check, NULL, NULL, _T("GVP #2"),
+ dmac_gvp_2_lgeti, dmac_gvp_2_wgeti, ABFLAG_IO | ABFLAG_SAFE
};
/* SUPERDMAC (A3000 mainboard built-in) */
wd_cmd_sel_xfer (wd, wds, false);
break;
case WD_CMD_TRANS_INFO:
- wd_cmd_trans_info (wd, wd->scsi);
+ wd_cmd_trans_info (wds, wd->scsi);
break;
case WD_CMD_TRANS_ADDR:
wd_cmd_trans_addr(wd, wds);
}
}
-static void freescsi (struct scsi_data *sd)
-{
- if (!sd)
- return;
- hdf_hd_close (sd->hfd);
- scsi_free (sd);
-}
-
-int add_wd_scsi_hd (struct wd_state *wd, int ch, struct hd_hardfiledata *hfd, struct uaedev_config_info *ci, int scsi_level)
-{
- freescsi (wd->scsis[ch]);
- wd->scsis[ch] = NULL;
- if (!hfd) {
- hfd = xcalloc (struct hd_hardfiledata, 1);
- memcpy (&hfd->hfd.ci, ci, sizeof (struct uaedev_config_info));
- }
- if (!hdf_hd_open (hfd))
- return 0;
- hfd->ansi_version = scsi_level;
- wd->scsis[ch] = scsi_alloc_hd (ch, hfd);
- return wd->scsis[ch] ? 1 : 0;
-}
-
-int add_wd_scsi_cd (struct wd_state *wd, int ch, int unitnum)
-{
- device_func_init (0);
- freescsi (wd->scsis[ch]);
- wd->scsis[ch] = scsi_alloc_cd (ch, unitnum, false);
- return wd->scsis[ch] ? 1 : 0;
-}
-
-int add_wd_scsi_tape (struct wd_state *wd, int ch, const TCHAR *tape_directory, bool readonly)
-{
- freescsi (wd->scsis[ch]);
- wd->scsis[ch] = scsi_alloc_tape (ch, tape_directory, readonly);
- return wd->scsis[ch] ? 1 : 0;
-}
-
-static void freenativescsi (struct wd_state *wd)
-{
- int i;
- for (i = 0; i < 8; i++) {
- freescsi (wd->scsis[i]);
- wd->scsis[i] = NULL;
- }
-}
-
-static void addnativescsi (struct wd_state *wd)
-{
- int i, j;
- int devices[MAX_TOTAL_SCSI_DEVICES];
- int types[MAX_TOTAL_SCSI_DEVICES];
- struct device_info dis[MAX_TOTAL_SCSI_DEVICES];
-
- freenativescsi (wd);
- i = 0;
- while (i < MAX_TOTAL_SCSI_DEVICES) {
- types[i] = -1;
- devices[i] = -1;
- if (sys_command_open (i)) {
- if (sys_command_info (i, &dis[i], 0)) {
- devices[i] = i;
- types[i] = 100 - i;
- if (dis[i].type == INQ_ROMD)
- types[i] = 1000 - i;
- }
- sys_command_close (i);
- }
- i++;
- }
- i = 0;
- while (devices[i] >= 0) {
- j = i + 1;
- while (devices[j] >= 0) {
- if (types[i] > types[j]) {
- int tmp = types[i];
- types[i] = types[j];
- types[j] = tmp;
- }
- j++;
- }
- i++;
- }
- i = 0; j = 0;
- while (devices[i] >= 0 && j < 7) {
- if (wd->scsis[j] == NULL) {
- wd->scsis[j] = scsi_alloc_native(j, devices[i]);
- write_log (_T("SCSI: %d:'%s'\n"), j, dis[i].label);
- i++;
- }
- j++;
- }
-}
-
int a3000_add_scsi_unit (int ch, struct uaedev_config_info *ci)
{
struct wd_state *wd = &wd_a3000;
if (ci->type == UAEDEV_CD)
- return add_wd_scsi_cd (wd, ch, ci->device_emu_unit);
+ return add_scsi_cd (wd->scsis, ch, ci->device_emu_unit);
else if (ci->type == UAEDEV_TAPE)
- return add_wd_scsi_tape (wd, ch, ci->rootdir, ci->readonly);
+ return add_scsi_tape (wd->scsis, ch, ci->rootdir, ci->readonly);
else
- return add_wd_scsi_hd (wd, ch, NULL, ci, 2);
+ return add_scsi_hd (wd->scsis, ch, NULL, ci, 2);
}
void a3000scsi_reset (void)
void a3000scsi_free (void)
{
struct wd_state *wd = &wd_a3000;
- freenativescsi (wd);
+ scsi_freenative(wd->scsis);
if (wd->scsi_thread_running > 0) {
wd->scsi_thread_running = 0;
write_comm_pipe_u32 (&wd->requests, 0xffffffff, 1);
struct wd_state *wd = wda2091[devnum];
if (ci->type == UAEDEV_CD)
- return add_wd_scsi_cd(wd, ch, ci->device_emu_unit);
+ return add_scsi_cd(wd->scsis, ch, ci->device_emu_unit);
else if (ci->type == UAEDEV_TAPE)
- return add_wd_scsi_tape(wd, ch, ci->rootdir, ci->readonly);
+ return add_scsi_tape(wd->scsis, ch, ci->rootdir, ci->readonly);
else
- return add_wd_scsi_hd(wd, ch, NULL, ci, 1);
+ return add_scsi_hd(wd->scsis, ch, NULL, ci, 1);
}
int gvp_add_scsi_unit(int ch, struct uaedev_config_info *ci, int devnum)
struct wd_state *wd = gvpscsi[devnum];
if (ci->type == UAEDEV_CD)
- return add_wd_scsi_cd(wd, ch, ci->device_emu_unit);
+ return add_scsi_cd(wd->scsis, ch, ci->device_emu_unit);
else if (ci->type == UAEDEV_TAPE)
- return add_wd_scsi_tape(wd, ch, ci->rootdir, ci->readonly);
+ return add_scsi_tape(wd->scsis, ch, ci->rootdir, ci->readonly);
else
- return add_wd_scsi_hd(wd, ch, NULL, ci, 2);
+ return add_scsi_hd(wd->scsis, ch, NULL, ci, 2);
}
void a2091_free_device (struct wd_state *wd)
{
- freenativescsi (wd);
+ scsi_freenative(wd->scsis);
xfree (wd->rom);
wd->rom = NULL;
}
wd->dmac_type = COMMODORE_DMAC;
wd->cdmac.old_dmac = 0;
if (currprefs.scsi == 2)
- addnativescsi (wd);
+ scsi_addnative(wd->scsis);
wd_cmd_reset (&wd->wc, false);
reset_dmac(wd);
if (wd == &wd_a2091)
void gvp_free_device (struct wd_state *wd)
{
- freenativescsi (wd);
+ scsi_freenative(wd->scsis);
xfree (wd->rom);
wd->rom = NULL;
}
wd->configured = 0;
wd->wc.wd_used = 0;
wd->wc.wd33c93_ver = 1;
- wd->dmac_type = GVP_DMAC;
- wd->gdmac.version = GVP_SERIESII;
- if (wd->gdmac.series2)
- wd->gdmac.version |= 1;
- wd->gdmac.addr_mask = 0x00ffffff;
+ wd->dmac_type = wd->gdmac.series2 ? GVP_DMAC_S2 : GVP_DMAC_S1;
if (currprefs.scsi == 2)
- addnativescsi (wd);
+ scsi_addnative(wd->scsis);
wd_cmd_reset (&wd->wc, false);
reset_dmac(wd);
if (wd == &wd_gvp)
static const uae_u8 gvp_scsi_i_autoconfig[16] = { 0xd1, 0x09, 0x00, 0x00, 0x07, 0xe1, 0xee, 0xee, 0xee, 0xee, 0x80, 0x00 };
static const uae_u8 gvp_scsi_ii_autoconfig[16] = { 0xd1, 0x0b, 0x00, 0x00, 0x07, 0xe1, 0xee, 0xee, 0xee, 0xee, 0x80, 0x00 };
-addrbank *gvp_init(int devnum)
+addrbank *gvp_init(int devnum, bool series2)
{
struct wd_state *wd = gvpscsi[devnum];
int roms[6];
struct romlist *rl;
+ struct boardromconfig *brc = series2 ? &currprefs.gvps2rom : &currprefs.gvps1rom;
- if (devnum > 0 && !wd->enabled)
+ if (devnum > 0 && !wd->enabled && currprefs.cpuboard_type != BOARD_GVP_A530)
return &expamem_null;
init_wd_scsi(wd);
wd->autoconfig = true;
wd->rombankswitcher = 0;
memset(wd->dmacmemory, 0xff, sizeof wd->dmacmemory);
+ wd->gdmac.series2 = series2;
+ wd->gdmac.version = GVP_SERIESII;
+ wd->gdmac.addr_mask = 0x00ffffff;
+ if (currprefs.cpuboard_type == BOARD_GVP_A530) {
+ wd->gdmac.version = GVP_A530_SCSI;
+ wd->gdmac.addr_mask = 0x01ffffff;
+ }
roms[0] = 109;
roms[1] = 110;
wd->rom_size = 32768;
wd->rom = xcalloc(uae_u8, wd->rom_size);
memset(wd->rom, 0xff, wd->rom_size);
- wd->rom_mask = wd->rom_size - 1;
- wd->gdmac.series2 = true;
-
- for (int i = 0; i < 16; i++) {
- uae_u8 b = wd->gdmac.series2 ? gvp_scsi_ii_autoconfig[i] : gvp_scsi_i_autoconfig[i];
- ew(wd, i * 4, b);
- }
+ wd->rom_mask = 32768 - 1;
- if (_tcscmp (currprefs.gvprom.roms[0].romfile, _T(":NOROM"))) {
- const TCHAR *romname = devnum && currprefs.gvprom.roms[1].romfile[0] ? currprefs.gvprom.roms[1].romfile : currprefs.gvprom.roms[0].romfile;
+ if (_tcscmp (brc->roms[0].romfile, _T(":NOROM"))) {
+ const TCHAR *romname = devnum && brc->roms[1].romfile[0] ? brc->roms[1].romfile : brc->roms[0].romfile;
struct zfile *z = read_rom_name(romname);
if (!z) {
rl = getromlistbyids(roms, romname);
if (rl) {
z = read_rom(rl->rd);
}
- if (rl && rl->rd && rl->rd->id == 111)
- wd->gdmac.series2 = false;
}
if (z) {
write_log(_T("GVP BOOT ROM '%s'\n"), zfile_getname(z));
- int size = zfile_fread(wd->rom, 1, wd->rom_size, z);
+ int size = zfile_size(z);
+ if (series2) {
+ zfile_fread(wd->rom, 1, wd->rom_size, z);
+ } else {
+ xfree(wd->gdmac.buffer);
+ wd->gdmac.buffer = xcalloc(uae_u8, GVP_SERIES_I_RAM_MASK + 1);
+ for (int i = 0; i < 16384; i++) {
+ uae_u8 b;
+ zfile_fread(&b, 1, 1, z);
+ wd->rom[i] = b;
+ }
+ }
zfile_fclose(z);
- if (size > 16384) {
+ if (series2 && size > 16384) {
wd->rombankswitcher = 1;
}
} else {
romwarning(roms);
}
}
+
+ for (int i = 0; i < 16; i++) {
+ uae_u8 b = wd->gdmac.series2 ? gvp_scsi_ii_autoconfig[i] : gvp_scsi_i_autoconfig[i];
+ ew(wd, i * 4, b);
+ }
+ gvp_reset_device(wd);
return wd == &wd_gvp ? &gvp_bank : &gvp_2_bank;
}
wd->cdmac.xt_control = restore_u8();
}
if (size)
- add_wd_scsi_hd (wd, num, hfd, NULL, s->hfd->ansi_version);
+ add_scsi_hd (wd->scsis, num, hfd, NULL, s->hfd->ansi_version);
xfree (path);
break;
case UAEDEV_CD:
num2 = restore_u32 ();
- add_wd_scsi_cd (wd, num, num2);
+ add_scsi_cd (wd->scsis, num, num2);
break;
case UAEDEV_TAPE:
num2 = restore_u32 ();
blocksize = restore_u32 ();
readonly = restore_u32 ();
path = restore_string ();
- add_wd_scsi_tape (wd, num, path, readonly != 0);
+ add_scsi_tape (wd->scsis, num, path, readonly != 0);
xfree (path);
break;
}
#include "a2091.h"
#include "uae.h"
#include "savestate.h"
+#include "scsi.h"
/* DMAC CNTR bits. */
#define CNTR_TCEN (1<<7)
int cdtv_add_scsi_hd_unit (int ch, struct uaedev_config_info *ci)
{
- return add_wd_scsi_hd (&wd_cdtv, ch, NULL, ci, 1);
+ return add_scsi_hd (wd_cdtv.scsis, ch, NULL, ci, 1);
}
void cdtv_free (void)
_T("FusionForty"),
_T("A3001SI"),
_T("A3001SII"),
+ _T("Apollo"),
+ _T("GVPA530"),
NULL
};
static const TCHAR *ppc_implementations[] = {
static const TCHAR *waitblits[] = { _T("disabled"), _T("automatic"), _T("noidleonly"), _T("always"), 0 };
static const TCHAR *autoext2[] = { _T("disabled"), _T("copy"), _T("replace"), 0 };
static const TCHAR *leds[] = { _T("power"), _T("df0"), _T("df1"), _T("df2"), _T("df3"), _T("hd"), _T("cd"), _T("fps"), _T("cpu"), _T("snd"), _T("md"), 0 };
-static int leds_order[] = { 3, 6, 7, 8, 9, 4, 5, 2, 1, 0, 9 };
+static const int leds_order[] = { 3, 6, 7, 8, 9, 4, 5, 2, 1, 0, 9 };
static const TCHAR *lacer[] = { _T("off"), _T("i"), _T("p"), 0 };
static const TCHAR *hdcontrollers[] = {
_T("uae"),
- _T("ide%d"), _T("ide%d_mainboard"), _T("ide%d_a3001"),
- _T("scsi%d"), _T("scsi%d_a2091"), _T("scsi%d_a2091-2"), _T("scsi%d_gvp"), _T("scsi%d_gvp-2"), _T("scsi%d_a4091"), _T("scsi%d_a4091-2"),
+
+ _T("ide%d"),
+ _T("ide%d_mainboard"),
+ _T("ide%d_a3001"),
+ _T("ide%d_alfa"), _T("ide%d_alfa-2"),
+ _T("ide%d_apollo"), _T("ide%d_apollo-2"),
+ _T("ide%d_masoboshi"), _T("ide%d_masoboshi-2"),
+ //_T("ide%d_adide"), _T("ide%d_adide-2"),
+
+ _T("scsi%d"),
+ _T("scsi%d_a2091"), _T("scsi%d_a2091-2"),
+ _T("scsi%d_gvp"), _T("scsi%d_gvp-2"),
+ _T("scsi%d_a4091"), _T("scsi%d_a4091-2"),
_T("scsi%d_fastlane"), _T("scsi%d_fastlane-2"),
_T("scsi%d_oktagon2008"), _T("scsi%d_oktagon2008-2"),
- _T("scsi%d_a3000"), _T("scsi%d_a4000t"), _T("scsi%d_cdtv"), _T("scsi%d_cpuboard"),
- _T("scsram"), _T("scide")
+ _T("scsi%d_apollo"), _T("scsi%d_apollo-2"),
+ _T("scsi%d_masoboshi"), _T("scsi%d_masoboshi-2"),
+ _T("scsi%d_a3000"),
+ _T("scsi%d_a4000t"),
+ _T("scsi%d_cdtv"),
+ _T("scsi%d_cpuboard"),
+
+ _T("scsram"),
+ _T("scide")
};
static const TCHAR *z3mapping[] = {
_T("auto"),
_T("gfx_filter_vert_offset"), _T("gfx_filter_horiz_offset"),
_T("rtg_vert_zoom_multf"), _T("rtg_horiz_zoom_multf"),
+ // created by some buggy beta
+ _T("uaehf0%s,%s"),
+ _T("uaehf1%s,%s"),
+ _T("uaehf2%s,%s"),
+ _T("uaehf3%s,%s"),
+ _T("uaehf4%s,%s"),
+ _T("uaehf5%s,%s"),
+ _T("uaehf6%s,%s"),
+ _T("uaehf7%s,%s"),
+
NULL
};
cfgfile_write_str (f, _T("kickstart_ext_rom="), p->romextident);
cfgfile_write_board_rom(f, &p->path_rom, &p->a2091rom, _T("a2091"));
- cfgfile_write_board_rom(f, &p->path_rom, &p->gvprom, _T("gvp"));
+ cfgfile_write_board_rom(f, &p->path_rom, &p->gvps1rom, _T("gvp1"));
+ cfgfile_write_board_rom(f, &p->path_rom, &p->gvps2rom, _T("gvp"));
cfgfile_write_board_rom(f, &p->path_rom, &p->a4091rom, _T("a4091"));
cfgfile_write_board_rom(f, &p->path_rom, &p->fastlanerom, _T("fastlane"));
cfgfile_write_board_rom(f, &p->path_rom, &p->oktagonrom, _T("oktagon2008"));
+ cfgfile_write_board_rom(f, &p->path_rom, &p->alfrom, _T("alfapower"));
+ cfgfile_write_board_rom(f, &p->path_rom, &p->alfplusrom, _T("alfapowerplus"));
+ cfgfile_write_board_rom(f, &p->path_rom, &p->apollorom, _T("apollo"));
+ cfgfile_write_board_rom(f, &p->path_rom, &p->masoboshirom, _T("masoboshi"));
cfgfile_write_rom(f, &p->path_rom, p->acceleratorromfile, _T("cpuboard_rom_file"));
if (p->acceleratorromident[0])
const TCHAR *ext2 = _tcsrchr(hdcontrollers[i], '_');
if (ext2) {
ext2++;
- if (!_tcsicmp(ext, ext2)) {
+ if (!_tcsicmp(ext, ext2) && hdc[0] == hdcontrollers[i][0]) {
hdcv = i;
break;
}
if (cfgfile_read_board_rom(option, value, &p->path_rom, &p->a2091rom, _T("a2091"), ROMTYPE_A2091))
return 1;
- if (cfgfile_read_board_rom(option, value, &p->path_rom, &p->gvprom, _T("gvp"), ROMTYPE_GVP))
+ if (cfgfile_read_board_rom(option, value, &p->path_rom, &p->gvps1rom, _T("gvp1"), ROMTYPE_GVPS1))
+ return 1;
+ if (cfgfile_read_board_rom(option, value, &p->path_rom, &p->gvps2rom, _T("gvp"), ROMTYPE_GVPS2))
return 1;
if (cfgfile_read_board_rom(option, value, &p->path_rom, &p->a4091rom, _T("a4091"), ROMTYPE_A4091))
return 1;
return 1;
if (cfgfile_read_board_rom(option, value, &p->path_rom, &p->oktagonrom, _T("oktagon2008"), ROMTYPE_OKTAGON))
return 1;
+ if (cfgfile_read_board_rom(option, value, &p->path_rom, &p->alfrom, _T("alfapower"), ROMTYPE_ALFA))
+ return 1;
+ if (cfgfile_read_board_rom(option, value, &p->path_rom, &p->alfplusrom, _T("alfapowerplus"), ROMTYPE_ALFAPLUS))
+ return 1;
+ if (cfgfile_read_board_rom(option, value, &p->path_rom, &p->apollorom, _T("apollo"), ROMTYPE_APOLLO))
+ return 1;
+ if (cfgfile_read_board_rom(option, value, &p->path_rom, &p->masoboshirom, _T("masoboshi"), ROMTYPE_MASOBOSHI))
+ return 1;
for (i = 0; i < 4; i++) {
_stprintf (tmpbuf, _T("floppy%d"), i);
for (i = 0; i < MAX_BOARD_ROMS; i++) {
subst(p->path_rom.path[0], p->a2091rom.roms[i].romfile, MAX_DPATH / sizeof(TCHAR));
- subst(p->path_rom.path[0], p->gvprom.roms[i].romfile, MAX_DPATH / sizeof(TCHAR));
+ subst(p->path_rom.path[0], p->gvps1rom.roms[i].romfile, MAX_DPATH / sizeof(TCHAR));
+ subst(p->path_rom.path[0], p->gvps2rom.roms[i].romfile, MAX_DPATH / sizeof(TCHAR));
subst(p->path_rom.path[0], p->a4091rom.roms[i].romfile, MAX_DPATH / sizeof(TCHAR));
subst(p->path_rom.path[0], p->fastlanerom.roms[i].romfile, MAX_DPATH / sizeof (TCHAR));
+ subst(p->path_rom.path[0], p->alfrom.roms[i].romfile, MAX_DPATH / sizeof (TCHAR));
+ subst(p->path_rom.path[0], p->alfplusrom.roms[i].romfile, MAX_DPATH / sizeof (TCHAR));
+ subst(p->path_rom.path[0], p->masoboshirom.roms[i].romfile, MAX_DPATH / sizeof (TCHAR));
}
return 1;
roms[2] = 31;
roms[3] = -1;
p->cs_rtc = 0;
+ p->cs_compatible = CP_A1200;
+ built_in_chipset_prefs (p);
switch (config)
{
case 1:
break;
}
set_68020_compa (p, compa, 0);
- p->cs_compatible = CP_A1200;
- built_in_chipset_prefs (p);
return configure_rom (p, roms, romcheck);
}
roms[1] = 9;
roms[2] = 8;
roms[3] = -1;
+ set_68000_compa (p, compa);
+ p->cs_compatible = CP_A600;
+ built_in_chipset_prefs (p);
p->bogomem_size = 0;
p->chipmem_size = 0x100000;
if (config > 0)
if (config == 2)
p->fastmem_size = 0x400000;
p->chipset_mask = CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE;
- set_68000_compa (p, compa);
- p->cs_compatible = CP_A600;
- built_in_chipset_prefs (p);
return configure_rom (p, roms, romcheck);
}
roms[0] = 7;
roms[1] = -1;
+ set_68000_compa (p, compa);
+ p->cs_compatible = CP_A500P;
+ built_in_chipset_prefs (p);
p->bogomem_size = 0;
p->chipmem_size = 0x100000;
if (config > 0)
if (config == 2)
p->fastmem_size = 0x400000;
p->chipset_mask = CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE;
- set_68000_compa (p, compa);
- p->cs_compatible = CP_A500P;
- built_in_chipset_prefs (p);
return configure_rom (p, roms, romcheck);
}
static int bip_a500 (struct uae_prefs *p, int config, int compa, int romcheck)
#include "flashrom.h"
#include "uae.h"
#include "uae/ppc.h"
+#include "idecontrollers.h"
+#include "scsi.h"
#define CPUBOARD_IO_LOG 0
#define CPUBOARD_IRQ_LOG 0
{
return currprefs.cpuboard_type == BOARD_FUSIONFORTY;
}
+static bool is_apollo(void)
+{
+ return currprefs.cpuboard_type == BOARD_APOLLO;
+}
DECLARE_MEMORY_FUNCTIONS(blizzardio);
static addrbank blizzardio_bank = {
addr &= 65535;
if (addr == 0x48 && !configured) {
map_banks(&blizzardea_bank, b, 0x20000 >> 16, 0x20000);
- write_log(_T("Blizzard/CyberStorm Z2 autoconfigured at %02X0000\n"), b);
+ write_log(_T("Accelerator Z2 board autoconfigured at %02X0000\n"), b);
configured = 1;
expamem_next (&blizzardea_bank, NULL);
return;
map_banks(&blizzardio_bank, 0x021d0000 >> 16, 65536 >> 16, 0);
map_banks(&blizzardram_bank, blizzardram_bank.start >> 16, cpuboard_size >> 16, 0);
}
+ if (is_apollo()) {
+ map_banks(&blizzardf0_bank, 0xf00000 >> 16, 131072 >> 16, 0);
+ }
}
void cpuboard_reset(void)
blizzardea_bank.mask = blizzardea_bank.allocated - 1;
mapped_malloc(&blizzardea_bank);
+ } else if (is_apollo()) {
+
+ blizzardf0_bank.start = 0x00f00000;
+ blizzardf0_bank.allocated = 131072;
+ blizzardf0_bank.mask = blizzardf0_bank.allocated - 1;
+ mapped_malloc(&blizzardf0_bank);
+
} else if (is_fusionforty()) {
blizzardf0_bank.start = 0x00f40000;
case BOARD_TEKMAGIC:
case BOARD_FUSIONFORTY:
case BOARD_DKB1200: // ??
+ case BOARD_APOLLO:
return BOARD_MEMORY_HIGHMEM;
case BOARD_A2630:
+ case BOARD_GVP_A530:
return BOARD_MEMORY_Z2;
case BOARD_BLIZZARD_1230_IV:
case BOARD_BLIZZARD_1230_IV_SCSI:
roms[0] = 105;
roms[1] = 106;
break;
+ case BOARD_GVP_A530:
+ return &expamem_null;
+ case BOARD_APOLLO:
+ roms[0] = 119;
+ break;
case BOARD_A3001_I:
case BOARD_A3001_II:
return &expamem_null;
return &expamem_null;
}
- struct romlist *rl = getromlistbyids(roms, romname);
- if (!rl) {
- rd = getromdatabyids(roms);
- if (!rd)
- return &expamem_null;
- } else {
- rd = rl->rd;
+ struct romlist *rl = NULL;
+ if (roms[0] >= 0) {
+ getromlistbyids(roms, romname);
+ if (!rl) {
+ rd = getromdatabyids(roms);
+ if (!rd)
+ return &expamem_null;
+ } else {
+ rd = rl->rd;
+ }
+ defaultromname = rd->defaultfilename;
}
- defaultromname = rd->defaultfilename;
- if (rl && !isflashrom) {
+ if (!isflashrom) {
if (romname)
autoconfig_rom = zfile_fopen(romname, _T("rb"));
if (!autoconfig_rom && defaultromname)
autoconfig_rom = zfile_fopen(defaultromname, _T("rb"));
- if (autoconfig_rom) {
- struct romdata *rd2 = getromdatabyids(roms);
- // Do not use image if it is not long enough (odd or even only?)
- if (!rd2 || zfile_size(autoconfig_rom) < rd2->size) {
- zfile_fclose(autoconfig_rom);
- autoconfig_rom = NULL;
+ if (rl) {
+ if (autoconfig_rom) {
+ struct romdata *rd2 = getromdatabyids(roms);
+ // Do not use image if it is not long enough (odd or even only?)
+ if (!rd2 || zfile_size(autoconfig_rom) < rd2->size) {
+ zfile_fclose(autoconfig_rom);
+ autoconfig_rom = NULL;
+ }
}
+ if (!autoconfig_rom)
+ autoconfig_rom = read_rom(rl->rd);
}
- if (!autoconfig_rom)
- autoconfig_rom = read_rom(rl->rd);
- } else if (isflashrom) {
+ } else {
autoconfig_rom = flashfile_open(romname);
if (!autoconfig_rom) {
if (rl)
write_log (_T("ROM id %d not found for CPU board emulation\n"), roms[0]);
return &expamem_null;
}
- if (autoconfig_rom)
- write_log(_T("CPUBoard ROM '%s' %lld loaded\n"), zfile_getname(autoconfig_rom), zfile_size(autoconfig_rom));
+ if (!autoconfig_rom) {
+ write_log(_T("Couldn't open CPU board rom '%s'\n"), defaultromname);
+ return &expamem_null;
+ }
+
+ write_log(_T("CPUBoard ROM '%s' %lld loaded\n"), zfile_getname(autoconfig_rom), zfile_size(autoconfig_rom));
protect_roms(false);
cpuboard_non_byte_ea = true;
zfile_fread(blizzardf0_bank.baseaddr, 1, f0rom_size, autoconfig_rom);
autoconf = false;
autoconf_stop = true;
+ } else if (is_apollo()) {
+ f0rom_size = 131072;
+ zfile_fread(blizzardf0_bank.baseaddr, 1, 131072, autoconfig_rom);
+ autoconf = false;
} else if (is_fusionforty()) {
f0rom_size = 262144;
zfile_fread(blizzardf0_bank.baseaddr, 1, 131072, autoconfig_rom);
DISK_reset ();
CIA_reset ();
gayle_reset (0);
+ apolloscsi_reset();
#ifdef A2091
a2091_reset ();
gvp_reset ();
gvp_free ();
a3000scsi_free ();
#endif
+ apolloscsi_free();
#ifdef NCR
ncr710_free();
ncr_free();
int allocated = boardnum ? fastmem2_bank.allocated : fastmem_bank.allocated;
uae_u32 serial = 1;
+ if (allocated == 0)
+ return &expamem_null;
+
expamem_init_clear ();
if (allocated == 65536)
type |= Z2_MEM_64KB;
pid = commodore_a2091_ram;
mid = commodore;
serial = 0;
- } else if (cfgfile_board_enabled(&currprefs.gvprom) || currprefs.cpuboard_type == BOARD_A3001_I || currprefs.cpuboard_type == BOARD_A3001_II) {
+ } else if (cfgfile_board_enabled(&currprefs.gvps1rom) || cfgfile_board_enabled(&currprefs.gvps2rom) || currprefs.cpuboard_type == BOARD_A3001_I || currprefs.cpuboard_type == BOARD_A3001_II) {
pid = 10;
mid = 2017;
serial = 0;
+ } else if (cfgfile_board_enabled(&currprefs.alfrom) || cfgfile_board_enabled(&currprefs.alfplusrom)) {
+ pid = 8;
+ mid = 2092;
+ serial = 0;
+ } else if (cfgfile_board_enabled(&currprefs.apollorom)) {
+ pid = 0;
+ mid = 8738;
+ serial = 0;
+ } else if (cfgfile_board_enabled(&currprefs.masoboshirom)) {
+ pid = 3;
+ mid = 2157;
+ serial = 0;
} else {
pid = currprefs.maprom && !currprefs.cpuboard_type ? 1 : 81;
mid = uae_id;
return v;
}
+static addrbank *expamem_init_masoboshi(void)
+{
+ return masoboshi_init (0);
+}
+static addrbank *expamem_init_masoboshi_2(void)
+{
+ return masoboshi_init (1);
+}
+static addrbank *expamem_init_alf(void)
+{
+ return alf_init (0);
+}
+static addrbank *expamem_init_alf_2(void)
+{
+ return alf_init (1);
+}
+static addrbank *expamem_init_apollo(void)
+{
+ return apollo_init (0);
+}
+static addrbank *expamem_init_apollo_2(void)
+{
+ return apollo_init (1);
+}
+static addrbank *expamem_init_apollo_cpu(void)
+{
+ return apollo_init (-1);
+}
#ifdef WITH_TOCCATA
static addrbank *expamem_init_toccata(void)
{
{
return a2091_init (0);
}
-#endif
-#ifdef A2091
static addrbank *expamem_init_a2091_2(void)
{
return a2091_init (1);
}
#endif
#ifdef A2091
-static addrbank *expamem_init_gvp(void)
+static addrbank *expamem_init_gvp_s1(void)
{
- return gvp_init(0);
+ return gvp_init(0, false);
}
-#endif
-#ifdef A2091
-static addrbank *expamem_init_gvp_2(void)
+static addrbank *expamem_init_gvp_s1_2(void)
{
- return gvp_init(1);
+ return gvp_init(1, false);
+}
+static addrbank *expamem_init_gvp_s2(void)
+{
+ return gvp_init(0, true);
+}
+static addrbank *expamem_init_gvp_s2_2(void)
+{
+ return gvp_init(1, true);
}
#endif
#ifdef NCR
card_init[cardno] = expamem_init_a3001_ide;
card_map[cardno++] = NULL;
}
+ if (currprefs.cpuboard_type == BOARD_GVP_A530) {
+ card_flags[cardno] = 1;
+ card_name[cardno] = _T("GVP A530");
+ card_init[cardno] = expamem_init_gvp_s2_2;
+ card_map[cardno++] = NULL;
+ }
+
+ if (currprefs.cpuboard_type == BOARD_APOLLO) {
+ card_name[cardno] = _T("Apollo");
+ card_init[cardno] = expamem_init_apollo_cpu;
+ card_map[cardno++] = NULL;
+ }
#ifdef A2091
if (cfgfile_board_enabled(&currprefs.a2091rom)) {
}
#endif
#ifdef A2091
- if (cfgfile_board_enabled(&currprefs.gvprom)) {
+ if (cfgfile_board_enabled(&currprefs.gvps2rom)) {
+ card_flags[cardno] = 0;
+ card_name[cardno] = _T("GVP SII");
+ card_init[cardno] = expamem_init_gvp_s2;
+ card_map[cardno++] = NULL;
+ card_name[cardno] = _T("GVP SII #2");
+ card_init[cardno] = expamem_init_gvp_s2_2;
+ card_map[cardno++] = NULL;
+ }
+ if (cfgfile_board_enabled(&currprefs.gvps1rom)) {
card_flags[cardno] = 0;
- card_name[cardno] = _T("GVP");
- card_init[cardno] = expamem_init_gvp;
+ card_name[cardno] = _T("GVP SI");
+ card_init[cardno] = expamem_init_gvp_s1;
card_map[cardno++] = NULL;
- card_name[cardno] = _T("GVP #2");
- card_init[cardno] = expamem_init_gvp_2;
+ card_name[cardno] = _T("GVP SI #2");
+ card_init[cardno] = expamem_init_gvp_s1_2;
card_map[cardno++] = NULL;
}
#endif
card_map[cardno++] = NULL;
}
#endif
+ if (cfgfile_board_enabled(&currprefs.alfrom) || cfgfile_board_enabled(&currprefs.alfplusrom)) {
+ card_name[cardno] = _T("ALF");
+ card_init[cardno] = expamem_init_alf;
+ card_map[cardno++] = NULL;
+ card_name[cardno] = _T("ALF #2");
+ card_init[cardno] = expamem_init_alf_2;
+ card_map[cardno++] = NULL;
+ }
+ if (cfgfile_board_enabled(&currprefs.apollorom)) {
+ card_name[cardno] = _T("Apollo");
+ card_init[cardno] = expamem_init_apollo;
+ card_map[cardno++] = NULL;
+ card_name[cardno] = _T("Apollo #2");
+ card_init[cardno] = expamem_init_apollo_2;
+ card_map[cardno++] = NULL;
+ }
+ if (cfgfile_board_enabled(&currprefs.masoboshirom)) {
+ card_name[cardno] = _T("Masoboshi");
+ card_init[cardno] = expamem_init_masoboshi;
+ card_map[cardno++] = NULL;
+ card_name[cardno] = _T("Masoboshi #2");
+ card_init[cardno] = expamem_init_masoboshi_2;
+ card_map[cardno++] = NULL;
+ }
#ifdef CDTV
if (currprefs.cs_cdtvcd && !currprefs.cs_cdtvcr) {
card_flags[cardno] = 0;
stripsemicolon (s);
fixcharset (s);
striplength (s, 30);
- if (_tcslen(s) == 0 && def)
- _tcscpy(s, def);
+ if (_tcslen(s) == 0 && def) {
+ xfree(s);
+ s = my_strdup(def);
+ }
return s;
}
TCHAR *validatedevicename (TCHAR *s, const TCHAR *def)
stripspace (s);
fixcharset (s);
striplength (s, 30);
- if (_tcslen(s) == 0 && def)
- _tcscpy(s, def);
+ if (_tcslen(s) == 0 && def) {
+ xfree(s);
+ s = my_strdup(def);
+ }
return s;
}
if (zv && zv->volumename && _tcslen(zv->volumename) > 0) {
nvol = my_strdup(zv->volumename);
- validatevolumename (nvol, def);
+ nvol = validatevolumename (nvol, def);
return nvol;
}
else
nvol = my_strdup (_T(""));
}
- validatevolumename (nvol, def);
+ nvol = validatevolumename (nvol, def);
xfree (p);
return nvol;
}
added = true;
}
#endif
+ if (currprefs.cpuboard_type == BOARD_APOLLO) {
+ apollo_add_scsi_unit(unit, uci, 0);
+ added = true;
+ } else if (currprefs.cpuboard_type == BOARD_GVP_A530) {
+ gvp_add_scsi_unit(unit, uci, 1);
+ added = true;
+ }
return added;
}
added = true;
}
} else if (type == HD_CONTROLLER_TYPE_IDE_GVP) {
- gvp_add_ide_unit(unit, uci);
- added = true;
+ if (currprefs.cpuboard_type == BOARD_A3001_I || currprefs.cpuboard_type == BOARD_A3001_II) {
+ gvp_add_ide_unit(unit, uci);
+ added = true;
+ }
+ } else if (type == HD_CONTROLLER_TYPE_IDE_ALFA) {
+ if (cfgfile_board_enabled(&currprefs.alfrom) || cfgfile_board_enabled(&currprefs.alfplusrom)) {
+ alf_add_ide_unit(unit, uci, 0);
+ added = true;
+ }
+ } else if (type == HD_CONTROLLER_TYPE_IDE_ALFA_2) {
+ if (cfgfile_board_enabled(&currprefs.alfrom) || cfgfile_board_enabled(&currprefs.alfplusrom)) {
+ alf_add_ide_unit(unit, uci, 1);
+ added = true;
+ }
+ } else if (type == HD_CONTROLLER_TYPE_IDE_APOLLO) {
+ if (cfgfile_board_enabled(&currprefs.apollorom)) {
+ apollo_add_ide_unit(unit, uci, 0);
+ added = true;
+ }
+ } else if (type == HD_CONTROLLER_TYPE_IDE_APOLLO_2) {
+ if (cfgfile_board_enabled(&currprefs.apollorom)) {
+ apollo_add_ide_unit(unit, uci, 1);
+ added = true;
+ }
+ } else if (type == HD_CONTROLLER_TYPE_IDE_MASOBOSHI) {
+ if (cfgfile_board_enabled(&currprefs.masoboshirom)) {
+ masoboshi_add_ide_unit(unit, uci, 0);
+ added = true;
+ }
+ } else if (type == HD_CONTROLLER_TYPE_IDE_MASOBOSHI_2) {
+ if (cfgfile_board_enabled(&currprefs.masoboshirom)) {
+ masoboshi_add_ide_unit(unit, uci, 1);
+ added = true;
+ }
}
return added;
}
#endif
} else if (type == HD_CONTROLLER_TYPE_SCSI_GVP) {
#ifdef A2091
- if (cfgfile_board_enabled(&currprefs.gvprom)) {
+ if (cfgfile_board_enabled(&currprefs.gvps2rom) || cfgfile_board_enabled(&currprefs.gvps1rom)) {
gvp_add_scsi_unit(unit, uci, 0);
added = true;
}
#endif
- }
- else if (type == HD_CONTROLLER_TYPE_SCSI_GVP_2) {
+ } else if (type == HD_CONTROLLER_TYPE_SCSI_GVP) {
#ifdef A2091
- if (cfgfile_board_enabled(&currprefs.gvprom)) {
+ if (cfgfile_board_enabled(&currprefs.gvps2rom) || cfgfile_board_enabled(&currprefs.gvps1rom)) {
gvp_add_scsi_unit(unit, uci, 1);
added = true;
}
added = true;
}
#endif
+ } else if (type == HD_CONTROLLER_TYPE_SCSI_APOLLO) {
+ if (cfgfile_board_enabled(&currprefs.apollorom)) {
+ apollo_add_scsi_unit(unit, uci, 0);
+ added = true;
+ }
+ } else if (type == HD_CONTROLLER_TYPE_SCSI_APOLLO_2) {
+ if (cfgfile_board_enabled(&currprefs.apollorom)) {
+ apollo_add_scsi_unit(unit, uci, 1);
+ added = true;
+ }
+ } else if (type == HD_CONTROLLER_TYPE_SCSI_MASOBOSHI) {
+ if (cfgfile_board_enabled(&currprefs.masoboshirom)) {
+ masoboshi_add_scsi_unit(unit, uci, 0);
+ added = true;
+ }
+ } else if (type == HD_CONTROLLER_TYPE_SCSI_MASOBOSHI_2) {
+ if (cfgfile_board_enabled(&currprefs.masoboshirom)) {
+ masoboshi_add_scsi_unit(unit, uci, 1);
+ added = true;
+ }
}
return added;
}
void gayle_hsync (void)
{
- if (ide_interrupt_check(idedrive, TOTAL_IDE * 2))
+ if (ide_interrupt_check(idedrive[0]) || ide_interrupt_check(idedrive[2]) || ide_interrupt_check(idedrive[4]))
rethink_gayle ();
}
return true;
}
-bool ide_interrupt_check(struct ide_hdf **idetable, int num)
+bool ide_interrupt_check(struct ide_hdf *idep)
{
bool irq = false;
- for (int i = 0; i < num; i++) {
- struct ide_hdf *ide = idetable[i];
+ for (int i = 0; i < 2; i++) {
+ struct ide_hdf *ide = i == 0 ? idep : idep->pair;
if (ide) {
if (ide->irq_delay > 0) {
ide->irq_delay--;
bool last;
ide->data_offset = 0;
- get_lbachs (ide, &lba, &cyl, &head, &sec);
nsec = get_nsec (ide);
+ get_lbachs (ide, &lba, &cyl, &head, &sec);
if (IDE_LOG > 1)
write_log (_T("IDE%d off=%d, nsec=%d (%d) lba48=%d\n"), ide->num, (uae_u32)lba, nsec, ide->multiple_mode, ide->lba48 + ide->lba48cmd);
if (nsec * ide->blocksize > ide->hdhfd.size - lba * ide->blocksize) {
ide_set_features (ide);
} else if (cmd == 0x00) { /* nop */
ide_fail (ide);
+ } else if (cmd == 0x70) { /* seek */
+ ide_interrupt (ide);
} else if (cmd == 0xe0 || cmd == 0xe1 || cmd == 0xe7 || cmd == 0xea) { /* standby now/idle/flush cache/flush cache ext */
ide_interrupt (ide);
} else if (cmd == 0xe5) { /* check power mode */
bool irq = false;
uae_u16 v;
- if (IDE_LOG > 4)
- write_log (_T("IDE%d DATA read\n"), ide->num);
if (ide->data_size == 0) {
if (IDE_LOG > 0)
write_log (_T("IDE%d DATA but no data left!? %02X PC=%08X\n"), ide->num, ide->regs.ide_status, m68k_getpc ());
}
if (ide->packet_state) {
v = ide->secbuf[ide->packet_data_offset + ide->data_offset + 1] | (ide->secbuf[ide->packet_data_offset + ide->data_offset + 0] << 8);
+ if (IDE_LOG > 4)
+ write_log (_T("IDE%d DATA read %04x\n"), ide->num, v);
ide->data_offset += 2;
if (ide->data_size < 0)
ide->data_size += 2;
}
} else {
v = ide->secbuf[ide->data_offset + 1] | (ide->secbuf[ide->data_offset + 0] << 8);
+ if (IDE_LOG > 4)
+ write_log (_T("IDE%d DATA read %04x\n"), ide->num, v);
ide->data_offset += 2;
if (ide->data_size < 0) {
ide->data_size += 2;
if (ide_reg == IDE_STATUS && ide->pair->irq)
ide->pair->irq = 0;
if (ide_isdrive (ide->pair))
- v = 0x00;
+ v = 0x01;
else
v = 0xff;
goto end;
#include "custom.h"
#include "rommgr.h"
#include "cpuboard.h"
+#include "scsi.h"
+#include "ncr9x_scsi.h"
#define DEBUG_IDE 0
+#define DEBUG_IDE_GVP 0
+#define DEBUG_IDE_ALF 0
+#define DEBUG_IDE_APOLLO 0
+#define DEBUG_IDE_MASOBOSHI 0
#define GVP_IDE 0 // GVP A3001
-#define TOTAL_IDE 1
+#define ALF_IDE 1
+#define APOLLO_IDE 3
+#define MASOBOSHI_IDE 5
+#define TOTAL_IDE 7
+#define ALF_ROM_OFFSET 0x0100
#define GVP_IDE_ROM_OFFSET 0x8000
+#define APOLLO_ROM_OFFSET 0x8000
+#define MASOBOSHI_ROM_OFFSET 0x0080
+#define MASOBOSHI_ROM_OFFSET_END 0xf000
+#define MASOBOSHI_SCSI_OFFSET 0xf800
+#define MASOBOSHI_SCSI_OFFSET_END 0xfc00
+
+/* masoboshi:
+
+IDE
+
+- FFCC = base address, data (0)
+- FF81 = -004B
+- FF41 = -008B
+- FF01 = -01CB
+- FEC1 = -010B
+- FE81 = -014B
+- FE41 = -018B select (6)
+- FE01 = -01CB status (7)
+- FE03 = command (7)
+
+- FA00 = ESP, 2 byte register spacing
+- F9CC = data
+
+- F047 = -0F85 (-0FB9) interrupt request? (bit 3)
+- F040 = -0F8C interrupt request? (bit 1) Write anything = clear irq?
+- F000 = some status register
+
+- F04C = DMA address (long)
+- F04A = number of words
+- F044 = ???
+- F047 = bit 7 = start dma
+
+*/
static struct ide_board gvp_ide_rom_board, gvp_ide_controller_board;
+static struct ide_board alf_board[2];
+static struct ide_board apollo_board[2];
+static struct ide_board masoboshi_board[2];
static struct ide_hdf *idecontroller_drive[TOTAL_IDE * 2];
static struct ide_thread_state idecontroller_its;
-static void init_ide(struct ide_board *board, struct ide_hdf **idetable)
+static struct ide_board *ide_boards[] =
+{
+ &gvp_ide_rom_board,
+ &alf_board[0],
+ &alf_board[1],
+ &apollo_board[0],
+ &apollo_board[1],
+ &masoboshi_board[0],
+ &masoboshi_board[1],
+ NULL
+};
+
+static void init_ide(struct ide_board *board, int ide_num, bool byteswap)
{
+ struct ide_hdf **idetable = &idecontroller_drive[ide_num * 2];
alloc_ide_mem (idetable, 2, &idecontroller_its);
board->ide = idetable[0];
idetable[0]->board = board;
idetable[1]->board = board;
- idetable[0]->byteswap = true;
- idetable[1]->byteswap = true;
- ide_initialize(idetable, 0);
+ idetable[0]->byteswap = byteswap;
+ idetable[1]->byteswap = byteswap;
+ ide_initialize(idecontroller_drive, ide_num);
idecontroller_its.idetable = idecontroller_drive;
idecontroller_its.idetotal = TOTAL_IDE * 2;
start_ide_thread(&idecontroller_its);
}
-static bool ide_irq_check(void)
+static bool ide_irq_check(struct ide_board *board)
{
- bool irq = ide_interrupt_check(idecontroller_drive, 2);
- gvp_ide_controller_board.irq = irq;
+ if (!board->configured)
+ return false;
+ bool irq = ide_interrupt_check(board->ide);
+ board->irq = irq;
+ return irq;
+}
+
+static bool ide_rethink(struct ide_board *board)
+{
+ bool irq = false;
+ if (board->configured) {
+ if (board->intena && ide_irq_check(board)) {
+ irq = true;
+ }
+ }
return irq;
}
void idecontroller_rethink(void)
{
- if (!gvp_ide_controller_board.configured)
- return;
- if (gvp_ide_controller_board.intena && ide_irq_check() && !(intreq & 0x0008)) {
+ bool irq = false;
+ for (int i = 0; ide_boards[i]; i++) {
+ irq |= ide_rethink(ide_boards[i]);
+ }
+ if (irq && !(intreq & 0x0008)) {
INTREQ_0(0x8000 | 0x0008);
}
}
void idecontroller_hsync(void)
{
- if (!gvp_ide_controller_board.configured)
- return;
- if (ide_irq_check())
- idecontroller_rethink();
+ for (int i = 0; ide_boards[i]; i++) {
+ if (ide_irq_check(ide_boards[i])) {
+ idecontroller_rethink();
+ }
+ }
}
void idecontroller_free_units(void)
}
}
-int gvp_add_ide_unit(int ch, struct uaedev_config_info *ci)
+static void reset_ide(struct ide_board *board)
{
- struct ide_hdf *ide;
-
- ide = add_ide_unit (idecontroller_drive, 2, ch, ci);
- if (ide == NULL)
- return 0;
- return 1;
+ board->configured = 0;
+ board->intena = false;
+ board->enabled = false;
}
-
-void idecontroller_free(void)
+void idecontroller_reset(void)
{
- stop_ide_thread(&idecontroller_its);
+ for (int i = 0; ide_boards[i]; i++) {
+ reset_ide(ide_boards[i]);
+ }
}
-void idecontroller_reset(void)
+void idecontroller_free(void)
{
- gvp_ide_controller_board.configured = 0;
- gvp_ide_controller_board.intena = false;
+ stop_ide_thread(&idecontroller_its);
}
static bool is_gvp2_intreq(uaecptr addr)
reg &= IDE_SECONDARY | 7;
ide = board->ide;
- if (idecontroller_drive[GVP_IDE]->ide_drv)
+ if (idecontroller_drive[GVP_IDE * 2]->ide_drv)
+ ide = ide->pair;
+ *idep = ide;
+ return reg;
+}
+
+static int get_apollo_reg(uaecptr addr, struct ide_board *board, struct ide_hdf **idep)
+{
+ struct ide_hdf *ide;
+ if (addr & 0x4000)
+ return -1;
+ int reg = addr & 0x1fff;
+ reg >>= 10;
+ if (addr & 0x2000)
+ reg |= IDE_SECONDARY;
+ ide = board->ide;
+ if (idecontroller_drive[APOLLO_IDE * 2]->ide_drv)
+ ide = ide->pair;
+ *idep = ide;
+ if (reg != 0 && !(addr & 1))
+ reg = -1;
+ write_log(_T("APOLLO %04x = %d\n"), addr, reg);
+ return reg;
+}
+
+static int get_alf_reg(uaecptr addr, struct ide_board *board, struct ide_hdf **idep)
+{
+ struct ide_hdf *ide;
+ if (addr & 0x8000)
+ return -1;
+ ide = board->ide;
+ if (idecontroller_drive[ALF_IDE * 2]->ide_drv)
ide = ide->pair;
*idep = ide;
+ if (addr & 0x4000) {
+ ;
+ } else if (addr & 0x1000) {
+ addr &= 0xfff;
+ addr >>= 9;
+ } else if (addr & 0x2000) {
+ addr &= 0xfff;
+ addr >>= 9;
+ addr |= IDE_SECONDARY;
+ }
+ return addr;
+}
+
+static int get_masoboshi_reg(uaecptr addr, struct ide_board *board, struct ide_hdf **idep)
+{
+ int reg;
+ struct ide_hdf *ide;
+ if (addr < 0xfc00)
+ return -1;
+ ide = board->ide;
+ if (idecontroller_drive[MASOBOSHI_IDE * 2]->ide_drv)
+ ide = ide->pair;
+ *idep = ide;
+ reg = 7 - ((addr >> 6) & 7);
+ if (addr < 0xfe00)
+ reg |= IDE_SECONDARY;
return reg;
}
static uae_u32 ide_read_byte(struct ide_board *board, uaecptr addr)
{
- uae_u8 v = 0;
+ uae_u8 v = 0xff;
addr &= 0xffff;
+
+#ifdef JIT
+ special_mem |= S_READ;
+#endif
+
+ addr &= board->mask;
+
+#if DEBUG_IDE
+ write_log(_T("IDE IO BYTE READ %08x %08x\n"), addr, M68K_GETPC);
+#endif
+
if (addr < 0x40)
return board->acmemory[addr];
- if (addr >= GVP_IDE_ROM_OFFSET) {
- if (board->rom) {
- if (addr & 1)
- v = 0xe8; // board id
- else
- v = board->rom[((addr - GVP_IDE_ROM_OFFSET) / 2) & board->rom_mask];
+ if (board->type == ALF_IDE) {
+
+ if (addr < 0x1100 || (addr & 1)) {
+ if (board->rom)
+ v = board->rom[addr & board->rom_mask];
return v;
}
- v = 0xe8;
-#if DEBUG_IDE
- write_log(_T("GVP BOOT GET %08x %02x %08x\n"), addr, v, M68K_GETPC);
+ struct ide_hdf *ide;
+ int regnum = get_alf_reg(addr, board, &ide);
+ if (regnum >= 0) {
+ v = ide_read_reg(ide, regnum);
+ }
+#if DEBUG_IDE_ALF
+ write_log(_T("ALF GET %08x %02x %d %08x\n"), addr, v, regnum, M68K_GETPC);
#endif
- return v;
- }
- if (board->configured) {
- if (board == &gvp_ide_rom_board && currprefs.cpuboard_type == BOARD_A3001_II) {
- if (addr == 0x42) {
- v = 0xff;
+
+ } else if (board->type == MASOBOSHI_IDE) {
+ int regnum = -1;
+ bool rom = false;
+ if (addr >= MASOBOSHI_ROM_OFFSET && addr < MASOBOSHI_ROM_OFFSET_END) {
+ if (board->rom) {
+ v = board->rom[addr & board->rom_mask];
+ rom = true;
}
-#if DEBUG_IDE
- write_log(_T("GVP BOOT GET %08x %02x %08x\n"), addr, v, M68K_GETPC);
-#endif
+ } else if (addr >= 0xf000 && addr <= 0xf007) {
+ v = masoboshi_ncr9x_scsi_get(addr, board == &masoboshi_board[0] ? 0 : 1);
+ } else if (addr == 0xf040) {
+ v = board->irq ? 2 : 0;
+ v |= masoboshi_ncr9x_scsi_get(addr, board == &masoboshi_board[0] ? 0 : 1);
+ } else if (addr == 0xf047) {
+ v = board->state;
} else {
struct ide_hdf *ide;
- int regnum = get_gvp_reg(addr, board, &ide);
-#if DEBUG_IDE
- write_log(_T("GVP IDE GET %08x %02x %d %08x\n"), addr, v, regnum, M68K_GETPC);
-#endif
+ regnum = get_masoboshi_reg(addr, board, &ide);
if (regnum >= 0) {
v = ide_read_reg(ide, regnum);
- } else if (is_gvp2_intreq(addr)) {
- v = board->irq ? 0x40 : 0x00;
-#if DEBUG_IDE
- write_log(_T("GVP IRQ %02x\n"), v);
+ } else if (addr >= MASOBOSHI_SCSI_OFFSET && addr < MASOBOSHI_SCSI_OFFSET_END) {
+ v = masoboshi_ncr9x_scsi_get(addr, board == &masoboshi_board[0] ? 0 : 1);
+ }
+ }
+#if DEBUG_IDE_MASOBOSHI
+ if (!rom)
+ write_log(_T("MASOBOSHI BYTE GET %08x %02x %d %08x\n"), addr, v, regnum, M68K_GETPC);
#endif
- ide_irq_check();
- } else if (is_gvp1_intreq(addr)) {
- v = gvp_ide_controller_board.irq ? 0x80 : 0x00;
-#if DEBUG_IDE
- write_log(_T("GVP IRQ %02x\n"), v);
+ } else if (board->type == APOLLO_IDE) {
+
+ if (addr >= APOLLO_ROM_OFFSET) {
+ if (board->rom)
+ v = board->rom[(addr - APOLLO_ROM_OFFSET) & board->rom_mask];
+ } else if (board->configured) {
+ if ((addr & 0xc000) == 0x4000) {
+ v = apollo_scsi_bget(addr);
+ } else if (addr < 0x4000) {
+ struct ide_hdf *ide;
+ int regnum = get_apollo_reg(addr, board, &ide);
+ if (regnum >= 0) {
+ v = ide_read_reg(ide, regnum);
+ } else {
+ v = 0;
+ }
+ }
+ }
+
+ } else if (board->type == GVP_IDE) {
+
+ if (addr >= GVP_IDE_ROM_OFFSET) {
+ if (board->rom) {
+ if (addr & 1)
+ v = 0xe8; // board id
+ else
+ v = board->rom[((addr - GVP_IDE_ROM_OFFSET) / 2) & board->rom_mask];
+ return v;
+ }
+ v = 0xe8;
+#if DEBUG_IDE_GVP
+ write_log(_T("GVP BOOT GET %08x %02x %08x\n"), addr, v, M68K_GETPC);
+#endif
+ return v;
+ }
+ if (board->configured) {
+ if (board == &gvp_ide_rom_board && currprefs.cpuboard_type == BOARD_A3001_II) {
+ if (addr == 0x42) {
+ v = 0xff;
+ }
+#if DEBUG_IDE_GVP
+ write_log(_T("GVP BOOT GET %08x %02x %08x\n"), addr, v, M68K_GETPC);
#endif
- ide_irq_check();
+ } else {
+ struct ide_hdf *ide;
+ int regnum = get_gvp_reg(addr, board, &ide);
+#if DEBUG_IDE_GVP
+ write_log(_T("GVP IDE GET %08x %02x %d %08x\n"), addr, v, regnum, M68K_GETPC);
+#endif
+ if (regnum >= 0) {
+ v = ide_read_reg(ide, regnum);
+ } else if (is_gvp2_intreq(addr)) {
+ v = board->irq ? 0x40 : 0x00;
+#if DEBUG_IDE_GVP
+ write_log(_T("GVP IRQ %02x\n"), v);
+#endif
+ ide_irq_check(board);
+ } else if (is_gvp1_intreq(addr)) {
+ v = gvp_ide_controller_board.irq ? 0x80 : 0x00;
+#if DEBUG_IDE_GVP
+ write_log(_T("GVP IRQ %02x\n"), v);
+#endif
+ ide_irq_check(board);
+ }
}
+ } else {
+ v = 0xff;
}
- } else {
- v = 0xff;
}
return v;
}
{
uae_u32 v = 0xffff;
- addr &= 65535;
- if (board->configured && (board == &gvp_ide_controller_board || currprefs.cpuboard_type == BOARD_A3001_I)) {
- if (addr < 0x60) {
- if (is_gvp1_intreq(addr))
- v = gvp_ide_controller_board.irq ? 0x8000 : 0x0000;
- else if (addr == 0x40) {
- if (currprefs.cpuboard_type == BOARD_A3001_II)
- v = board->intena ? 8 : 0;
+#ifdef JIT
+ special_mem |= S_READ;
+#endif
+
+ addr &= board->mask;
+
+ if (board->type == APOLLO_IDE) {
+
+ if (addr >= APOLLO_ROM_OFFSET) {
+ if (board->rom) {
+ v = board->rom[(addr + 0 - APOLLO_ROM_OFFSET) & board->rom_mask];
+ v <<= 8;
+ v |= board->rom[(addr + 1 - APOLLO_ROM_OFFSET) & board->rom_mask];
}
-#if DEBUG_IDE
- write_log(_T("GVP IO WORD READ %08x %08x\n"), addr, M68K_GETPC);
+ }
+ }
+
+
+ if (board->configured) {
+
+ if (board->type == ALF_IDE) {
+
+ struct ide_hdf *ide;
+ int regnum = get_alf_reg(addr, board, &ide);
+ if (regnum == IDE_DATA) {
+ v = ide_get_data(ide);
+ } else {
+ v = 0;
+ if (addr == 0x4000 && board->intena)
+ v = board->irq ? 0x8000 : 0x0000;
+#if DEBUG_IDE_ALF
+ write_log(_T("ALF IO WORD READ %08x %08x\n"), addr, M68K_GETPC);
#endif
+ }
+
+ } else if (board->type == MASOBOSHI_IDE) {
+
+ if (addr >= MASOBOSHI_ROM_OFFSET && addr < MASOBOSHI_ROM_OFFSET_END) {
+ if (board->rom) {
+ v = board->rom[addr & board->rom_mask] << 8;
+ v |= board->rom[(addr + 1) & board->rom_mask];
+ }
} else {
struct ide_hdf *ide;
- int regnum = get_gvp_reg(addr, board, &ide);
+ int regnum = get_masoboshi_reg(addr, board, &ide);
if (regnum == IDE_DATA) {
v = ide_get_data(ide);
-#if DEBUG_IDE > 2
- write_log(_T("IDE WORD READ %04x\n"), v);
-#endif
} else {
v = ide_read_byte(board, addr) << 8;
v |= ide_read_byte(board, addr + 1);
}
}
+
+ } else if (board->type == APOLLO_IDE) {
+
+ if ((addr & 0xc000) == 0x4000) {
+ v = apollo_scsi_bget(addr);
+ v <<= 8;
+ v |= apollo_scsi_bget(addr + 1);
+ } else if (addr < 0x4000) {
+ struct ide_hdf *ide;
+ int regnum = get_apollo_reg(addr, board, &ide);
+ if (regnum == IDE_DATA) {
+ v = ide_get_data(ide);
+ } else {
+ v = 0;
+ }
+ }
+
+ } else if (board->type == GVP_IDE) {
+
+ if (board == &gvp_ide_controller_board || currprefs.cpuboard_type == BOARD_A3001_I) {
+ if (addr < 0x60) {
+ if (is_gvp1_intreq(addr))
+ v = gvp_ide_controller_board.irq ? 0x8000 : 0x0000;
+ else if (addr == 0x40) {
+ if (currprefs.cpuboard_type == BOARD_A3001_II)
+ v = board->intena ? 8 : 0;
+ }
+#if DEBUG_IDE_GVP
+ write_log(_T("GVP IO WORD READ %08x %08x\n"), addr, M68K_GETPC);
+#endif
+ } else {
+ struct ide_hdf *ide;
+ int regnum = get_gvp_reg(addr, board, &ide);
+ if (regnum == IDE_DATA) {
+ v = ide_get_data(ide);
+#if DEBUG_IDE_GVP > 2
+ write_log(_T("IDE WORD READ %04x\n"), v);
+#endif
+ } else {
+ v = ide_read_byte(board, addr) << 8;
+ v |= ide_read_byte(board, addr + 1);
+ }
+ }
+ }
+ }
}
+
+#if DEBUG_IDE
+ write_log(_T("IDE IO WORD READ %08x %04x %08x\n"), addr, v, M68K_GETPC);
+#endif
+
return v;
}
static void ide_write_byte(struct ide_board *board, uaecptr addr, uae_u8 v)
{
- addr &= 65535;
+ addr &= board->mask;
+
+#ifdef JIT
+ special_mem |= S_WRITE;
+#endif
+
+#if DEBUG_IDE
+ write_log(_T("IDE IO BYTE WRITE %08x=%02x %08x\n"), addr, v, M68K_GETPC);
+#endif
+
if (!board->configured) {
addrbank *ab = board->bank;
if (addr == 0x48) {
- map_banks_z2(ab, v, 0x10000 >> 16);
+ map_banks_z2(ab, v, (board->mask + 1) >> 16);
board->configured = 1;
expamem_next(ab, NULL);
return;
}
}
if (board->configured) {
- if (board == &gvp_ide_rom_board && currprefs.cpuboard_type == BOARD_A3001_II) {
-#if DEBUG_IDE
- write_log(_T("GVP BOOT PUT %08x %02x %08x\n"), addr, v, M68K_GETPC);
-#endif
- } else {
+ if (board->type == ALF_IDE) {
struct ide_hdf *ide;
- int regnum = get_gvp_reg(addr, board, &ide);
-#if DEBUG_IDE
- write_log(_T("GVP IDE PUT %08x %02x %d %08x\n"), addr, v, regnum, M68K_GETPC);
-#endif
+ int regnum = get_alf_reg(addr, board, &ide);
if (regnum >= 0)
ide_write_reg(ide, regnum, v);
- }
- }
-}
+#if DEBUG_IDE_ALF
+ write_log(_T("ALF PUT %08x %02x %d %08x\n"), addr, v, regnum, M68K_GETPC);
+#endif
+ } else if (board->type == MASOBOSHI_IDE) {
-static void ide_write_word(struct ide_board *board, uaecptr addr, uae_u16 v)
-{
- addr &= 65535;
- if (board->configured && (board == &gvp_ide_controller_board || currprefs.cpuboard_type == BOARD_A3001_I)) {
- if (addr < 0x60) {
-#if DEBUG_IDE
- write_log(_T("GVP IO WORD WRITE %08x %04x %08x\n"), addr, v, M68K_GETPC);
+#if DEBUG_IDE_MASOBOSHI
+ write_log(_T("MASOBOSHI IO BYTE PUT %08x %02x %08x\n"), addr, v, M68K_GETPC);
#endif
- if (addr == 0x40 && currprefs.cpuboard_type == BOARD_A3001_II)
- board->intena = (v & 8) != 0;
- } else {
struct ide_hdf *ide;
- int regnum = get_gvp_reg(addr, board, &ide);
- if (regnum == IDE_DATA) {
- ide_put_data(ide, v);
-#if DEBUG_IDE > 2
- write_log(_T("IDE WORD WRITE %04x\n"), v);
+ int regnum = get_masoboshi_reg(addr, board, &ide);
+ if (regnum >= 0) {
+ ide_write_reg(ide, regnum, v);
+ } else if (addr >= MASOBOSHI_SCSI_OFFSET && addr < MASOBOSHI_SCSI_OFFSET_END) {
+ masoboshi_ncr9x_scsi_put(addr, v, board == &masoboshi_board[0] ? 0 : 1);
+ } else if ((addr >= 0xf000 && addr <= 0xf007) || (addr >= 0xf04a && addr <= 0xf04f)) {
+ masoboshi_ncr9x_scsi_put(addr, v, board == &masoboshi_board[0] ? 0 : 1);
+ } else if (addr >= 0xf040 && addr < 0xf048) {
+ masoboshi_ncr9x_scsi_put(addr, v, board == &masoboshi_board[0] ? 0 : 1);
+ if (addr == 0xf047) {
+ board->state = v;
+ board->intena = (v & 8) != 0;
+ }
+ if (addr == 0xf040) {
+ board->irq = false;
+ }
+ write_log(_T("MASOBOSHI STATUS BYTE PUT %08x %02x %08x\n"), addr, v, M68K_GETPC);
+ }
+
+ } else if (board->type == APOLLO_IDE) {
+
+ if ((addr & 0xc000) == 0x4000) {
+ apollo_scsi_bput(addr, v);
+ } else if (addr < 0x4000) {
+ struct ide_hdf *ide;
+ int regnum = get_apollo_reg(addr, board, &ide);
+ if (regnum >= 0) {
+ ide_write_reg(ide, regnum, v);
+ }
+ }
+
+ } else if (board->type == GVP_IDE) {
+ if (board == &gvp_ide_rom_board && currprefs.cpuboard_type == BOARD_A3001_II) {
+#if DEBUG_IDE_GVP
+ write_log(_T("GVP BOOT PUT %08x %02x %08x\n"), addr, v, M68K_GETPC);
#endif
} else {
- ide_write_byte(board, addr, v >> 8);
- ide_write_byte(board, addr + 1, v & 0xff);
+ struct ide_hdf *ide;
+ int regnum = get_gvp_reg(addr, board, &ide);
+#if DEBUG_IDE_GVP
+ write_log(_T("GVP IDE PUT %08x %02x %d %08x\n"), addr, v, regnum, M68K_GETPC);
+#endif
+ if (regnum >= 0)
+ ide_write_reg(ide, regnum, v);
}
}
}
}
-static uae_u32 REGPARAM2 ide_controller_gvp_lget (uaecptr addr)
+static void ide_write_word(struct ide_board *board, uaecptr addr, uae_u16 v)
{
- uae_u32 v;
+ addr &= board->mask;
+
#ifdef JIT
- special_mem |= S_READ;
+ special_mem |= S_WRITE;
#endif
- v = ide_read_word (&gvp_ide_controller_board, addr + 0) << 16;
- v |= ide_read_word (&gvp_ide_controller_board, addr + 2) << 0;
- return v;
-}
-static uae_u32 REGPARAM2 ide_controller_gvp_wget (uaecptr addr)
-{
- uae_u32 v;
-#ifdef JIT
- special_mem |= S_READ;
+
+#if DEBUG_IDE
+ write_log(_T("IDE IO WORD WRITE %08x=%04x %08x\n"), addr, v, M68K_GETPC);
#endif
- v = ide_read_word (&gvp_ide_controller_board, addr);
- return v;
-}
-static uae_u32 REGPARAM2 ide_controller_gvp_bget (uaecptr addr)
-{
-#ifdef JIT
- special_mem |= S_READ;
+ if (board->configured) {
+ if (board->type == ALF_IDE) {
+
+ struct ide_hdf *ide;
+ int regnum = get_alf_reg(addr, board, &ide);
+ if (regnum == IDE_DATA) {
+ ide_put_data(ide, v);
+ } else {
+#if DEBUG_IDE_ALF
+ write_log(_T("ALF IO WORD WRITE %08x %04x %08x\n"), addr, v, M68K_GETPC);
#endif
- return ide_read_byte (&gvp_ide_controller_board, addr);
-}
-static void REGPARAM2 ide_controller_gvp_lput (uaecptr addr, uae_u32 l)
-{
-#ifdef JIT
- special_mem |= S_WRITE;
+ }
+
+ } else if (board->type == MASOBOSHI_IDE) {
+
+ struct ide_hdf *ide;
+ int regnum = get_masoboshi_reg(addr, board, &ide);
+ if (regnum == IDE_DATA) {
+ ide_put_data(ide, v);
+ } else {
+ ide_write_byte(board, addr, v >> 8);
+ ide_write_byte(board, addr + 1, v);
+ }
+#if DEBUG_IDE_MASOBOSHI
+ write_log(_T("MASOBOSHI IO WORD WRITE %08x %04x %08x\n"), addr, v, M68K_GETPC);
#endif
- ide_write_word (&gvp_ide_controller_board, addr + 0, l >> 16);
- ide_write_word (&gvp_ide_controller_board, addr + 2, l >> 0);
-}
-static void REGPARAM2 ide_controller_gvp_wput (uaecptr addr, uae_u32 w)
-{
-#ifdef JIT
- special_mem |= S_WRITE;
+
+ } else if (board->type == APOLLO_IDE) {
+
+ if ((addr & 0xc000) == 0x4000) {
+ apollo_scsi_bput(addr, v >> 8);
+ apollo_scsi_bput(addr + 1, v);
+ } else if (addr < 0x4000) {
+ struct ide_hdf *ide;
+ int regnum = get_apollo_reg(addr, board, &ide);
+ if (regnum == IDE_DATA) {
+ ide_put_data(ide, v);
+ }
+ }
+
+ } else if (board->type == GVP_IDE) {
+
+ if (board == &gvp_ide_controller_board || currprefs.cpuboard_type == BOARD_A3001_I) {
+ if (addr < 0x60) {
+#if DEBUG_IDE_GVP
+ write_log(_T("GVP IO WORD WRITE %08x %04x %08x\n"), addr, v, M68K_GETPC);
#endif
- ide_write_word (&gvp_ide_controller_board, addr + 0, w);
-}
-static void REGPARAM2 ide_controller_gvp_bput (uaecptr addr, uae_u32 b)
-{
-#ifdef JIT
- special_mem |= S_WRITE;
+ if (addr == 0x40 && currprefs.cpuboard_type == BOARD_A3001_II)
+ board->intena = (v & 8) != 0;
+ } else {
+ struct ide_hdf *ide;
+ int regnum = get_gvp_reg(addr, board, &ide);
+ if (regnum == IDE_DATA) {
+ ide_put_data(ide, v);
+#if DEBUG_IDE_GVP > 2
+ write_log(_T("IDE WORD WRITE %04x\n"), v);
#endif
- ide_write_byte (&gvp_ide_controller_board, addr, b);
+ } else {
+ ide_write_byte(board, addr, v >> 8);
+ ide_write_byte(board, addr + 1, v & 0xff);
+ }
+ }
+ }
+ }
+ }
}
+
+IDE_MEMORY_FUNCTIONS(ide_controller_gvp, ide, gvp_ide_controller_board);
+
addrbank gvp_ide_controller_bank = {
ide_controller_gvp_lget, ide_controller_gvp_wget, ide_controller_gvp_bget,
ide_controller_gvp_lput, ide_controller_gvp_wput, ide_controller_gvp_bput,
dummy_lgeti, dummy_wgeti, ABFLAG_IO | ABFLAG_SAFE
};
-static uae_u32 REGPARAM2 ide_rom_gvp_lget (uaecptr addr)
-{
- uae_u32 v;
-#ifdef JIT
- special_mem |= S_READ;
-#endif
- v = ide_read_word (&gvp_ide_rom_board, addr + 0) << 16;
- v |= ide_read_word (&gvp_ide_rom_board, addr + 2) << 0;
- return v;
-}
-static uae_u32 REGPARAM2 ide_rom_gvp_wget (uaecptr addr)
-{
- uae_u32 v;
-#ifdef JIT
- special_mem |= S_READ;
-#endif
- v = ide_read_word (&gvp_ide_rom_board, addr);
- return v;
-}
-static uae_u32 REGPARAM2 ide_rom_gvp_bget (uaecptr addr)
-{
-#ifdef JIT
- special_mem |= S_READ;
-#endif
- return ide_read_byte (&gvp_ide_rom_board, addr);
-}
-static void REGPARAM2 ide_rom_gvp_lput (uaecptr addr, uae_u32 l)
-{
-#ifdef JIT
- special_mem |= S_WRITE;
-#endif
- ide_write_word (&gvp_ide_rom_board, addr + 0, l >> 16);
- ide_write_word (&gvp_ide_rom_board, addr + 2, l >> 0);
-}
-static void REGPARAM2 ide_rom_gvp_wput (uaecptr addr, uae_u32 w)
-{
-#ifdef JIT
- special_mem |= S_WRITE;
-#endif
- ide_write_word (&gvp_ide_rom_board, addr + 0, w);
-}
-static void REGPARAM2 ide_rom_gvp_bput (uaecptr addr, uae_u32 b)
-{
-#ifdef JIT
- special_mem |= S_WRITE;
-#endif
- ide_write_byte (&gvp_ide_rom_board, addr, b);
-}
+IDE_MEMORY_FUNCTIONS(ide_rom_gvp, ide, gvp_ide_rom_board);
+
addrbank gvp_ide_rom_bank = {
ide_rom_gvp_lget, ide_rom_gvp_wget, ide_rom_gvp_bget,
ide_rom_gvp_lput, ide_rom_gvp_wput, ide_rom_gvp_bput,
dummy_lgeti, dummy_wgeti, ABFLAG_IO | ABFLAG_SAFE
};
+IDE_MEMORY_FUNCTIONS(alf, ide, alf_board[0]);
+IDE_MEMORY_FUNCTIONS(alf2, ide, alf_board[1]);
+
+addrbank alf_bank = {
+ alf_lget, alf_wget, alf_bget,
+ alf_lput, alf_wput, alf_bput,
+ default_xlate, default_check, NULL, NULL, _T("ALF"),
+ dummy_lgeti, dummy_wgeti, ABFLAG_IO | ABFLAG_SAFE
+};
+addrbank alf_bank2 = {
+ alf2_lget, alf2_wget, alf2_bget,
+ alf2_lput, alf2_wput, alf2_bput,
+ default_xlate, default_check, NULL, NULL, _T("ALF #2"),
+ dummy_lgeti, dummy_wgeti, ABFLAG_IO | ABFLAG_SAFE
+};
+
+IDE_MEMORY_FUNCTIONS(apollo_ide, ide, apollo_board[0]);
+
+addrbank apollo_bank = {
+ apollo_ide_lget, apollo_ide_wget, apollo_ide_bget,
+ apollo_ide_lput, apollo_ide_wput, apollo_ide_bput,
+ default_xlate, default_check, NULL, NULL, _T("Apollo"),
+ dummy_lgeti, dummy_wgeti, ABFLAG_IO | ABFLAG_SAFE
+};
+
+IDE_MEMORY_FUNCTIONS(masoboshi_ide, ide, masoboshi_board[0]);
+
+addrbank masoboshi_bank = {
+ masoboshi_ide_lget, masoboshi_ide_wget, masoboshi_ide_bget,
+ masoboshi_ide_lput, masoboshi_ide_wput, masoboshi_ide_bput,
+ default_xlate, default_check, NULL, NULL, _T("Masoboshi"),
+ dummy_lgeti, dummy_wgeti, ABFLAG_IO | ABFLAG_SAFE
+};
+
static void ew(struct ide_board *ide, int addr, uae_u32 value)
{
addr &= 0xffff;
if (currprefs.cpuboard_type == BOARD_A3001_I) {
ide->bank = &gvp_ide_rom_bank;
autoconfig = gvp_ide1_controller_autoconfig;
- init_ide(ide, &idecontroller_drive[GVP_IDE]);
+ init_ide(ide, GVP_IDE, true);
ide->rom_size = 8192;
gvp_ide_controller_board.intena = true;
gvp_ide_controller_board.configured = -1;
ide->rom_size = 16384;
roms[0] = -1;
}
+ ide->mask = 65536 - 1;
+ ide->type = GVP_IDE;
ide->configured = 0;
memset(ide->acmemory, 0xff, sizeof ide->acmemory);
{
struct ide_board *ide = &gvp_ide_controller_board;
- init_ide(ide, &idecontroller_drive[GVP_IDE]);
+ init_ide(ide, GVP_IDE, true);
ide->configured = 0;
ide->bank = &gvp_ide_controller_bank;
memset(ide->acmemory, 0xff, sizeof ide->acmemory);
return ide->bank;
}
+int gvp_add_ide_unit(int ch, struct uaedev_config_info *ci)
+{
+ struct ide_hdf *ide;
+
+ ide = add_ide_unit (&idecontroller_drive[GVP_IDE], 2, ch, ci);
+ if (ide == NULL)
+ return 0;
+ return 1;
+}
+
+static const uae_u8 alf_autoconfig[16] = { 0xd1, 6, 0x00, 0x00, 0x08, 0x2c, 0x00, 0x00, 0x00, 0x00, ALF_ROM_OFFSET >> 8, ALF_ROM_OFFSET & 0xff };
+static const uae_u8 alfplus_autoconfig[16] = { 0xd1, 38, 0x00, 0x00, 0x08, 0x2c, 0x00, 0x00, 0x00, 0x00, ALF_ROM_OFFSET >> 8, ALF_ROM_OFFSET & 0xff };
+
+addrbank *alf_init(int devnum)
+{
+ struct ide_board *ide = &alf_board[devnum];
+ int roms[2];
+ struct romlist *rl;
+ bool alfplus = cfgfile_board_enabled(&currprefs.alfplusrom);
+
+ if (devnum > 0 && !ide->enabled)
+ return &expamem_null;
+
+ roms[0] = alfplus ? 118 : 117;
+ roms[1] = -1;
+
+ init_ide(ide, ALF_IDE + devnum, false);
+ ide->configured = 0;
+ ide->bank = &alf_bank;
+ ide->type = ALF_IDE + devnum;
+ ide->rom_size = 32768 * 6;
+ ide->userdata = alfplus;
+ ide->intena = alfplus;
+ ide->mask = 65536 - 1;
+
+ memset(ide->acmemory, 0xff, sizeof ide->acmemory);
+
+ ide->rom = xcalloc(uae_u8, ide->rom_size);
+ memset(ide->rom, 0xff, ide->rom_size);
+ ide->rom_mask = ide->rom_size - 1;
+ const TCHAR *romname = alfplus ? currprefs.alfplusrom.roms[0].romfile : currprefs.alfrom.roms[0].romfile;
+ struct zfile *z = read_rom_name(romname);
+ if (!z) {
+ rl = getromlistbyids(roms, romname);
+ if (rl) {
+ z = read_rom(rl->rd);
+ }
+ }
+ for (int i = 0; i < 16; i++) {
+ uae_u8 b = alfplus ? alfplus_autoconfig[i] : alf_autoconfig[i];
+ ew(ide, i * 4, b);
+ }
+ if (z) {
+ write_log(_T("ALF BOOT ROM '%s'\n"), zfile_getname(z));
+ for (int i = 0; i < 0x1000 / 2; i++) {
+ uae_u8 b;
+ zfile_fread(&b, 1, 1, z);
+ ide->rom[ALF_ROM_OFFSET + i * 4 + 0] = b;
+ zfile_fread(&b, 1, 1, z);
+ ide->rom[ALF_ROM_OFFSET + i * 4 + 2] = b;
+ }
+ for (int i = 0; i < 32768 - 0x1000; i++) {
+ uae_u8 b;
+ zfile_fread(&b, 1, 1, z);
+ ide->rom[0x2000 + i * 4 + 1] = b;
+ zfile_fread(&b, 1, 1, z);
+ ide->rom[0x2000 + i * 4 + 3] = b;
+ }
+ zfile_fclose(z);
+ } else {
+ romwarning(roms);
+ }
+ return ide->bank;
+}
+
+int alf_add_ide_unit(int ch, struct uaedev_config_info *ci, int devnum)
+{
+ struct ide_hdf *ide;
+
+ ide = add_ide_unit (&idecontroller_drive[(ALF_IDE + devnum) * 2], 2, ch, ci);
+ if (ide == NULL)
+ return 0;
+ return 1;
+}
+
+// prod 0x22 = IDE + SCSI
+// prod 0x23 = SCSI only
+// prod 0x33 = IDE only
+
+const uae_u8 apollo_autoconfig[16] = { 0xd2, 0x23, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, APOLLO_ROM_OFFSET >> 8, APOLLO_ROM_OFFSET & 0xff };
+const uae_u8 apollo_autoconfig_cpuboard[16] = { 0xd2, 0x23, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, APOLLO_ROM_OFFSET >> 8, APOLLO_ROM_OFFSET & 0xff };
+const uae_u8 apollo_autoconfig_cpuboard_060[16] = { 0xd2, 0x23, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x02, APOLLO_ROM_OFFSET >> 8, APOLLO_ROM_OFFSET & 0xff };
+
+addrbank *apollo_init(int devnum)
+{
+ struct ide_board *ide;
+ int roms[2];
+ struct romlist *rl;
+ const uae_u8 *autoconfig;
+ bool cpuboard = false;
+
+ if (devnum < 0) {
+ cpuboard = true;
+ devnum = 0;
+ }
+
+ ide = &apollo_board[devnum];
+ if (devnum > 0 && !ide->enabled)
+ return &expamem_null;
+
+ roms[0] = -1;
+ init_ide(ide, APOLLO_IDE + devnum, false);
+ ide->configured = 0;
+ ide->bank = &apollo_bank;
+ ide->type = APOLLO_IDE + devnum;
+ ide->rom_size = 32768;
+ ide->mask = 131072 - 1;
+
+ memset(ide->acmemory, 0xff, sizeof ide->acmemory);
+
+ ide->rom = xcalloc(uae_u8, ide->rom_size);
+ memset(ide->rom, 0xff, ide->rom_size);
+ ide->rom_mask = ide->rom_size - 1;
+ autoconfig = apollo_autoconfig;
+ if (cpuboard) {
+ if (currprefs.cpu_model == 68060)
+ autoconfig = apollo_autoconfig_cpuboard_060;
+ else
+ autoconfig = apollo_autoconfig_cpuboard;
+ }
+ const TCHAR *romname = cpuboard ? currprefs.acceleratorromfile : currprefs.apollorom.roms[0].romfile;
+ struct zfile *z = read_rom_name(romname);
+ if (!z) {
+ rl = getromlistbyids(roms, romname);
+ if (rl) {
+ z = read_rom(rl->rd);
+ }
+ }
+ for (int i = 0; i < 16; i++) {
+ uae_u8 b = autoconfig[i];
+ ew(ide, i * 4, b);
+ }
+ if (z) {
+ int len = zfile_size(z);
+ write_log(_T("Apollo BOOT ROM '%s' %d\n"), zfile_getname(z), len);
+ // skip 68060 $f0 ROM block
+ if (len >= 65536)
+ zfile_fseek(z, 32768, SEEK_SET);
+ for (int i = 0; i < 32768; i++) {
+ uae_u8 b;
+ zfile_fread(&b, 1, 1, z);
+ ide->rom[i] = b;
+ }
+ zfile_fclose(z);
+ } else {
+ romwarning(roms);
+ }
+ return ide->bank;
+}
+
+int apollo_add_ide_unit(int ch, struct uaedev_config_info *ci, int devnum)
+{
+ struct ide_hdf *ide;
+
+ ide = add_ide_unit (&idecontroller_drive[(APOLLO_IDE + devnum) * 2], 2, ch, ci);
+ if (ide == NULL)
+ return 0;
+ return 1;
+}
+
+static const uae_u8 masoboshi_fake_no_rom[] = { 0xcf, 0x1f, 0xff, 0xbf, 0xbf, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x9f, 0x2f };
+
+addrbank *masoboshi_init(int devnum)
+{
+ struct ide_board *ide;
+ int roms[2];
+ struct romlist *rl;
+
+ ide = &masoboshi_board[devnum];
+ if (devnum > 0 && !ide->enabled)
+ return &expamem_null;
+
+ roms[0] = 120;
+ roms[1] = -1;
+ init_ide(ide, MASOBOSHI_IDE + devnum, true);
+ ide->configured = 0;
+ ide->bank = &masoboshi_bank;
+ ide->type = MASOBOSHI_IDE + devnum;
+ ide->rom_size = 65536;
+ ide->mask = 65536 - 1;
+
+ ide->rom = xcalloc(uae_u8, ide->rom_size);
+ memset(ide->rom, 0xff, ide->rom_size);
+ memset(ide->acmemory, 0xff, sizeof ide->acmemory);
+ ide->rom_mask = ide->rom_size - 1;
+ if (_tcscmp (currprefs.masoboshirom.roms[0].romfile, _T(":NOROM"))) {
+ const TCHAR *romname = currprefs.masoboshirom.roms[0].romfile;
+ struct zfile *z = read_rom_name(romname);
+ if (!z) {
+ rl = getromlistbyids(roms, romname);
+ if (rl) {
+ z = read_rom(rl->rd);
+ }
+ }
+ if (z) {
+ int len = zfile_size(z);
+ write_log(_T("Masoboshi BOOT ROM '%s' %d\n"), zfile_getname(z), len);
+ for (int i = 0; i < 32768; i++) {
+ uae_u8 b;
+ zfile_fread(&b, 1, 1, z);
+ ide->rom[i * 2 + 0] = b;
+ ide->rom[i * 2 + 1] = 0xff;
+ }
+ zfile_fclose(z);
+ memcpy(ide->acmemory, ide->rom, sizeof ide->acmemory);
+ } else {
+ romwarning(roms);
+ }
+ } else {
+ for (int i = 0; i < sizeof masoboshi_fake_no_rom; i++) {
+ ide->acmemory[i * 2 + 0] = masoboshi_fake_no_rom[i];
+ }
+ }
+ // init SCSI part
+ ncr_masoboshi_autoconfig_init(devnum);
+ return ide->bank;
+}
+
+int masoboshi_add_ide_unit(int ch, struct uaedev_config_info *ci, int devnum)
+{
+ struct ide_hdf *ide;
+
+ ide = add_ide_unit (&idecontroller_drive[(MASOBOSHI_IDE + devnum) * 2], 2, ch, ci);
+ if (ide == NULL)
+ return 0;
+ return 1;
+}
#define COMMODORE_DMAC 1
#define COMMODORE_SDMAC 2
-#define GVP_DMAC 3
+#define GVP_DMAC_S2 3
+#define GVP_DMAC_S1 4
struct commodore_dmac
{
uae_u8 version;
uae_u32 addr_mask;
bool series2;
+ uae_u8 *buffer;
+ int bufoffset;
};
struct wd_state {
extern void a2091_free(void);
extern void a2091_reset (void);
-extern addrbank *gvp_init(int devnum);
+extern addrbank *gvp_init(int devnum, bool series2);
extern void gvp_free(void);
extern void gvp_reset (void);
#define BOARD_FUSIONFORTY 15
#define BOARD_A3001_I 16
#define BOARD_A3001_II 17
-
+#define BOARD_APOLLO 18
+#define BOARD_GVP_A530 19
#define HD_CONTROLLER_TYPE_IDE_AUTO 1
#define HD_CONTROLLER_TYPE_IDE_MB 2
#define HD_CONTROLLER_TYPE_IDE_GVP 3
-#define HD_CONTROLLER_TYPE_SCSI_AUTO 4
-#define HD_CONTROLLER_TYPE_SCSI_A2091 5
-#define HD_CONTROLLER_TYPE_SCSI_A2091_2 6
-#define HD_CONTROLLER_TYPE_SCSI_GVP 7
-#define HD_CONTROLLER_TYPE_SCSI_GVP_2 8
-#define HD_CONTROLLER_TYPE_SCSI_A4091 9
-#define HD_CONTROLLER_TYPE_SCSI_A4091_2 10
-#define HD_CONTROLLER_TYPE_SCSI_FASTLANE 11
-#define HD_CONTROLLER_TYPE_SCSI_FASTLANE_2 12
-#define HD_CONTROLLER_TYPE_SCSI_OKTAGON 13
-#define HD_CONTROLLER_TYPE_SCSI_OKTAGON_2 14
-#define HD_CONTROLLER_TYPE_SCSI_A3000 15
-#define HD_CONTROLLER_TYPE_SCSI_A4000T 16
-#define HD_CONTROLLER_TYPE_SCSI_CDTV 17
-#define HD_CONTROLLER_TYPE_SCSI_CPUBOARD 18
-#define HD_CONTROLLER_TYPE_PCMCIA_SRAM 19
-#define HD_CONTROLLER_TYPE_PCMCIA_IDE 20
+#define HD_CONTROLLER_TYPE_IDE_ALFA 4
+#define HD_CONTROLLER_TYPE_IDE_ALFA_2 5
+#define HD_CONTROLLER_TYPE_IDE_APOLLO 6
+#define HD_CONTROLLER_TYPE_IDE_APOLLO_2 7
+#define HD_CONTROLLER_TYPE_IDE_MASOBOSHI 8
+#define HD_CONTROLLER_TYPE_IDE_MASOBOSHI_2 9
+#define HD_CONTROLLER_TYPE_SCSI_AUTO 10
+#define HD_CONTROLLER_TYPE_SCSI_A2091 11
+#define HD_CONTROLLER_TYPE_SCSI_A2091_2 12
+#define HD_CONTROLLER_TYPE_SCSI_GVP 13
+#define HD_CONTROLLER_TYPE_SCSI_GVP_2 14
+#define HD_CONTROLLER_TYPE_SCSI_A4091 15
+#define HD_CONTROLLER_TYPE_SCSI_A4091_2 16
+#define HD_CONTROLLER_TYPE_SCSI_FASTLANE 17
+#define HD_CONTROLLER_TYPE_SCSI_FASTLANE_2 18
+#define HD_CONTROLLER_TYPE_SCSI_OKTAGON 19
+#define HD_CONTROLLER_TYPE_SCSI_OKTAGON_2 20
+#define HD_CONTROLLER_TYPE_SCSI_APOLLO 21
+#define HD_CONTROLLER_TYPE_SCSI_APOLLO_2 22
+#define HD_CONTROLLER_TYPE_SCSI_MASOBOSHI 23
+#define HD_CONTROLLER_TYPE_SCSI_MASOBOSHI_2 24
+#define HD_CONTROLLER_TYPE_SCSI_A3000 25
+#define HD_CONTROLLER_TYPE_SCSI_A4000T 26
+#define HD_CONTROLLER_TYPE_SCSI_CDTV 27
+#define HD_CONTROLLER_TYPE_SCSI_CPUBOARD 28
+#define HD_CONTROLLER_TYPE_PCMCIA_SRAM 29
+#define HD_CONTROLLER_TYPE_PCMCIA_IDE 30
#define HD_CONTROLLER_TYPE_IDE_FIRST 1
-#define HD_CONTROLLER_TYPE_IDE_LAST 3
-#define HD_CONTROLLER_TYPE_SCSI_FIRST 4
-#define HD_CONTROLLER_TYPE_SCSI_LAST 18
+#define HD_CONTROLLER_TYPE_IDE_LAST 9
+#define HD_CONTROLLER_TYPE_SCSI_FIRST 10
+#define HD_CONTROLLER_TYPE_SCSI_LAST 28
#define FILESYS_VIRTUAL 0
#define FILESYS_HARDFILE 1
int rom_size;
int rom_mask;
int configured;
+ int mask;
addrbank *bank;
struct ide_hdf *ide;
bool irq;
bool intena;
+ bool enabled;
+ int state;
+ int type;
+ int userdata;
};
struct ide_hdf
void ide_put_data (struct ide_hdf *ide, uae_u16 v);
uae_u16 ide_get_data (struct ide_hdf *ide);
-bool ide_interrupt_check(struct ide_hdf **ide, int num);
+bool ide_interrupt_check(struct ide_hdf *ide);
bool ide_isdrive(struct ide_hdf *ide);
void ide_initialize(struct ide_hdf **idetable, int chpair);
struct ide_hdf *add_ide_unit (struct ide_hdf **idetable, int max, int ch, struct uaedev_config_info *ci);
uae_u8 *ide_save_state(uae_u8 *dst, struct ide_hdf *ide);
uae_u8 *ide_restore_state(uae_u8 *src, struct ide_hdf *ide);
+#define IDE_MEMORY_FUNCTIONS(x, y, z) \
+static void REGPARAM2 x ## _bput(uaecptr addr, uae_u32 b) \
+{ \
+ y ## _write_byte(& ## z, addr, b); \
+} \
+static void REGPARAM2 x ## _wput(uaecptr addr, uae_u32 b) \
+{ \
+ y ## _write_word(& ## z, addr, b); \
+} \
+static void REGPARAM2 x ## _lput(uaecptr addr, uae_u32 b) \
+{ \
+ y ## _write_word(& ## z, addr, b >> 16); \
+ y ## _write_word(& ## z, addr + 2, b); \
+} \
+static uae_u32 REGPARAM2 x ## _bget(uaecptr addr) \
+{ \
+return y ## _read_byte(& ## z, addr); \
+} \
+static uae_u32 REGPARAM2 x ## _wget(uaecptr addr) \
+{ \
+return y ## _read_word(& ## z, addr); \
+} \
+static uae_u32 REGPARAM2 x ## _lget(uaecptr addr) \
+{ \
+ uae_u32 v = y ## _read_word(& ## z, addr) << 16; \
+ v |= y ## _read_word(& ## z, addr + 2); \
+ return v; \
+}
int gvp_add_ide_unit(int ch, struct uaedev_config_info *ci);
addrbank *gvp_ide_rom_autoconfig_init(void);
addrbank *gvp_ide_controller_autoconfig_init(void);
+
+int alf_add_ide_unit(int ch, struct uaedev_config_info *ci, int devnum);
+addrbank *alf_init(int);
+
+int apollo_add_ide_unit(int ch, struct uaedev_config_info *ci, int devnum);
+addrbank *apollo_init(int);
+
+int masoboshi_add_ide_unit(int ch, struct uaedev_config_info *ci, int devnum);
+addrbank *masoboshi_init(int);
+
+uae_u32 REGPARAM3 apollo_ide_lget (uaecptr addr) REGPARAM;
+uae_u32 REGPARAM3 apollo_ide_wget (uaecptr addr) REGPARAM;
+uae_u32 REGPARAM3 apollo_ide_bget (uaecptr addr) REGPARAM;
+void REGPARAM3 apollo_ide_lput (uaecptr addr, uae_u32 l) REGPARAM;
+void REGPARAM3 apollo_ide_wput (uaecptr addr, uae_u32 w) REGPARAM;
+void REGPARAM3 apollo_ide_bput (uaecptr addr, uae_u32 b) REGPARAM;
+extern const uae_u8 apollo_autoconfig[16];
+extern const uae_u8 apollo_autoconfig_060[16];
extern int cpuboard_dkb_add_scsi_unit(int ch, struct uaedev_config_info *ci);
extern int fastlane_add_scsi_unit(int ch, struct uaedev_config_info *ci, int devnum);
extern int oktagon_add_scsi_unit(int ch, struct uaedev_config_info *ci, int devnum);
+extern int masoboshi_add_scsi_unit(int ch, struct uaedev_config_info *ci, int devnum);
extern addrbank *ncr_fastlane_autoconfig_init(int devnum);
extern addrbank *ncr_oktagon_autoconfig_init(int devnum);
extern void cpuboard_ncr9x_scsi_put(uaecptr, uae_u32);
extern uae_u32 cpuboard_ncr9x_scsi_get(uaecptr);
+uae_u32 masoboshi_ncr9x_scsi_get(uaecptr addr, int devnum);
+void masoboshi_ncr9x_scsi_put(uaecptr addr, uae_u32 v, int devnum);
+void ncr_masoboshi_autoconfig_init(int devnum);
+
#define BLIZZARD_2060_SCSI_OFFSET 0x1ff00
#define BLIZZARD_2060_DMA_OFFSET 0x1fff0
#define BLIZZARD_2060_LED_OFFSET 0x1ffe0
struct boardromconfig a4091rom;
struct boardromconfig fastlanerom;
struct boardromconfig oktagonrom;
- struct boardromconfig gvprom;
+ struct boardromconfig gvps1rom;
+ struct boardromconfig gvps2rom;
+ struct boardromconfig alfrom;
+ struct boardromconfig alfplusrom;
+ struct boardromconfig apollorom;
+ struct boardromconfig masoboshirom;
TCHAR romfile[MAX_DPATH];
TCHAR romident[256];
#define ROMTYPE_CPUBOARDEXT 0x00100003
#define ROMTYPE_FASTLANE 0x00100004
#define ROMTYPE_OKTAGON 0x00100005
-#define ROMTYPE_GVP 0x00100006
-#define ROMTYPE_AMAX 0x00100007
+#define ROMTYPE_GVPS1 0x00100006
+#define ROMTYPE_GVPS2 0x00100007
+#define ROMTYPE_AMAX 0x00100008
+#define ROMTYPE_ALFA 0x00100009
+#define ROMTYPE_ALFAPLUS 0x0010000a
+#define ROMTYPE_APOLLO 0x0010000b
+#define ROMTYPE_MASOBOSHI 0x0010000c
#define ROMTYPE_QUAD 0x01000000
#define ROMTYPE_EVEN 0x02000000
extern void tape_free (struct scsi_data_tape*);
extern void tape_media_change (int unitnum, struct uaedev_config_info*);
+int add_scsi_hd (struct scsi_data **sd, int ch, struct hd_hardfiledata *hfd, struct uaedev_config_info *ci, int scsi_level);
+int add_scsi_cd (struct scsi_data **sd, int ch, int unitnum);
+int add_scsi_tape (struct scsi_data **sd, int ch, const TCHAR *tape_directory, bool readonly);
+void free_scsi (struct scsi_data *sd);
+
+void scsi_freenative(struct scsi_data **sd);
+void scsi_addnative(struct scsi_data **sd);
+
#define SCSI_NO_SENSE_DATA 0x00
#define SCSI_NOT_READY 0x04
#define SCSI_NOT_LOADED 0x09
{ \
return y ## _lget(& ## z, addr); \
}
+
+
+void apollo_scsi_bput(uaecptr addr, uae_u8 v);
+uae_u8 apollo_scsi_bget(uaecptr addr);
+int apollo_add_scsi_unit(int ch, struct uaedev_config_info *ci, int devnum);
+void apolloscsi_free(void);
+void apolloscsi_reset(void);
#define OKTAGON_EEPROM_SDA 0x8018
#define OKTAGON_EEPROM_SIZE 512
+#define MASOBOSHI_ESP_ADDR 0xfa00
+#define MASOBOSHI_DMA_START 0xf900
+#define MASOBOSHI_DMA_END 0xfa00
+
#define DKB_BOARD_SIZE 131072
#define DKB_ROM_SIZE 32768
#define DKB_ROM_OFFSET 0x8000
uaecptr dma_ptr;
int dma_cnt;
int state;
+ int state2;
+ int state3;
uae_u8 data;
bool data_valid;
bool romisoddonly;
bool romisevenonly;
- uae_u8 *dkb_data_buf;
- int dkb_data_size_allocated;
- int dkb_data_size;
- int dkb_data_offset;
- uae_u8 *dkb_data_write_buffer;
+ uae_u8 *fakedma_data_buf;
+ int fakedma_data_size_allocated;
+ int fakedma_data_size;
+ int fakedma_data_offset;
+ uae_u8 *fakedma_data_write_buffer;
};
static struct ncr9x_state ncr_blizzard_scsi;
static struct ncr9x_state ncr_fastlane_scsi[MAX_BOARD_ROMS];
static struct ncr9x_state ncr_oktagon2008_scsi[MAX_BOARD_ROMS];
+static struct ncr9x_state ncr_masoboshi_scsi[MAX_BOARD_ROMS];
static struct ncr9x_state ncr_dkb1200_scsi;
-
static struct ncr9x_state *ncrs[] =
{
&ncr_blizzard_scsi,
&ncr_fastlane_scsi[1],
&ncr_oktagon2008_scsi[0],
&ncr_oktagon2008_scsi[1],
+ &ncr_masoboshi_scsi[0],
+ &ncr_masoboshi_scsi[1],
&ncr_dkb1200_scsi,
NULL
};
void ncr9x_rethink(void)
{
for (int i = 0; ncrs[i]; i++) {
- if (ncrs[i]->boardirq)
+ if (ncrs[i]->boardirq) {
INTREQ_0(0x8000 | 0x0008);
+ return;
+ }
}
}
}
}
+static void set_irq2_masoboshi(struct ncr9x_state *ncr)
+{
+ if (ncr->chipirq && !ncr->boardirq) {
+ ncr->state2 |= 2;
+ ncr->boardirq = true;
+#if NCR_DEBUG > 1
+ write_log(_T("MASOBOSHI IRQ\n"));
+#endif
+ ncr9x_rethink();
+ }
+}
+
void esp_irq_raise(qemu_irq irq)
{
struct ncr9x_state *ncr = (struct ncr9x_state*)irq;
ncr->irq_func(ncr);
}
-static void dkb_buffer_size(struct ncr9x_state *ncr, int size)
+static void fakedma_buffer_size(struct ncr9x_state *ncr, int size)
{
size = (size + 1) & ~1;
- if (ncr->dkb_data_size_allocated >= size)
+ if (ncr->fakedma_data_size_allocated >= size)
return;
- if (ncr->dkb_data_buf)
- xfree(ncr->dkb_data_buf);
- ncr->dkb_data_buf = xmalloc(uae_u8, size);
- ncr->dkb_data_size_allocated = size;
+ if (ncr->fakedma_data_buf)
+ xfree(ncr->fakedma_data_buf);
+ ncr->fakedma_data_buf = xmalloc(uae_u8, size);
+ ncr->fakedma_data_size_allocated = size;
}
/* Fake DMA */
-static int dkb_dma_read(void *opaque, uint8_t *buf, int len)
+static int fake_dma_read(void *opaque, uint8_t *buf, int len)
{
struct ncr9x_state *ncr = (struct ncr9x_state*)opaque;
- ncr->dkb_data_offset = 0;
- ncr->dkb_data_write_buffer = buf;
- dkb_buffer_size(ncr, len);
+ ncr->fakedma_data_offset = 0;
+ ncr->fakedma_data_write_buffer = buf;
+ fakedma_buffer_size(ncr, len);
return 0;
}
-static int dkb_dma_write(void *opaque, uint8_t *buf, int len)
+static int fake_dma_write(void *opaque, uint8_t *buf, int len)
{
struct ncr9x_state *ncr = (struct ncr9x_state*)opaque;
- ncr->dkb_data_offset = 0;
- dkb_buffer_size(ncr, len);
- memcpy(ncr->dkb_data_buf, buf, len);
+ ncr->fakedma_data_offset = 0;
+ fakedma_buffer_size(ncr, len);
+ memcpy(ncr->fakedma_data_buf, buf, len);
if (len & 1)
- ncr->dkb_data_buf[len] = 0;
- ncr->dkb_data_size = len;
+ ncr->fakedma_data_buf[len] = 0;
+ ncr->fakedma_data_size = len;
return 0;
}
/* Fake DMA */
-static int oktagon_dma_read(void *opaque, uint8_t *buf, int len)
+static int fake2_dma_read(void *opaque, uint8_t *buf, int len)
{
struct ncr9x_state *ncr = (struct ncr9x_state*)opaque;
esp_dma_enable(ncr->devobject.lsistate, 0);
}
return 1;
}
-static int oktagon_dma_write(void *opaque, uint8_t *buf, int len)
+static int fake2_dma_write(void *opaque, uint8_t *buf, int len)
{
struct ncr9x_state *ncr = (struct ncr9x_state*)opaque;
esp_dma_enable(ncr->devobject.lsistate, 0);
{
int reg_shift = 2;
addr &= ncr->board_mask;
- if (ncr == &ncr_oktagon2008_scsi[0] || ncr == &ncr_oktagon2008_scsi[1]) {
+ if (ncr == &ncr_masoboshi_scsi[0] || ncr == &ncr_masoboshi_scsi[1]) {
+
+ if (addr >= 0xf04c && addr < 0xf04f) {
+ int shift = (addr - 0xf04c) * 8;
+ uae_u32 mask = 0xff << shift;
+ ncr->dma_ptr &= ~mask;
+ ncr->dma_ptr |= val << shift;
+ ncr->dma_ptr &= 0xffffff;
+ return;
+ }
+ if (addr >= 0xf040 && addr <= 0xf047) {
+ if (addr == 0xf047) {
+ if (val & 0x80)
+ ncr->state3 = 0x80;
+ }
+ if (addr == 0xf040) {
+ ncr->state3 = 0;
+ }
+ return;
+ }
+
+ if (addr == 0xf007) {
+ ncr->state = val;
+ }
+ if (addr == 0xf000) {
+ ncr->state2 &= ~2;
+ }
+ if (addr == 0xf004) {
+ ncr->state2 &= ~1;
+ }
+ if (addr >= MASOBOSHI_DMA_START && addr < MASOBOSHI_DMA_END) {
+ if (esp_reg_read(ncr->devobject.lsistate, ESP_RSTAT) & STAT_TC) {
+#if NCR_DEBUG > 2
+ write_log(_T("MASOBOSHI DMA OVERFLOW %08X PUT %02x %08x\n"), addr, val & 0xff, M68K_GETPC);
+#endif
+ } else {
+ ncr->data = val;
+ ncr->data_valid = true;
+ esp_dma_enable(ncr->devobject.lsistate, 1);
+#if NCR_DEBUG > 2
+ write_log(_T("MASOBOSHI DMA %08X PUT %02x %08x\n"), addr, val & 0xff, M68K_GETPC);
+#endif
+ }
+ return;
+ }
+ if (addr < MASOBOSHI_ESP_ADDR || addr >= MASOBOSHI_ESP_ADDR + 0x100) {
+#if NCR_DEBUG
+ write_log(_T("MASOBOSHI IO %08X PUT %02x %08x\n"), addr, val & 0xff, M68K_GETPC);
+#endif
+ return;
+ }
+ if (addr == MASOBOSHI_ESP_ADDR + 3 * 2 && val == 0x02)
+ ncr->state |= 0x80;
+ reg_shift = 1;
+ addr &= 0x3f;
+
+ } else if (ncr == &ncr_oktagon2008_scsi[0] || ncr == &ncr_oktagon2008_scsi[1]) {
if (addr == OKTAGON_EEPROM_SCL) {
eeprom_i2c_set(ncr->eeprom, BITBANG_I2C_SCL, (val & 0x80) != 0);
} else if (addr == OKTAGON_EEPROM_SDA) {
}
if (addr >= 0x10080 && addr < 0x10088) {
//write_log(_T("DKB PUT BYTE %02x\n"), val & 0xff);
- if (ncr->dkb_data_offset < ncr->dkb_data_size) {
- ncr->dkb_data_buf[ncr->dkb_data_offset++] = val;
- if (ncr->dkb_data_offset == ncr->dkb_data_size) {
- memcpy(ncr->dkb_data_write_buffer, ncr->dkb_data_buf, ncr->dkb_data_size);
+ if (ncr->fakedma_data_offset < ncr->fakedma_data_size) {
+ ncr->fakedma_data_buf[ncr->fakedma_data_offset++] = val;
+ if (ncr->fakedma_data_offset == ncr->fakedma_data_size) {
+ memcpy(ncr->fakedma_data_write_buffer, ncr->fakedma_data_buf, ncr->fakedma_data_size);
esp_fake_dma_done(ncr->devobject.lsistate);
}
}
}
+static int perse = 0;
+
uae_u32 ncr9x_io_bget(struct ncr9x_state *ncr, uaecptr addr)
{
uae_u8 v;
int reg_shift = 2;
addr &= ncr->board_mask;
- if (ncr == &ncr_oktagon2008_scsi[0] || ncr == &ncr_oktagon2008_scsi[1]) {
+ if (ncr == &ncr_masoboshi_scsi[0] || ncr == &ncr_masoboshi_scsi[1]) {
+
+ if (addr == MASOBOSHI_ESP_ADDR + 3 * 2 && (ncr->state & 0x80))
+ return 2;
+ if (ncr->state & 0x80)
+ ncr->state &= ~0x80;
+
+ if (addr == 0xf040) {
+ return ncr->state3;
+ }
+
+ if (addr == 0xf000) {
+ if (esp_reg_read(ncr->devobject.lsistate, ESP_RSTAT) & STAT_TC) {
+ if (perse)
+ activate_debugger();
+ ncr->state2 |= 1; // dma complete
+ }
+ return ncr->state2 & 0x7f;
+ }
+ if (addr == 0xf007) {
+ v = ncr->state;
+ }
+ if (addr >= MASOBOSHI_DMA_START && addr < MASOBOSHI_DMA_END) {
+ esp_dma_enable(ncr->devobject.lsistate, 1);
+ v = ncr->data;
+ ncr->data_valid = false;
+#if NCR_DEBUG > 2
+ write_log(_T("MASOBOSHI DMA %08X GET %02x %08x\n"), addr, v, M68K_GETPC);
+#endif
+ return v;
+ }
+ if (addr < MASOBOSHI_ESP_ADDR || addr >= MASOBOSHI_ESP_ADDR + 0x100) {
+#if NCR_DEBUG
+ write_log(_T("MASOBOSHI IO %08X GET %02x %08x\n"), addr, v, M68K_GETPC);
+#endif
+ return v;
+ }
+ reg_shift = 1;
+ addr &= 0x3f;
+
+ } else if (ncr == &ncr_oktagon2008_scsi[0] || ncr == &ncr_oktagon2008_scsi[1]) {
if (addr == OKTAGON_EEPROM_SCL) {
return eeprom_i2c_set(ncr->eeprom, BITBANG_I2C_SCL, -1) ? 0x80 : 0x00;
} else if (addr == OKTAGON_EEPROM_SDA) {
uae_u8 v = 0;
if (ncr->chipirq)
v |= 0x40;
- if (ncr->dkb_data_offset < ncr->dkb_data_size)
+ if (ncr->fakedma_data_offset < ncr->fakedma_data_size)
v |= 0x80;
//write_log(_T("DKB IO GET %02x %08x\n"), v, M68K_GETPC);
return v;
}
if (addr >= 0x10080 && addr < 0x10088) {
- //write_log(_T("DKB GET BYTE %02x\n"), ncr->dkb_data_buf[ncr->dkb_data_offset]);
- if (ncr->dkb_data_offset >= ncr->dkb_data_size)
+ //write_log(_T("DKB GET BYTE %02x\n"), ncr->fakedma_data_buf[ncr->fakedma_data_offset]);
+ if (ncr->fakedma_data_offset >= ncr->fakedma_data_size)
return 0;
- if (ncr->dkb_data_offset == ncr->dkb_data_size - 1) {
+ if (ncr->fakedma_data_offset == ncr->fakedma_data_size - 1) {
esp_fake_dma_done(ncr->devobject.lsistate);
//write_log(_T("DKB fake dma finished\n"));
}
- return ncr->dkb_data_buf[ncr->dkb_data_offset++];
+ return ncr->fakedma_data_buf[ncr->fakedma_data_offset++];
}
if (addr < 0x10000 || addr >= 0x10040) {
write_log(_T("DKB IO GET %08x %08x\n"), addr, M68K_GETPC);
ncr9x_io_bput(&ncr_blizzard_scsi, addr, v);
}
+uae_u32 masoboshi_ncr9x_scsi_get(uaecptr addr, int devnum)
+{
+ return ncr9x_io_bget(&ncr_masoboshi_scsi[devnum], addr);
+}
+void masoboshi_ncr9x_scsi_put(uaecptr addr, uae_u32 v, int devnum)
+{
+ ncr9x_io_bput(&ncr_masoboshi_scsi[devnum], addr, v);
+}
+
static void ew(struct ncr9x_state *ncr, int addr, uae_u8 value)
{
if (addr == 00 || addr == 02 || addr == 0x40 || addr == 0x42) {
ncr->bank = &ncr_bank_dkb;
ncr->board_mask = DKB_BOARD_SIZE - 1;
ncr->irq_func = set_irq2_dkb1200;
+ } else if (ncr == &ncr_masoboshi_scsi[0] || ncr == &ncr_masoboshi_scsi[1]) {
+ ncr->irq_func = set_irq2_masoboshi;
}
- ncr->name = ncr->bank->name;
+ if (ncr->bank)
+ ncr->name = ncr->bank->name;
}
void ncr9x_reset(void)
}
+void ncr_masoboshi_autoconfig_init(int devnum)
+{
+ struct ncr9x_state *ncr = &ncr_masoboshi_scsi[devnum];
+
+ if (!ncr->enabled && devnum > 0)
+ return;
+
+ ncr->enabled = true;
+
+ ncr9x_init ();
+ ncr9x_reset_board(ncr);
+}
+
+
static void freescsi_hdf(struct scsi_data *sd)
{
if (!sd)
esp_scsi_init(&ncr_blizzard_scsi.devobject, blizzard_dma_read, blizzard_dma_write);
esp_scsi_init(&ncr_fastlane_scsi[0].devobject, fastlane_dma_read, fastlane_dma_write);
esp_scsi_init(&ncr_fastlane_scsi[1].devobject, fastlane_dma_read, fastlane_dma_write);
- esp_scsi_init(&ncr_oktagon2008_scsi[0].devobject, oktagon_dma_read, oktagon_dma_write);
- esp_scsi_init(&ncr_oktagon2008_scsi[1].devobject, oktagon_dma_read, oktagon_dma_write);
- esp_scsi_init(&ncr_dkb1200_scsi.devobject, dkb_dma_read, dkb_dma_write);
+ esp_scsi_init(&ncr_oktagon2008_scsi[0].devobject, fake2_dma_read, fake2_dma_write);
+ esp_scsi_init(&ncr_oktagon2008_scsi[1].devobject, fake2_dma_read, fake2_dma_write);
+ esp_scsi_init(&ncr_dkb1200_scsi.devobject, fake_dma_read, fake_dma_write);
+ esp_scsi_init(&ncr_masoboshi_scsi[0].devobject, fake2_dma_read, fake2_dma_write);
+ esp_scsi_init(&ncr_masoboshi_scsi[1].devobject, fake2_dma_read, fake2_dma_write);
}
}
return ncr9x_add_scsi_unit(&ncr_oktagon2008_scsi[devnum], ch, ci);
}
+int masoboshi_add_scsi_unit (int ch, struct uaedev_config_info *ci, int devnum)
+{
+ return ncr9x_add_scsi_unit(&ncr_masoboshi_scsi[devnum], ch, ci);
+}
+
+
#endif
s->async_buf = scsiesp_req_get_buf(req);
if (s->dma_left) {
esp_do_dma(s);
- } else if (s->dma_counter != 0 && s->ti_size <= 0) {
+ } else if (s->dma_counter != 0 && s->ti_size == 0) {
/* If this was the last part of a DMA transfer then the
completion interrupt is deferred to here. */
esp_dma_done(s);
esp_lower_irq(s);
return old_val;
+ case ESP_RFLAGS:
+ return s->rregs[saddr] | s->rregs[ESP_RSEQ] << 5;
case ESP_RES4:
return 0x80 | 0x20 | 0x2;
default:
s->rregs[ESP_RINTR] = INTR_DC;
s->rregs[ESP_RSEQ] = 0;
s->rregs[ESP_RFLAGS] = 0;
+ // Masoboshi driver expects phase=0!
+ s->rregs[ESP_RSTAT] &= ~7;
esp_raise_irq(s);
break;
case CMD_PAD:
s->rregs[ESP_RINTR] = 0;
break;
case CMD_DISSEL:
- s->rregs[ESP_RINTR] = 0;
+ // Masoboshi driver expects Function Complete.
+ s->rregs[ESP_RINTR] = INTR_FC;
esp_raise_irq(s);
break;
default:
return NULL;
}
-#define NEXT_ROM_ID 117
+#define NEXT_ROM_ID 121
static struct romheader romheaders[] = {
{ _T("Freezer Cartridges"), 1 },
ALTROM(116, 1, 1, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, 0x1909f7e9, 0x5abe9b9d,0xaae328c8,0x134e2b62,0x7b33b698,0xe342afc2)
ALTROM(116, 1, 2, 32768, ROMTYPE_ODD | ROMTYPE_8BIT, 0xa3927c72, 0x7adc9352,0x2d112ae9,0x23b9a70d,0x951b1e7a,0xba800ea6)
-
{ _T("Freezer: HRTMon v2.33 (built-in)"), 0, 0, 0, 0, _T("HRTMON\0"), 0, 63, 0, 0, ROMTYPE_HRTMON, 0, 1, NULL,
0xffffffff, 0, 0, 0, 0, 0, _T("HRTMon") },
ALTROMPN(113, 1, 2, 32768, ROMTYPE_QUAD | ROMTYPE_ODD | ROMTYPE_8BIT, _T("U27"), 0x38373cf6, 0xfe8aa931, 0xada6b6f3, 0x6b48ca3c, 0x9b86677d, 0xbee4da59)
ALTROMPN(113, 1, 3, 32768, ROMTYPE_QUAD | ROMTYPE_EVEN | ROMTYPE_8BIT, _T("U25"), 0xc9e990d3, 0xb251ef73, 0x1374e796, 0xa87cbc7e, 0x9263320a, 0x28a71d2b)
ALTROMPN(113, 1, 4, 32768, ROMTYPE_QUAD | ROMTYPE_ODD | ROMTYPE_8BIT, _T("U26"), 0x2e117fe0, 0xbb2de2da, 0x6db4e92c, 0x636fefe6, 0x13a32699, 0xcea31011)
+ { _T("Apollo 1240/1260 ROM"), 5, 60, 5, 60, _T("APOLLO12XX\0"), 131072, 119, 0, 0, ROMTYPE_CPUBOARD, 0, 0, NULL,
+ 0xcd009ad9, 0x1c3b4851,0xc5a221e3,0xa7ca24fc,0xc1df4a5b,0x9f2343ad },
+ { _T("GVP A3001 Series I ROM"), 3, 3, 3, 3, _T("A3001SI\0"), 8192, 114, 0, 0, ROMTYPE_CPUBOARD, 0, 0, NULL,
+ 0xaaff7c65, 0x424cf3da,0xcc9da794,0x0ba74446,0x69dd1691,0x44ae87ee, NULL, NULL },
- { _T("GVP Series I ROM"), 3, 15, 3, 15, _T("GVP\0"), 16384, 111, 0, 0, ROMTYPE_GVP, 0, 0, NULL,
+ { _T("GVP Series II v3.15 ROM"), 3, 15, 3, 15, _T("GVPII\0"), 16384, 111, 0, 0, ROMTYPE_GVPS2, 0, 0, NULL,
0xf99c6f11, 0x77098a9e,0x35acaef2,0x11a546f0,0xc564cdac,0xf52836c4, NULL, NULL },
- { _T("GVP Series II ROM"), 4, 15, 4, 15, _T("GVPII\0"), 16384, 109, 0, 0, ROMTYPE_GVP, 0, 0, NULL,
+ { _T("GVP Series II v4.15 ROM"), 4, 15, 4, 15, _T("GVPII\0"), 16384, 109, 0, 0, ROMTYPE_GVPS2, 0, 0, NULL,
0xf89f44d6, 0xbf10c12c,0xc72dd040,0x549ea17c,0x24947633,0xe3773297, NULL, NULL },
- { _T("GVP Series II Guru ROM"), 6, 14, 6, 14, _T("GVPII\0"), 32768, 110, 0, 0, ROMTYPE_GVP, 0, 0, NULL,
+ { _T("GVP Series II Guru ROM"), 6, 14, 6, 14, _T("GVPII\0"), 32768, 110, 0, 0, ROMTYPE_GVPS2, 0, 0, NULL,
0x756103b1, 0x7f1335ea,0xf5b7ce73,0xc5231173,0x261da5aa,0xe7249645, NULL, NULL },
-
- { _T("GVP A3001 Series I ROM"), 3, 3, 3, 3, _T("A3001SI\0"), 8192, 114, 0, 0, ROMTYPE_CPUBOARD, 0, 0, NULL,
- 0xaaff7c65, 0x424cf3da,0xcc9da794,0x0ba74446,0x69dd1691,0x44ae87ee, NULL, NULL },
-
+ { _T("AlfaPower v6.10 ROM"), 6, 10, 6, 10, _T("ALFAPOWER\0"), 32768, 117, 0, 0, ROMTYPE_ALFA, 0, 0, NULL,
+ 0x1cfb0a0b, 0xc7275eda,0x547d6664,0x5c4eb7a0,0x3b5cef37,0xa498365a, NULL, NULL },
+ { _T("AlfaPower v8.3 ROM"), 8, 3, 8, 3, _T("ALFAPOWERPLUS\0"), 32768, 118, 0, 0, ROMTYPE_ALFAPLUS, 0, 0, NULL,
+ 0xe8201bad, 0xdefea015,0x596fce32,0x11e84397,0x23046a31,0x5a7726dc, NULL, NULL },
+ { _T("Masoboshi MC-702 ROM"), 2, 201, 2, 201, _T("MASOBOSHI\0"), 32768, 120, 0, 0, ROMTYPE_MASOBOSHI, 0, 0, NULL,
+ 0xcd99b98a, 0x3897e46a,0x66d5833f,0x849b8e81,0x30acb3cb,0x319a2fa0, NULL, NULL },
{ _T("CyberStorm MK I 68040"), 0, 0, 0, 0, _T("CSMKI\0"), 32768, 95, 0, 0, ROMTYPE_CPUBOARD, 0, 0, NULL,
0, 0, 0, 0, 0, 0, NULL, _T("cyberstormmk1_040.rom") },
TCHAR tmp1[MAX_DPATH], tmp2[MAX_DPATH];
TCHAR tmp3[MAX_DPATH];
+ if (ids[0] == -1)
+ return;
exp = 0;
tmp2[0] = 0;
i = 0;
#include "filesys.h"
#include "blkdev.h"
#include "zfile.h"
+#include "debug.h"
#define SCSI_EMU_DEBUG 0
+#define RAW_SCSI_DEBUG 0
extern int log_scsiemu;
return 0;
}
+void free_scsi (struct scsi_data *sd)
+{
+ if (!sd)
+ return;
+ hdf_hd_close (sd->hfd);
+ scsi_free (sd);
+}
+
+int add_scsi_hd (struct scsi_data **sd, int ch, struct hd_hardfiledata *hfd, struct uaedev_config_info *ci, int scsi_level)
+{
+ free_scsi (sd[ch]);
+ sd[ch] = NULL;
+ if (!hfd) {
+ hfd = xcalloc (struct hd_hardfiledata, 1);
+ memcpy (&hfd->hfd.ci, ci, sizeof (struct uaedev_config_info));
+ }
+ if (!hdf_hd_open (hfd))
+ return 0;
+ hfd->ansi_version = scsi_level;
+ sd[ch] = scsi_alloc_hd (ch, hfd);
+ return sd[ch] ? 1 : 0;
+}
+
+int add_scsi_cd (struct scsi_data **sd, int ch, int unitnum)
+{
+ device_func_init (0);
+ free_scsi (sd[ch]);
+ sd[ch] = scsi_alloc_cd (ch, unitnum, false);
+ return sd[ch] ? 1 : 0;
+}
+
+int add_scsi_tape (struct scsi_data **sd, int ch, const TCHAR *tape_directory, bool readonly)
+{
+ free_scsi (sd[ch]);
+ sd[ch] = scsi_alloc_tape (ch, tape_directory, readonly);
+ return sd[ch] ? 1 : 0;
+}
+
+void scsi_freenative(struct scsi_data **sd)
+{
+ for (int i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) {
+ free_scsi (sd[i]);
+ sd[i] = NULL;
+ }
+}
+
+void scsi_addnative(struct scsi_data **sd)
+{
+ int i, j;
+ int devices[MAX_TOTAL_SCSI_DEVICES];
+ int types[MAX_TOTAL_SCSI_DEVICES];
+ struct device_info dis[MAX_TOTAL_SCSI_DEVICES];
+
+ scsi_freenative (sd);
+ i = 0;
+ while (i < MAX_TOTAL_SCSI_DEVICES) {
+ types[i] = -1;
+ devices[i] = -1;
+ if (sys_command_open (i)) {
+ if (sys_command_info (i, &dis[i], 0)) {
+ devices[i] = i;
+ types[i] = 100 - i;
+ if (dis[i].type == INQ_ROMD)
+ types[i] = 1000 - i;
+ }
+ sys_command_close (i);
+ }
+ i++;
+ }
+ i = 0;
+ while (devices[i] >= 0) {
+ j = i + 1;
+ while (devices[j] >= 0) {
+ if (types[i] > types[j]) {
+ int tmp = types[i];
+ types[i] = types[j];
+ types[j] = tmp;
+ }
+ j++;
+ }
+ i++;
+ }
+ i = 0; j = 0;
+ while (devices[i] >= 0 && j < 7) {
+ if (sd[j] == NULL) {
+ sd[j] = scsi_alloc_native(j, devices[i]);
+ write_log (_T("SCSI: %d:'%s'\n"), j, dis[i].label);
+ i++;
+ }
+ j++;
+ }
+}
+
+
// raw scsi
+
+#define SCSI_IO_BUSY 0x80
+#define SCSI_IO_ATN 0x40
+#define SCSI_IO_SEL 0x20
+#define SCSI_IO_REQ 0x10
+#define SCSI_IO_DIRECTION 0x01
+#define SCSI_IO_COMMAND 0x02
+#define SCSI_IO_MESSAGE 0x04
+
+#define SCSI_SIGNAL_PHASE_FREE -1
+#define SCSI_SIGNAL_PHASE_ARBIT -2
+#define SCSI_SIGNAL_PHASE_SELECT_1 -3
+#define SCSI_SIGNAL_PHASE_SELECT_2 -4
+
#define SCSI_SIGNAL_PHASE_DATA_OUT 0
#define SCSI_SIGNAL_PHASE_DATA_IN 1
#define SCSI_SIGNAL_PHASE_COMMAND 2
#define SCSI_SIGNAL_PHASE_MESSAGE_OUT 6
#define SCSI_SIGNAL_PHASE_MESSAGE_IN 7
-#define SCSI_BUS_PHASE_FREE 0
-#define SCSI_BUS_PHASE_ARBITRATION 1
-#define SCSI_BUS_PHASE_SELECTION 2
-#define SCSI_BUS_PHASE_RESELECTION 3
-#define SCSI_BUS_PHASE_COMMAND 4
-#define SCSI_BUS_PHASE_DATA_IN 5
-#define SCSI_BUS_PHASE_DATA_OUT 6
-#define SCSI_BUS_PHASE_STATUS 7
-#define SCSI_BUS_PHASE_MESSAGE_IN 8
-#define SCSI_BUS_PHASE_MESSAGE_OUT 9
-
-struct raw_scsi_device
-{
- int x;
- int id;
-};
struct raw_scsi
{
- int signal_phase;
- int old_signal_phase;
+ int io;
int bus_phase;
+ bool atn;
uae_u8 data;
- int initiator;
- int target;
- uae_u8 cmd[16];
- int len;
- struct raw_scsi_device *device[8];
+ int initiator_id, target_id;
+ struct scsi_data *device[8];
+ struct scsi_data *target;
};
-struct raw_scsi *new_raw_scsi(void)
+void raw_scsi_reset(struct raw_scsi *rs)
{
- struct raw_scsi *rs = xcalloc(struct raw_scsi, 1);
- return rs;
+ rs->target = NULL;
+ rs->io = 0;
+ rs->bus_phase = SCSI_SIGNAL_PHASE_FREE;
}
-void free_raw_scsi(struct raw_scsi *rs)
+void raw_scsi_busfree(struct raw_scsi *rs)
{
- if (!rs)
- return;
- for (int i = 0; i < 8; i++)
- xfree(rs->device[i]);
- xfree(rs);
+ rs->target = NULL;
+ rs->io = 0;
+ rs->bus_phase = SCSI_SIGNAL_PHASE_FREE;
}
-struct raw_scsi_device *new_raw_scsi_device(struct raw_scsi *rs, int id)
+static void bus_free(struct raw_scsi *rs)
{
- rs->device[id] = xcalloc(struct raw_scsi_device, 1);
- rs->device[id]->id = id;
- return rs->device[id];
+ rs->bus_phase = SCSI_SIGNAL_PHASE_FREE;
+ rs->io = 0;
}
-void free_raw_scsi_device(struct raw_scsi *rs, struct raw_scsi_device *dev)
+static int getbit(uae_u8 v)
{
- if (!dev)
- return;
- rs->device[dev->id] = NULL;
- xfree(dev);
+ for (int i = 0; i < 8; i++) {
+ if ((1 << i) & v)
+ return i;
+ }
+ return -1;
}
-int raw_scsi_get_signal_phase(struct raw_scsi *rs, struct raw_scsi_device *dev)
+void raw_scsi_set_signal_phase(struct raw_scsi *rs, bool busy, bool select, bool atn)
{
- return rs->signal_phase;
+ switch (rs->bus_phase)
+ {
+ case SCSI_SIGNAL_PHASE_FREE:
+ if (busy && !select) {
+ rs->bus_phase = SCSI_SIGNAL_PHASE_ARBIT;
+ }
+ break;
+ case SCSI_SIGNAL_PHASE_ARBIT:
+ rs->target_id = -1;
+ rs->target = NULL;
+ if (busy && select) {
+ rs->bus_phase = SCSI_SIGNAL_PHASE_SELECT_1;
+ }
+ break;
+ case SCSI_SIGNAL_PHASE_SELECT_1:
+ rs->atn = atn;
+ if (!busy) {
+ uae_u8 data = rs->data & ~(1 << rs->initiator_id);
+ rs->target_id = getbit(data);
+ if (rs->target_id >= 0) {
+ rs->target = rs->device[rs->target_id];
+ if (rs->target) {
+#if RAW_SCSI_DEBUG
+ write_log(_T("raw_scsi: selected id %d\n"), rs->target_id);
+#endif
+ rs->io |= SCSI_IO_BUSY;
+ } else {
+#if RAW_SCSI_DEBUG
+ write_log(_T("raw_scsi: selected non-existing id %d\n"), rs->target_id);
+#endif
+ rs->target_id = -1;
+ }
+ }
+ if (rs->target_id >= 0) {
+ rs->bus_phase = SCSI_SIGNAL_PHASE_SELECT_2;
+ } else {
+ if (!select) {
+ rs->bus_phase = SCSI_SIGNAL_PHASE_FREE;
+ }
+ }
+ }
+ break;
+ case SCSI_SIGNAL_PHASE_SELECT_2:
+ if (!select) {
+ scsi_start_transfer(rs->target);
+ rs->bus_phase = rs->atn ? SCSI_SIGNAL_PHASE_MESSAGE_IN : SCSI_SIGNAL_PHASE_COMMAND;
+ rs->io = SCSI_IO_BUSY | SCSI_IO_REQ;
+ }
+ break;
+ }
}
-void raw_scsi_put_signal_phase(struct raw_scsi *rs, struct raw_scsi_device *dev, uae_u8 phase)
+uae_u8 raw_scsi_get_signal_phase(struct raw_scsi *rs)
{
- if (rs->signal_phase == phase)
- return;
- rs->old_signal_phase = rs->signal_phase;
- rs->signal_phase = phase;
- switch(rs->bus_phase)
+ uae_u8 v = rs->io;
+ if (rs->bus_phase >= 0)
+ v |= rs->bus_phase;
+ return v;
+}
+
+uae_u8 raw_scsi_get_data(struct raw_scsi *rs)
+{
+ struct scsi_data *sd = rs->target;
+ uae_u8 v = 0;
+
+ switch (rs->bus_phase)
{
- case SCSI_BUS_PHASE_FREE:
+ case SCSI_SIGNAL_PHASE_FREE:
+#if RAW_SCSI_DEBUG
+ write_log(_T("raw_scsi: bus free\n"));
+#endif
+ v = 0;
+ break;
+ case SCSI_SIGNAL_PHASE_ARBIT:
+#if RAW_SCSI_DEBUG
+ write_log(_T("raw_scsi: arbitration\n"));
+#endif
+ v = rs->data;
+ break;
+ case SCSI_SIGNAL_PHASE_DATA_IN:
+ if (scsi_receive_data(sd, & v)) {
+ rs->bus_phase = SCSI_SIGNAL_PHASE_STATUS;
+#if RAW_SCSI_DEBUG
+ write_log(_T("raw_scsi: data in finished, %d bytes: status phase\n"), sd->offset);
+#endif
+ }
+ break;
+ case SCSI_SIGNAL_PHASE_STATUS:
+#if RAW_SCSI_DEBUG
+ write_log(_T("raw_scsi: status byte read %02x\n"), sd->status);
+#endif
+ v = sd->status;
+ bus_free(rs);
+ break;
+ default:
+ write_log(_T("raw_scsi_get_data but bus phase is %d!\n"), rs->bus_phase);
+ break;
+ }
+
+ return v;
+}
+
+void raw_scsi_put_data(struct raw_scsi *rs, uae_u8 data)
+{
+ struct scsi_data *sd = rs->target;
+ int len;
+ rs->data = data;
+ switch (rs->bus_phase)
+ {
+ case SCSI_SIGNAL_PHASE_ARBIT:
+ rs->initiator_id = getbit(data);
+ write_log(_T("raw_scsi: arbitration initiator id %d\n"), rs->initiator_id);
break;
-
+ case SCSI_SIGNAL_PHASE_SELECT_1:
+ break;
+ case SCSI_SIGNAL_PHASE_COMMAND:
+ sd->cmd[sd->offset++] = data;
+ len = scsicmdsizes[sd->cmd[0] >> 5];
+ if (sd->offset >= len) {
+#if RAW_SCSI_DEBUG
+ write_log(_T("raw_scsi: got command %02x (%d bytes)\n"), sd->cmd[0], len);
+#endif
+ scsi_emulate_analyze(rs->target);
+ if (sd->direction > 0) {
+#if RAW_SCSI_DEBUG
+ write_log(_T("raw_scsi: data out %d bytes required\n"), sd->data_len);
+#endif
+ scsi_start_transfer(sd);
+ rs->bus_phase = SCSI_SIGNAL_PHASE_DATA_OUT;
+ } else if (sd->direction <= 0) {
+ scsi_emulate_cmd(sd);
+ scsi_start_transfer(sd);
+ if (!sd->status && sd->data_len > 0) {
+#if RAW_SCSI_DEBUG
+ write_log(_T("raw_scsi: data in %d bytes waiting\n"), sd->data_len);
+#endif
+ rs->bus_phase = SCSI_SIGNAL_PHASE_DATA_IN;
+ } else {
+#if RAW_SCSI_DEBUG
+ write_log(_T("raw_scsi: no data, status = %d\n"), sd->status);
+#endif
+ rs->bus_phase = SCSI_SIGNAL_PHASE_STATUS;
+ }
+ }
+ }
+ break;
+ case SCSI_SIGNAL_PHASE_DATA_OUT:
+ if (scsi_send_data(sd, data)) {
+#if RAW_SCSI_DEBUG
+ write_log(_T("raw_scsi: data out finished, %d bytes\n"), sd->data_len);
+#endif
+ scsi_emulate_cmd(sd);
+ rs->bus_phase = SCSI_SIGNAL_PHASE_STATUS;
+ }
+ break;
+ default:
+ write_log(_T("raw_scsi_put_data but bus phase is %d!\n"), rs->bus_phase);
+ break;
+ }
+}
+
+struct apollo_soft_scsi
+{
+ bool enabled;
+ int configured;
+ bool autoconfig;
+ bool irq;
+ struct raw_scsi rscsi;
+};
+static struct apollo_soft_scsi apolloscsi[2];
+
+void apollo_scsi_bput(uaecptr addr, uae_u8 v)
+{
+ int bank = addr & (0x800 | 0x400);
+ struct apollo_soft_scsi *as = &apolloscsi[0];
+ struct raw_scsi *rs = &as->rscsi;
+ addr &= 0x3fff;
+ if (bank == 0) {
+ raw_scsi_put_data(rs, v);
+ } else if (bank == 0xc00 && !(addr & 1)) {
+ as->irq = (v & 64) != 0;
+ raw_scsi_set_signal_phase(rs,
+ (v & 128) != 0,
+ (v & 32) != 0,
+ false);
+ } else if (bank == 0x400 && (addr & 1)) {
+ raw_scsi_set_signal_phase(rs, true, false, false);
+ raw_scsi_put_data(rs, v);
+ }
+ //write_log(_T("apollo scsi put %04x = %02x\n"), addr, v);
+}
+
+uae_u8 apollo_scsi_bget(uaecptr addr)
+{
+ int bank = addr & (0x800 | 0x400);
+ struct apollo_soft_scsi *as = &apolloscsi[0];
+ struct raw_scsi *rs = &as->rscsi;
+ uae_u8 v = 0xff;
+ addr &= 0x3fff;
+ if (bank == 0) {
+ v = raw_scsi_get_data(rs);
+ } else if (bank == 0x800 && (addr & 1)) {
+ uae_u8 t = raw_scsi_get_signal_phase(rs);
+ v = 1; // disable switch off
+ if (t & SCSI_IO_BUSY)
+ v |= 128;
+ if (t & SCSI_IO_SEL)
+ v |= 32;
+ if (t & SCSI_IO_REQ)
+ v |= 2;
+ if (t & SCSI_IO_DIRECTION)
+ v |= 8;
+ if (t & SCSI_IO_COMMAND)
+ v |= 16;
+ if (t & SCSI_IO_MESSAGE)
+ v |= 4;
+ v ^= (1 | 2 | 4 | 8 | 16 | 32 | 128);
+ //v |= apolloscsi.irq ? 64 : 0;
}
+ //write_log(_T("apollo scsi get %04x = %02x\n"), addr, v);
+ return v;
}
-uae_u16 raw_scsi_get_data(struct raw_scsi *rs, struct raw_scsi_device *dev)
+int apollo_add_scsi_unit(int ch, struct uaedev_config_info *ci, int devnum)
{
- return rs->data;
+ struct raw_scsi *rs = &apolloscsi[devnum].rscsi;
+ raw_scsi_reset(rs);
+ if (ci->type == UAEDEV_CD)
+ return add_scsi_cd(rs->device, ch, ci->device_emu_unit);
+ else if (ci->type == UAEDEV_TAPE)
+ return add_scsi_tape(rs->device, ch, ci->rootdir, ci->readonly);
+ else
+ return add_scsi_hd(rs->device, ch, NULL, ci, 1);
+ return 0;
}
-void raw_scsi_put_data(struct raw_scsi *rs, struct raw_scsi_device *dev, uae_u16 data)
+void apolloscsi_free(void)
{
+ for (int j = 0; j < 2; j++) {
+ struct raw_scsi *rs = &apolloscsi[j].rscsi;
+ for (int i = 0; i < 8; i++) {
+ free_scsi (rs->device[i]);
+ rs->device[i] = NULL;
+ }
+ }
}
+
+void apolloscsi_reset(void)
+{
+ raw_scsi_reset(&apolloscsi[0].rscsi);
+ raw_scsi_reset(&apolloscsi[1].rscsi);
+}
\ No newline at end of file