NULL, 0,
true, EXPANSIONTYPE_IDE
},
+ {
+ _T("synthesis"), _T("Synthesis"), _T("Hardital"),
+ NULL, synthesis_init, NULL, synthesis_add_scsi_unit, ROMTYPE_SYNTHESIS, 0, 0, BOARD_AUTOCONFIG_Z2, false,
+ NULL, 0,
+ true, EXPANSIONTYPE_SCSI
+ },
{
_T("vector"), _T("Vector Falcon 8000"), _T("HK-Computer"),
NULL, vector_init, NULL, vector_add_scsi_unit, ROMTYPE_VECTOR, 0, 0, BOARD_AUTOCONFIG_Z2, false,
false, EXPANSIONTYPE_SCSI,
18260, 8, 0, true
},
+ {
+ _T("mastfb"), _T("Fireball"), _T("M.A.S.T."),
+ NULL, fireball_init, NULL, fireball_add_scsi_unit, ROMTYPE_MASTFB, 0, 0, BOARD_AUTOCONFIG_Z2, false,
+ NULL, 0,
+ true, EXPANSIONTYPE_SCSI,
+ 0, 0, 0, false, NULL,
+ false, 0, NULL,
+ { 0xd1, 8, 0x40, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00 }
+ },
{
_T("scram8490"), _T("SCRAM (DP8490V)"), _T("MegaMicro"),
NULL, scram5380_init, NULL, scram5380_add_scsi_unit, ROMTYPE_SCRAM5380, 0, 0, BOARD_AUTOCONFIG_Z2, false,
return NULL;
}
-#define NEXT_ROM_ID 265
+#define NEXT_ROM_ID 267
#define ALTROM(id,grp,num,size,flags,crc32,a,b,c,d,e) \
{ _T("X"), 0, 0, 0, 0, 0, size, id, 0, 0, flags, (grp << 16) | num, 0, NULL, crc32, a, b, c, d, e },
0xee803484, 0x62822cb9,0x0b095efa,0x455496ea,0xd5b22740,0x77d86375, NULL, NULL },
{ _T("A.L.F. 2"), 0, 0, 0, 0, _T("ALF2\0"), 65536, 264, 0, 0, ROMTYPE_ALF2, 0, 0, NULL,
0x9cf8a7b7, 0x3df4667c,0xd3436367,0x7896da65,0x94994769,0x13bc6746, NULL, NULL },
+ { _T("M.A.S.T. Fireball"), 0, 0, 0, 0, _T("MASTFB\0"), 8192, 265, 0, 0, ROMTYPE_MASTFB, 0, 0, NULL,
+ 0xb475ff5f, 0x63609553,0x98b06812,0x23ade9ac,0x6ee31364,0x5375fce3, NULL, NULL },
+ { _T("Hardital Synthesis"), 0, 0, 0, 0, _T("SYNTHESIS\0"), 32768, 266, 0, 0, ROMTYPE_SYNTHESIS, 0, 0, NULL,
+ 0x667c7616, 0x0eb1cb38,0x3133f070,0x7cb57944,0xc516f236,0xbad4d4f6, NULL, NULL },
{ _T("CyberStorm MK I 68040"), 0, 0, 0, 0, _T("CSMKI\0"), 32768, 95, 0, 0, ROMTYPE_CB_CSMK1, 0, 0, NULL,
0, 0, 0, 0, 0, 0, NULL, _T("cyberstormmk1_040.rom") },
#define NCR5380_OVERDRIVE 42
#define NCR5380_TRUMPCARD 43
#define OMTI_ALF2 44
-#define NCR_LAST 45
+#define NCR5380_SYNTHESIS 45 // clone of ICD AdSCSI
+#define NCR5380_FIREBALL 46
+#define NCR_LAST 47
extern int log_scsiemu;
uae_u8 scratch_400[64];
int c400_count;
bool c400;
+ bool dp8490v;
uae_u8 aic_reg;
struct raw_scsi rscsi;
bool irq;
}
}
+static void fireball_do_dma(struct soft_scsi* ncr)
+{
+ struct raw_scsi* rs = &ncr->rscsi;
+ while (rs->bus_phase == SCSI_SIGNAL_PHASE_DATA_OUT || rs->bus_phase == SCSI_SIGNAL_PHASE_DATA_IN) {
+ if (rs->bus_phase == SCSI_SIGNAL_PHASE_DATA_IN) {
+ dma_put_byte(ncr->dmac_address & ncr->dma_mask, ncr5380_bget(ncr, 8));
+ ncr->dmac_address++;
+ } else if (rs->bus_phase == SCSI_SIGNAL_PHASE_DATA_OUT) {
+ ncr5380_bput(ncr, 8, dma_get_byte(ncr->dmac_address & ncr->dma_mask));
+ ncr->dmac_address++;
+ }
+ }
+}
+
static void dma_check(struct soft_scsi *ncr)
{
}
+ if (ncr->type == NCR5380_FIREBALL) {
+
+ fireball_do_dma(ncr);
+
+ }
+
ncr->dmac_active = 0;
}
}
{
for (int i = 0; soft_scsi_devices[i]; i++) {
struct soft_scsi *s = soft_scsi_devices[i];
- if (s->irq && s->intena && ((s->c400 && (s->regs_400[0] & 0x10) && !s->c400_count) || !s->c400)) {
+ if (s->irq && s->intena && (
+ (s->c400 && (s->regs_400[0] & 0x10) && !s->c400_count) ||
+ (s->dp8490v && (s->regs[18] & 0x20)) ||
+ (!s->c400 && !s->dp8490v)))
+ {
if (soft_scsi_devices[i] == x86_hd_data) {
;// x86_doirq(5);
} else {
{
struct raw_scsi *r = &scsi->rscsi;
- memset(scsi->regs, 0, sizeof scsi->regs);
+ if (scsi->dp8490v) {
+ // DP8490V manual says all registers are reset but that can't work
+ // with Fireball driver. It assumes IMR is not reset.
+ memset(scsi->regs, 0, 16);
+ } else {
+ memset(scsi->regs, 0, sizeof scsi->regs);
+ }
if (busreset) {
raw_scsi_reset_bus(scsi);
scsi->regs[1] = 0x80;
{
if (reg > 8)
return 0;
+
+ if (scsi->dp8490v) {
+ if ((scsi->regs[1] & 0x40) && reg == 7) {
+ reg = 17;
+ }
+ }
+
+
uae_u8 v = scsi->regs[reg];
struct raw_scsi *r = &scsi->rscsi;
switch(reg)
case 7:
scsi->irq = false;
break;
+
+ case 17: // DP8490V MODE_E
+ {
+ int efr = (scsi->regs[17] >> 1) & 3;
+ if (efr == 3) {
+ v = 0;
+ uae_u8 t = raw_scsi_get_signal_phase(r);
+ // End of DMA -> DMA Phase Mismatch
+ if (scsi->regs[5] & 0x80) {
+ v = 0x10;
+ }
+ // Any Phase Mismatch
+ if (r->bus_phase == (scsi->regs[3] & 7)) {
+ v |= 0x20;
+ }
+ } else {
+ scsi->regs[17] &= ~(3 << 1);
+ }
+ }
+ break;
+
case 8: // fake dma port
v = raw_scsi_get_data(r, true);
ncr5380_check_phase(scsi);
{
if (reg > 8)
return;
+
+ if (scsi->dp8490v) {
+ if ((scsi->regs[1] & 0x40) && reg == 7) {
+ reg = 17;
+ }
+ }
+
bool dataoutput = (scsi->regs[1] & 1) != 0;
struct raw_scsi *r = &scsi->rscsi;
uae_u8 old = scsi->regs[reg];
if (v & 0x80) { // RST
ncr5380_reset(scsi, true);
}
+ if (scsi->dp8490v) {
+ scsi->regs[reg] &= ~0x40;
+ scsi->regs[reg] |= v & 0x40;
+ }
}
break;
case 2:
scsi->dma_active = true;
scsi->dma_started = true;
dma_check(scsi);
+#if NCR5380_DEBUG
+ write_log(_T("DMA initiator recv PC=%08x\n"), M68K_GETPC);
+#endif
}
+ break;
+
+ case 17: // DP8490V MODE_E
+ {
+ int efr = (old >> 1) & 3;
+ if (efr == 3) {
+ scsi->regs[18] = v;
+ scsi->regs[17] &= ~(3 << 1);
+ } else {
+ int efr = (v >> 1) & 3;
+ if (efr == 1) {
+ scsi->irq = false;
+ } else if (efr == 2) {
+ if (scsi->regs[2] & 2) {
+ // start DMA initiator receive
+ scsi->dma_direction = -1;
+ scsi->dma_active = true;
+ scsi->dma_started = true;
+ dma_check(scsi);
#if NCR5380_DEBUG
- write_log(_T("DMA initiator recv PC=%08x\n"), M68K_GETPC);
+ write_log(_T("DMA8490 initiator recv PC=%08x\n"), M68K_GETPC);
#endif
+ }
+ }
+ }
+ }
break;
+
+
case 8: // fake dma port
if (r->bus_phase == (scsi->regs[3] & 7)) {
raw_scsi_put_data(r, v, true);
return -1;
}
+static int fireball_reg(struct soft_scsi* ncr, uaecptr addr)
+{
+ if ((addr & 0xc000) != 0x4000)
+ return -1;
+ return (addr >> 1) & 7;
+}
+
static uae_u8 read_684xx_dma(struct soft_scsi *ncr, uaecptr addr)
{
uae_u8 val = 0;
v = ncr->rom[addr];
}
- } else if (ncr->type == NCR5380_ADSCSI) {
+ } else if (ncr->type == NCR5380_ADSCSI || ncr->type == NCR5380_SYNTHESIS) {
+
struct raw_scsi *rs = &ncr->rscsi;
if (ncr->configured)
v = ncr->rom[addr & 0x3fff];
}
+ } else if (ncr->type == NCR5380_FIREBALL) {
+
+ reg = fireball_reg(ncr, addr);
+ if (reg >= 0) {
+ v = ncr5380_bget(ncr, reg);
+ } else if ((addr & 0xc000) == 0xc000) {
+ v = ncr->rom[addr & 0x3fff];
+ } else if (addr < 128) {
+ v = ncr->acmemory[addr];
+ }
+
}
#if NCR5380_DEBUG > 1
- if (0 || origaddr < 0x8000)
+ if (0 || (origaddr & 0xffff) <= 0x8100)
write_log(_T("GET %08x %02x %d %08x %d\n"), origaddr, v, reg, M68K_GETPC, regs.intmask);
#endif
}
}
- } else if (ncr->type == NCR5380_ADSCSI) {
+ } else if (ncr->type == NCR5380_ADSCSI || ncr->type == NCR5380_SYNTHESIS) {
if (ncr->configured)
reg = adscsi_reg(ncr, addr, true);
else
ncr5380_bput(ncr, reg, val);
}
+
+ } else if (ncr->type == NCR5380_FIREBALL) {
+
+ if ((addr & 0xc000) == 0x8000) {
+ // this is strange way to set up DMA address..
+ if (val & 0x40) {
+ ncr->dmac_address = 0x00777777;
+ ncr->dmac_length = 1;
+ ncr->dmac_active = 1;
+ }
+ if (!(val & 0xc0) && val && ncr->dmac_length > 0 && ncr->dmac_length <= 8) {
+ // nybbles, value 0 to 7
+ for (int i = 0; i < 6; i++) {
+ int shift = i * 4;
+ int bm = 1 << i;
+ if (!(val & bm)) {
+ uae_u8 n = (ncr->dmac_length - 1) & 0x0f;
+ uae_u8 v = (ncr->dmac_address >> shift) & 0x0f;
+ if (v > n)
+ v = n;
+ ncr->dmac_address &= ~(0x0f << shift);
+ ncr->dmac_address |= (v & 0x0f) << shift;
+ }
+ }
+ ncr->dmac_length++;
+ }
+ if (ncr->dmac_length > 8 && !(val & 0xc0) && val) {
+ // nybbles, value 8 to 15..
+ for (int i = 0; i < 6; i++) {
+ int bm = 1 << i;
+ if (val & bm) {
+ int shift = i * 4;
+ uae_u8 v = (ncr->dmac_address >> shift) & 0x0f;
+ v++;
+ ncr->dmac_address &= ~(0x0f << shift);
+ ncr->dmac_address |= (v & 0x0f) << shift;
+ }
+ }
+ }
+ ncr->dmac_direction = (val & 0x80) != 0;
+ } else {
+ reg = fireball_reg(ncr, addr);
+ if (reg >= 0) {
+ ncr5380_bput(ncr, reg, val);
+ }
+ }
+
}
#if NCR5380_DEBUG > 1
- if (origaddr < 0x8000)
+ if ((origaddr & 0xffff) <= 0x8100)
write_log(_T("PUT %08x %02x %d %08x %d\n"), origaddr, val, reg, M68K_GETPC, regs.intmask);
#endif
}
generic_soft_scsi_add(ch, ci, rc, NCR5380_ADSCSI, 65536, 65536, ROMTYPE_ADSCSI);
}
+bool synthesis_init(struct autoconfig_info* aci)
+{
+ scsi_add_reset();
+ if (!aci->doinit) {
+ load_rom_rc(aci->rc, ROMTYPE_SYNTHESIS, 32768, 0, aci->autoconfig_raw, 128, LOADROM_EVENONLY_ODDONE | LOADROM_FILL);
+ return true;
+ }
+
+ struct soft_scsi* scsi = getscsi(aci->rc);
+ if (!scsi)
+ return false;
+
+ load_rom_rc(aci->rc, ROMTYPE_SYNTHESIS, 32768, 0, scsi->rom, 65536, LOADROM_EVENONLY_ODDONE | LOADROM_FILL);
+ memcpy(scsi->acmemory, scsi->rom, sizeof scsi->acmemory);
+ aci->addrbank = scsi->bank;
+}
+
+void synthesis_add_scsi_unit(int ch, struct uaedev_config_info* ci, struct romconfig* rc)
+{
+ generic_soft_scsi_add(ch, ci, rc, NCR5380_SYNTHESIS, 65536, 65536, ROMTYPE_SYNTHESIS);
+}
+
+bool fireball_init(struct autoconfig_info* aci)
+{
+ const struct expansionromtype* ert = get_device_expansion_rom(ROMTYPE_MASTFB);
+ scsi_add_reset();
+ aci->autoconfigp = ert->autoconfig;
+ if (!aci->doinit)
+ return true;
+
+ struct soft_scsi* scsi = getscsi(aci->rc);
+ if (!scsi)
+ return false;
+
+ scsi->dp8490v = true;
+ scsi->intena = true;
+ scsi->dma_controller = true;
+
+ load_rom_rc(aci->rc, ROMTYPE_MASTFB, 8192, 0, scsi->rom, 16384, LOADROM_EVENONLY_ODDONE | LOADROM_FILL);
+
+ for (int i = 0; i < 16; i++) {
+ uae_u8 b = ert->autoconfig[i];
+ ew(scsi, i * 4, b);
+ }
+ aci->addrbank = scsi->bank;
+ return true;
+}
+
+void fireball_add_scsi_unit(int ch, struct uaedev_config_info* ci, struct romconfig* rc)
+{
+ generic_soft_scsi_add(ch, ci, rc, NCR5380_FIREBALL, 65536, 16384, ROMTYPE_MASTFB);
+}
+
+
bool trumpcardpro_init(struct autoconfig_info *aci)
{
const struct expansionromtype *ert = get_device_expansion_rom(ROMTYPE_IVSTPRO);
void trumpcardpro_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
{
- generic_soft_scsi_add(ch, ci, rc, NCR5380_TRUMPCARDPRO, 65536, 32768, NCR5380_TRUMPCARDPRO);
+ generic_soft_scsi_add(ch, ci, rc, NCR5380_TRUMPCARDPRO, 65536, 32768, ROMTYPE_IVSTPRO);
}
bool trumpcard_init(struct autoconfig_info *aci)