#ifdef GFXBOARD
if (currprefs.rtgmem_type >= GFXBOARD_HARDWARE && !gfxboard_is_z3 (currprefs.rtgmem_type)) {
cards[cardno].flags = 4;
- cards[cardno].name = _T("Gfxboard VRAM Zorro II");
- cards[cardno++].initnum = gfxboard_init_memory;
- if (gfxboard_num_boards (currprefs.rtgmem_type) == 3) {
- cards[cardno].flags = 0;
- cards[cardno].name = _T("Gfxboard VRAM Zorro II Extra");
- cards[cardno++].initnum = gfxboard_init_memory_p4_z2;
- }
- if (gfxboard_is_registers (currprefs.rtgmem_type)) {
- cards[cardno].flags = 0;
- cards[cardno].name = _T ("Gfxboard Registers");
- cards[cardno++].initnum = gfxboard_init_registers;
+ if (currprefs.rtgmem_type == GFXBOARD_A2410) {
+ cards[cardno].name = _T("Gfxboard A2410");
+ cards[cardno++].initnum = tms_init;
+ } else {
+ cards[cardno].name = _T("Gfxboard VRAM Zorro II");
+ cards[cardno++].initnum = gfxboard_init_memory;
+ if (gfxboard_num_boards (currprefs.rtgmem_type) == 3) {
+ cards[cardno].flags = 0;
+ cards[cardno].name = _T("Gfxboard VRAM Zorro II Extra");
+ cards[cardno++].initnum = gfxboard_init_memory_p4_z2;
+ }
+ if (gfxboard_is_registers (currprefs.rtgmem_type)) {
+ cards[cardno].flags = 0;
+ cards[cardno].name = _T ("Gfxboard Registers");
+ cards[cardno++].initnum = gfxboard_init_registers;
+ }
}
}
#endif
{
_T("DMAC-01"), _T("dmac01"), 0,
commodore, commodore_a2091_ram, 0, true,
- { 0 },
+ { 0 }
},
{
_T("DMAC-02"), _T("dmac02"), 0,
commodore, commodore_a2091_ram, 0, true,
- { 0 },
+ { 0 }
},
{
NULL
{
_T("Impact A2000-1/X"), _T("a2000-1"), 0,
1761, 8, 0, false,
- { 0 },
+ { 0 }
},
{
_T("Impact A2000-HC"), _T("a2000-hc"), 0,
1761, 8, 0, false,
- { 0 },
+ { 0 }
},
{
_T("Impact A2000-HC+2"), _T("a2000-hc+"), 0,
1761, 8, 0, false,
- { 0 },
+ { 0 }
},
{
NULL
{
_T("MC-302"), _T("mc-302"), 0,
2157, 3, 0, false,
- { 0 },
+ { 0 }
},
{
_T("MC-702"), _T("mc-702"), 0,
2157, 3, 0, false,
- { 0 },
+ { 0 }
},
{
NULL
{
_T("IDE"), _T("ide"), 0,
2144, 2, 0, false,
- { 0 },
+ { 0 }
},
{
_T("IDE+SCSI"), _T("scsi"), 0,
2144, 2, 0, false,
- { 0 },
+ { 0 }
},
{
NULL
};
static const struct expansionsubromtype mediator_sub[] = {
+ {
+ _T("1200"), _T("1200"), ROMTYPE_NOT | ROMTYPE_MEDIATOR
+ },
{
_T("1200TX"), _T("1200tx"), ROMTYPE_NOT | ROMTYPE_MEDIATOR
},
NULL
}
};
-
static void fastlane_memory_callback(struct romconfig *rc, uae_u8 *ac, int size)
{
struct zfile *z = read_device_from_romconfig(rc, NULL);
ac[2] = (ac[2] & 0x0f) | (act[2] & 0xf0);
}
}
-
+static void hda506_memory_callback(struct romconfig *rc, uae_u8 *ac, int size)
+{
+ if (currprefs.cs_a1000ram)
+ ac[1] = 1;
+ else
+ ac[1] = 2;
+}
static void nexus_memory_callback(struct romconfig *rc, uae_u8 *ac, int size)
{
if (rc->device_settings & 1)
false, EXPANSIONTYPE_SASI | EXPANSIONTYPE_SCSI
},
#endif
+ {
+ _T("alf1"), _T("A.L.F."), _T("Elaborate Bytes"),
+ alf1_init, NULL, alf1_add_scsi_unit, ROMTYPE_ALF1 | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG, true,
+ NULL, 0,
+ false, EXPANSIONTYPE_CUSTOM | EXPANSIONTYPE_SCSI
+ },
+ {
+ _T("promigos"), _T("Promigos"), _T("Flesch und Hörnemann"),
+ promigos_init, NULL, promigos_add_scsi_unit, ROMTYPE_PROMIGOS | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG, true,
+ NULL, 0,
+ false, EXPANSIONTYPE_CUSTOM | EXPANSIONTYPE_SCSI
+ },
{
_T("tecmar"), _T("T-Card/T-Disk"), _T("Tecmar"),
- tecmar_init, NULL, tecmar_add_scsi_unit, ROMTYPE_TECMAR | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG, true,
+ tecmar_init, NULL, tecmar_add_scsi_unit, ROMTYPE_TECMAR | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG, true,
NULL, 0,
false, EXPANSIONTYPE_SASI | EXPANSIONTYPE_SCSI
},
+ {
+ _T("system2000"), _T("System 2000"), _T("Vortex"),
+ system2000_init, NULL, system2000_add_scsi_unit, ROMTYPE_SYSTEM2000 | ROMTYPE_NONE, 0, 0, BOARD_NONAUTOCONFIG, true,
+ NULL, 0,
+ false, EXPANSIONTYPE_CUSTOM | EXPANSIONTYPE_SCSI
+ },
{
_T("xebec"), _T("9720H"), _T("Xebec"),
xebec_init, NULL, xebec_add_scsi_unit, ROMTYPE_XEBEC | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG, true,
{ 0xd1, 4, 0x00, 0x00, 0x03, 0xec, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00 },
},
#endif
+ {
+ _T("hda506"), _T("HDA-506"), _T("Spirit Technology"),
+ hda506_init, NULL, hda506_add_scsi_unit, ROMTYPE_HDA506 | ROMTYPE_NOT, 0, 0, BOARD_AUTOCONFIG_Z2, true,
+ NULL, 0,
+ false, EXPANSIONTYPE_CUSTOM | EXPANSIONTYPE_SCSI,
+ 0, 0, 0, false, NULL,
+ false, NULL,
+ { 0xc1, 0x04, 0x00, 0x00, 0x07, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
+ },
{
_T("amax"), _T("AMAX ROM dongle"), _T("ReadySoft"),
NULL, 0, NULL, NULL, NULL, ROMTYPE_AMAX | ROMTYPE_NONE, 0, 0, 0, false
/*
* UAE - The Un*x Amiga Emulator
*
-* SCSI emulation (not uaescsi.device)
+* SCSI and SASI emulation (not uaescsi.device)
*
* Copyright 2007-2015 Toni Wilen
*
#define NCR5380_XEBEC 16
#define NONCR_MICROFORGE 17
#define NONCR_PARADOX 18
-#define NCR_LAST 19
+#define OMTI_HDA506 19
+#define OMTI_ALF1 20
+#define OMTI_PROMIGOS 21
+#define OMTI_SYSTEM2000 22
+#define NCR_LAST 23
extern int log_scsiemu;
static const int outcmd[] = { 0x04, 0x0a, 0x0c, 0x2a, 0xaa, 0x15, 0x55, 0x0f, -1 };
-static const int incmd[] = { 0x01, 0x03, 0x05, 0x08, 0x12, 0x1a, 0x5a, 0x25, 0x28, 0x34, 0x37, 0x42, 0x43, 0xa8, 0x51, 0x52, 0xbd, -1 };
-static const int nonecmd[] = { 0x00, 0x09, 0x0b, 0x11, 0x16, 0x17, 0x19, 0x1b, 0x1e, 0x2b, 0x35, 0xe0, 0xe3, 0xe4, -1 };
-static const int scsicmdsizes[] = { 6, 10, 10, 12, 16, 12, 10, 10 };
+static const int incmd[] = { 0x01, 0x03, 0x08, 0x12, 0x1a, 0x5a, 0x25, 0x28, 0x34, 0x37, 0x42, 0x43, 0xa8, 0x51, 0x52, 0xbd, -1 };
+static const int nonecmd[] = { 0x00, 0x05, 0x09, 0x0b, 0x11, 0x16, 0x17, 0x19, 0x1b, 0x1e, 0x2b, 0x35, 0xe0, 0xe3, 0xe4, -1 };
+static const int scsicmdsizes[] = { 6, 10, 10, 12, 16, 12, 10, 6 };
static void scsi_illegal_command(struct scsi_data *sd)
{
}
break;
case 0x0c: // INITIALIZE DRIVE CHARACTERICS (SASI)
+ if (sd->hfd && sd->hfd->hfd.ci.unit_feature_level < HD_LEVEL_SASI)
+ goto nocmd;
data_len = 8;
break;
case 0x08: // READ(6)
ss->board_size = boardsize;
ss->board_mask = ss->board_size - 1;
}
+ if (!ss->board_mask && !ss->board_size) {
+ ss->board_size = 0x10000;
+ ss->board_mask = 0xffff;
+ }
if (romsize >= 0) {
ss->rom_size = romsize;
xfree(ss->rom);
v |= 1 << 4;
v = v ^ 0xff;
- }
- else {
+ } else {
v = raw_scsi_get_data_2(rs, true, false);
scsi->active_select = false;
raw_scsi_set_signal_phase(rs, false, false, false);
}
- }
- else {
+ } else {
raw_scsi_put_data(rs, v, true);
if (scsi->wait_select && scsi->active_select)
raw_scsi_set_signal_phase(rs, false, true, false);
}
}
+// OMTI 5510
+static void omti_irq(struct soft_scsi *scsi)
+{
+ if (scsi->intena && (scsi->chip_state & 2))
+ ncr5380_set_irq(scsi);
+}
+static void omti_check_state(struct soft_scsi *scsi)
+{
+ struct raw_scsi *rs = &scsi->rscsi;
+ if ((rs->bus_phase == SCSI_SIGNAL_PHASE_DATA_IN || rs->bus_phase == SCSI_SIGNAL_PHASE_DATA_OUT) && (scsi->chip_state & 1)) {
+ omti_irq(scsi);
+ }
+}
+
+static uae_u8 omti_bget(struct soft_scsi *scsi, int reg)
+{
+ struct raw_scsi *rs = &scsi->rscsi;
+ uae_u8 t = raw_scsi_get_signal_phase(rs);
+ uae_u8 v = 0;
+
+ switch (reg)
+ {
+ case 0: // DATA IN
+ if (rs->bus_phase == SCSI_SIGNAL_PHASE_STATUS) {
+ v = raw_scsi_get_data_2(rs, true, false);
+ // get message (not used in OMTI protocol)
+ raw_scsi_get_data_2(rs, true, false);
+ } else {
+ v = raw_scsi_get_data_2(rs, true, false);
+ if (rs->bus_phase == SCSI_SIGNAL_PHASE_STATUS) {
+ omti_irq(scsi); // command complete interrupt
+ }
+ }
+ break;
+ case 1: // STATUS
+ if (rs->bus_phase >= 0)
+ v |= 8; // busy
+ if (v & 8) {
+ if (t & SCSI_IO_REQ)
+ v |= 1; // req
+ if (t & SCSI_IO_DIRECTION)
+ v |= 2;
+ if (t & SCSI_IO_COMMAND)
+ v |= 4;
+ }
+ v |= 0x80 | 0x40;
+ if ((rs->bus_phase == SCSI_SIGNAL_PHASE_DATA_IN || rs->bus_phase == SCSI_SIGNAL_PHASE_DATA_OUT) && (scsi->chip_state & 1))
+ v |= 0x10;
+ if (scsi->irq)
+ v |= 0x20;
+ scsi->irq = false;
+ break;
+ break;
+ case 2: // CONFIGURATION
+ v = 0xff;
+ break;
+ case 3: // -
+ break;
+ }
+ omti_check_state(scsi);
+ return v;
+}
+static void omti_bput(struct soft_scsi *scsi, int reg, uae_u8 v)
+{
+ struct raw_scsi *rs = &scsi->rscsi;
+ switch (reg)
+ {
+ case 0: // DATA OUT
+ raw_scsi_put_data(rs, v, true);
+ if (rs->bus_phase == SCSI_SIGNAL_PHASE_STATUS)
+ omti_irq(scsi); // command complete interrupt
+ break;
+ case 1: // RESET
+ raw_scsi_busfree(rs);
+ scsi->chip_state = 0;
+ break;
+ case 2: // SELECT
+ rs->data_write = 0x01;
+ raw_scsi_set_signal_phase(rs, false, true, false);
+ raw_scsi_set_signal_phase(rs, false, false, false);
+ break;
+ case 3: // MASK
+ scsi->chip_state = v;
+ break;
+ }
+ omti_check_state(scsi);
+}
+
static int suprareg(struct soft_scsi *ncr, uaecptr addr, bool write)
{
int reg = (addr & 0x0f) >> 1;
return -1;
}
+static int hda506_reg(struct soft_scsi *ncr, uaecptr addr, bool write)
+{
+ if ((addr & 0x7fe1) != 0x7fe0)
+ return -1;
+ addr &= 0x7;
+ addr >>= 1;
+ return addr;
+}
+
+static int alf1_reg(struct soft_scsi *ncr, uaecptr addr, bool write)
+{
+ if ((addr & 0x7ff9) != 0x0641)
+ return -1;
+ addr >>= 1;
+ addr &= 3;
+ return addr;
+}
+
+static int system2000_reg(struct soft_scsi *ncr, uaecptr addr, int size, bool write)
+{
+ if (size != 1)
+ return -1;
+ if ((addr & 0xc007) != 0x4000)
+ return -1;
+ addr >>= 3;
+ addr &= 3;
+ return addr;
+}
+
+static int promigos_reg(struct soft_scsi *ncr, uaecptr addr, int size, bool write)
+{
+ if (size != 1)
+ return -1;
+ if ((addr & 0x1) != 1)
+ return -1;
+ addr &= 7;
+ if (addr == 1 && write)
+ return 3;
+ if (addr == 3 && write)
+ return 0;
+ if (addr == 5 && write)
+ return 1;
+ if (addr == 5 && !write)
+ return 0;
+ if (addr == 7 && write)
+ return 2;
+ if (addr == 7 && !write)
+ return 1;
+ return -1;
+}
static int microforge_reg(struct soft_scsi *ncr, uaecptr addr, bool write)
{
if (reg >= 0)
v = sasi_microforge_bget(ncr, reg);
- }
+ } else if (ncr->type == OMTI_HDA506) {
+
+ reg = hda506_reg(ncr, addr, false);
+ if (reg >= 0)
+ v = omti_bget(ncr, reg);
+
+ } else if (ncr->type == OMTI_ALF1) {
+
+ reg = alf1_reg(ncr, addr, false);
+ if (reg >= 0)
+ v = omti_bget(ncr, reg);
+
+ } else if (ncr->type == OMTI_PROMIGOS) {
+
+ reg = promigos_reg(ncr, addr, size, false);
+ if (reg >= 0)
+ v = omti_bget(ncr, reg);
+
+ } else if (ncr->type == OMTI_SYSTEM2000) {
+
+ reg = system2000_reg(ncr, addr, size, false);
+ if (reg >= 0) {
+ v = omti_bget(ncr, reg);
+ } else if (addr < 0x4000) {
+ v = ncr->rom[addr];
+ } else if (ncr->rscsi.bus_phase >= 0) {
+ if ((addr & 0xc000) == 0x8000) {
+ v = ncr->databuffer[addr & 1];
+ ncr->databuffer[addr & 1] = omti_bget(ncr, 0);
+ } else if ((addr & 0xc000) == 0xc000) {
+ v = ncr->databuffer[addr & 1];
+ }
+ }
+ }
#if NCR5380_DEBUG > 1
- //if (addr >= 0x8000)
+ if ((origaddr >= 0xf00000 && size == 1) || (origaddr < 0xf00000))
write_log(_T("GET %08x %02x %d %08x %d\n"), origaddr, v, reg, M68K_GETPC, regs.intmask);
#endif
if (reg >= 0)
sasi_microforge_bput(ncr, reg, val);
+ } else if (ncr->type == OMTI_HDA506) {
+
+ reg = hda506_reg(ncr, addr, true);
+ if (reg >= 0)
+ omti_bput(ncr, reg, val);
+
+ } else if (ncr->type == OMTI_ALF1) {
+
+ reg = alf1_reg(ncr, addr, true);
+ if (reg >= 0)
+ omti_bput(ncr, reg, val);
+
+ } else if (ncr->type == OMTI_PROMIGOS) {
+
+ reg = promigos_reg(ncr, addr, size, true);
+ if (reg >= 0)
+ omti_bput(ncr, reg, val);
+
+ } else if (ncr->type == OMTI_SYSTEM2000) {
+
+ reg = system2000_reg(ncr, addr, size, true);
+ if (reg >= 0) {
+ omti_bput(ncr, reg, val);
+ } else if (ncr->rscsi.bus_phase >= 0) {
+ if ((addr & 0x8000) == 0x8000) {
+ omti_bput(ncr, 0, val);
+ }
+ }
+
}
#if NCR5380_DEBUG > 1
scsi->intena = true;
- struct zfile *z = NULL;
if (!rc->autoboot_disabled) {
load_rom_rc(rc, roms, 32768, 0, scsi->rom, 32768, 0);
memcpy(scsi->acmemory, scsi->rom, sizeof scsi->acmemory);
return scsi->bank;
}
-void cltda1000scsi_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc) {
+void cltda1000scsi_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
+{
generic_soft_scsi_add(ch, ci, rc, NCR5380_CLTD, 65536, 0, ROMTYPE_CLTDSCSI);
}
generic_soft_scsi_add(ch, ci, rc, NONCR_PARADOX, 0, 0, ROMTYPE_PARADOX);
}
+addrbank *hda506_init(struct romconfig *rc)
+{
+ struct soft_scsi *scsi = getscsi(rc);
+
+ if (!scsi)
+ return NULL;
+
+ const struct expansionromtype *ert = get_device_expansion_rom(ROMTYPE_HDA506);
+ for (int i = 0; i < 16; i++) {
+ uae_u8 b = ert->autoconfig[i];
+ ew(scsi, i * 4, b);
+ }
+ scsi->level6 = true;
+ scsi->intena = true;
+ return scsi->bank;
+}
+
+void hda506_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
+{
+ generic_soft_scsi_add(ch, ci, rc, OMTI_HDA506, 0, 0, ROMTYPE_HDA506);
+}
+
+addrbank *alf1_init(struct romconfig *rc)
+{
+ struct soft_scsi *scsi = getscsi(rc);
+
+ if (!scsi)
+ return NULL;
+ map_banks(scsi->bank, 0xef0000 >> 16, 0x10000 >> 16, 0);
+ scsi->board_mask = 0xffff;
+ scsi->baseaddress = 0xef0000;
+ scsi->configured = 1;
+
+ return scsi->bank;
+}
+
+void alf1_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
+{
+ generic_soft_scsi_add(ch, ci, rc, OMTI_ALF1, 65536, 0, ROMTYPE_ALF1);
+}
+
+addrbank *promigos_init(struct romconfig *rc)
+{
+ struct soft_scsi *scsi = getscsi(rc);
+
+ if (!scsi)
+ return NULL;
+ map_banks(scsi->bank, 0xf40000 >> 16, 0x10000 >> 16, 0);
+ scsi->board_mask = 0xffff;
+ scsi->baseaddress = 0xf40000;
+ scsi->configured = 1;
+ scsi->intena = true;
+
+ return scsi->bank;
+}
+
+void promigos_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
+{
+ generic_soft_scsi_add(ch, ci, rc, OMTI_PROMIGOS, 65536, 0, ROMTYPE_PROMIGOS);
+}
+
+addrbank *system2000_init(struct romconfig *rc)
+{
+ struct soft_scsi *scsi = getscsi(rc);
+
+ if (!scsi)
+ return NULL;
+ map_banks(scsi->bank, 0xf00000 >> 16, 0x10000 >> 16, 0);
+ scsi->board_mask = 0xffff;
+ scsi->baseaddress = 0xf00000;
+ scsi->configured = 1;
+ if (!rc->autoboot_disabled) {
+ load_rom_rc(rc, NULL, 16384, 0, scsi->rom, 16384, 0);
+ }
+ return scsi->bank;
+}
+
+void system2000_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
+{
+ generic_soft_scsi_add(ch, ci, rc, OMTI_SYSTEM2000, 65536, 16384, ROMTYPE_SYSTEM2000);
+}
+
+
void soft_scsi_free(void)
{
parallel_port_scsi = false;