/* Autoconfig address space at 0xE80000 */
static uae_u8 expamem[65536];
+static uae_u8 expamem_write_space[65536];
#define AUTOMATIC_AUTOCONFIG_MAX_ADDRESS 0x80
static int expamem_autoconfig_mode;
static addrbank*(*expamem_map)(struct autoconfig_info*);
addrbank expamem_null, expamem_none;
+DECLARE_MEMORY_FUNCTIONS(expamem_write);
+addrbank expamem_write_bank = {
+ expamem_write_lget, expamem_write_wget, expamem_write_bget,
+ expamem_write_lput, expamem_write_wput, expamem_write_bput,
+ default_xlate, default_check, NULL, NULL, _T("Autoconfig Z2 WRITE"),
+ dummy_lgeti, dummy_wgeti,
+ ABFLAG_IO | ABFLAG_SAFE | ABFLAG_PPCIOSPACE, S_READ, S_WRITE
+};
DECLARE_MEMORY_FUNCTIONS(expamem);
addrbank expamem_bank = {
expamem_lget, expamem_wget, expamem_bget,
}
}
+ if (aci->write_bank_address && aci->write_bank_address != 0xffffffff) {
+ map_banks(&expamem_write_bank, aci->write_bank_address >> 16, aci->size >> 16, 0);
+ }
+
if (ab) {
// non-NULL: not using expamem_bank
expamem_bank_current = ab;
}
}
+// only for custom autoconfig device development purposes, not in use in any normal config
+static uae_u32 REGPARAM2 expamem_write_lget(uaecptr addr)
+{
+ addr &= 0xffff;
+ return (expamem_write_space[addr + 0] << 24) | (expamem_write_space[addr + 1] << 16) | (expamem_write_space[addr + 2] << 8) | (expamem_write_space[addr + 3] << 0);
+}
+static uae_u32 REGPARAM2 expamem_write_wget(uaecptr addr)
+{
+ addr &= 0xffff;
+ return (expamem_write_space[addr + 0] << 8) | (expamem_write_space[addr + 1] << 0);
+}
+static uae_u32 REGPARAM2 expamem_write_bget(uaecptr addr)
+{
+ addr &= 0xffff;
+ return expamem_write_space[addr];
+}
+static void REGPARAM2 expamem_write_lput(uaecptr addr, uae_u32 value)
+{
+ addr &= 0xffff;
+ expamem_write_space[addr + 0] = value >> 24;
+ expamem_write_space[addr + 1] = value >> 16;
+ expamem_write_space[addr + 2] = value >> 8;
+ expamem_write_space[addr + 3] = value >> 0;
+}
+static void REGPARAM2 expamem_write_wput(uaecptr addr, uae_u32 value)
+{
+ addr &= 0xffff;
+ expamem_write_space[addr + 0] = value >> 8;
+ expamem_write_space[addr + 1] = value;
+}
+static void REGPARAM2 expamem_write_bput(uaecptr addr, uae_u32 value)
+{
+ addr &= 0xffff;
+ expamem_write_space[addr] = value;
+}
+
static uae_u32 REGPARAM2 expamem_lget (uaecptr addr)
{
if (expamem_bank_current && expamem_bank_current != &expamem_bank) {
type |= Z2_MEM_8MB;
aci->addrbank = bank;
+ aci->write_bank_address = p->fastmem[aci->devnum].write_address;
if (aci->devnum == 0) {
if (ISCPUBOARDP(p, BOARD_COMMODORE, BOARD_COMMODORE_SUB_A26x0)) {
aci->zorro = -1;
}
+ if (expamem_write_space[0] != 0x00 && expamem_write_space[0] != 0xff && aci->write_bank_address) {
+ memcpy(expamem, expamem_write_space, 65536);
+ memcpy(bank->baseaddr, expamem_write_space, 65536);
+ }
+
memcpy(aci->autoconfig_raw, expamem, sizeof aci->autoconfig_raw);
return true;
}
NULL, 0,
true, EXPANSIONTYPE_SCSI | EXPANSIONTYPE_PARALLEL_ADAPTER
},
+ {
+ _T("ateam"), _T("A-Team"), _T("Mainhattan Data"),
+ ateam_init, NULL, ateam_add_ide_unit, ROMTYPE_ATEAM, 0, 0, BOARD_AUTOCONFIG_Z2, false,
+ NULL, 0,
+ true, EXPANSIONTYPE_IDE
+ },
{
_T("mtecat"), _T("AT 500"), _T("M-Tec"),
mtec_init, NULL, mtec_add_ide_unit, ROMTYPE_MTEC, 0, 0, BOARD_AUTOCONFIG_Z2, false,
masoboshi_sub, 0,
true, EXPANSIONTYPE_SCSI | EXPANSIONTYPE_IDE
},
+ {
+ _T("hardframe"), _T("HardFrame"), _T("Microbotics"),
+ hardframe_init, NULL, hardframe_add_scsi_unit, ROMTYPE_HARDFRAME, 0, 0, BOARD_AUTOCONFIG_Z2, false,
+ NULL, 0,
+ true, EXPANSIONTYPE_SCSI,
+ 0, 0, 0, false, NULL,
+ true
+ },
{
_T("stardrive"), _T("StarDrive"), _T("Microbotics"),
stardrive_init, NULL, stardrive_add_scsi_unit, ROMTYPE_STARDRIVE | ROMTYPE_NOT, 0, 0, BOARD_AUTOCONFIG_Z2, true,
static void process_packet_command (struct ide_hdf *ide)
{
setbsy (ide);
- write_comm_pipe_u32 (&ide->its->requests, ide->num | 0x80, 1);
+ write_comm_pipe_u32 (&ide->its->requests, ide->num | 0x100, 1);
}
static void atapi_data_done (struct ide_hdf *ide)
struct ide_hdf *ide;
if (its->state == 0 || unit == 0xfffffff)
break;
- ide = its->idetable[unit & 0x7f];
- if (unit & 0x80)
+ ide = its->idetable[unit & 0xff];
+ if (unit & 0x100)
do_process_packet_command (ide);
else
do_process_rw_command (ide);
#define GOLEMFAST_IDE (x86_AT_IDE + 2 * MAX_DUPLICATE_EXPANSION_BOARDS)
#define BUDDHA_IDE (GOLEMFAST_IDE + 2 * MAX_DUPLICATE_EXPANSION_BOARDS)
#define DATAFLYERPLUS_IDE (BUDDHA_IDE + 3 * MAX_DUPLICATE_EXPANSION_BOARDS)
-#define TOTAL_IDE (DATAFLYERPLUS_IDE + MAX_DUPLICATE_EXPANSION_BOARDS)
+#define ATEAM_IDE (DATAFLYERPLUS_IDE + MAX_DUPLICATE_EXPANSION_BOARDS)
+#define TOTAL_IDE (ATEAM_IDE + MAX_DUPLICATE_EXPANSION_BOARDS)
#define ALF_ROM_OFFSET 0x0100
#define GVP_IDE_ROM_OFFSET 0x8000
static struct ide_board *golemfast_board[MAX_DUPLICATE_EXPANSION_BOARDS];
static struct ide_board *buddha_board[MAX_DUPLICATE_EXPANSION_BOARDS];
static struct ide_board *dataflyerplus_board[MAX_DUPLICATE_EXPANSION_BOARDS];
+static struct ide_board *ateam_board[MAX_DUPLICATE_EXPANSION_BOARDS];
static struct ide_hdf *idecontroller_drive[TOTAL_IDE * 2];
static struct ide_thread_state idecontroller_its;
return reg;
}
+static int get_ateam_reg(uaecptr addr, struct ide_board *board)
+{
+ if (!(addr & 1))
+ return -1;
+ if ((addr & 0xf000) != 0xf000)
+ return -1;
+ addr >>= 7;
+ addr &= 15;
+ if (addr >= 8) {
+ addr &= 7;
+ addr |= IDE_SECONDARY;
+ }
+ return addr;
+}
+
+
static int getidenum(struct ide_board *board, struct ide_board **arr)
{
for (int i = 0; i < MAX_DUPLICATE_EXPANSION_BOARDS; i++) {
v = board->rom[addr & board->rom_mask];
}
+ } else if (board->type == ATEAM_IDE) {
+
+ if (addr == 1) {
+ v = ide_irq_check(board->ide[0], false) ? 0x00 : 0x80;
+ } else {
+ int reg = get_ateam_reg(addr, board);
+ if (reg >= 0) {
+ v = get_ide_reg(board, reg);
+ } else {
+ v = board->rom[addr & board->rom_mask];
+ }
+ }
}
v = get_ide_reg_multi(board, IDE_DATA, (addr & 0x4000) ? 1 : 0, 1);
}
+ } else if (board->type == ATEAM_IDE) {
+
+ if (board->configured && (addr & 0xf800) == 0xf800) {
+ v = get_ide_reg_multi(board, IDE_DATA, 0, 1);
+ }
+
}
}
idescsi_scsi_put(oaddr, v);
}
}
+
+ } else if (board->type == ATEAM_IDE) {
+
+ if ((addr & 0xff01) == 0x0101) {
+ // disable interrupt strobe address
+ board->intena = false;
+ } else if ((addr & 0xff01) == 0x0201) {
+ // enable interrupt strobe address
+ board->intena = true;
+ } else {
+ int reg = get_ateam_reg(addr, board);
+ if (reg >= 0) {
+ put_ide_reg(board, reg, v);
+ }
+ }
+
}
}
put_ide_reg_multi(board, IDE_DATA, v, (addr & 0x4000) ? 1 : 0, 1);
}
+ } else if (board->type == ATEAM_IDE) {
+
+ if (board->configured && (addr & 0xf800) == 0xf800) {
+ put_ide_reg_multi(board, IDE_DATA, v, 0, 1);
+ }
+
}
}
}
}
}
+bool ateam_init(struct autoconfig_info *aci)
+{
+ uae_u8 *rom;
+ int rom_size = 32768;
+
+ rom = xcalloc(uae_u8, rom_size);
+ memset(rom, 0xff, rom_size);
+ load_rom_rc(aci->rc, ROMTYPE_ATEAM, 16384, !aci->rc->autoboot_disabled ? 0xc000 : 0x8000, rom, 32768, LOADROM_EVENONLY_ODDONE | LOADROM_FILL);
+
+ if (!aci->doinit) {
+ memcpy(aci->autoconfig_raw, rom, sizeof aci->autoconfig_raw);
+ xfree(rom);
+ return true;
+ }
+
+ struct ide_board *ide = getide(aci->rc);
+
+ ide->configured = 0;
+ ide->keepautoconfig = false;
+ ide->bank = &ide_bank_generic;
+ ide->mask = 65536 - 1;
+
+ ide->rom = rom;
+ ide->rom_size = rom_size;
+ ide->rom_mask = rom_size - 1;
+ memcpy(ide->acmemory, ide->rom, sizeof ide->acmemory);
+
+ aci->addrbank = ide->bank;
+ return true;
+}
+
+void ateam_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
+{
+ add_ide_standard_unit(ch, ci, rc, ateam_board, ATEAM_IDE, true, false, 2);
+}
+
+
extern void x86_xt_ide_bios(struct zfile*, struct romconfig*);
static bool x86_at_hd_init(struct autoconfig_info *aci, int type)
{
bool dataflyerplus_init(struct autoconfig_info *aci);
void dataflyerplus_add_idescsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
+bool ateam_init(struct autoconfig_info *aci);
+void ateam_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
+
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;
#define ROMTYPE_HYDRA 0x0010005b
#define ROMTYPE_LANROVER 0x0010005c
#define ROMTYPE_ARIADNE 0x0010005d
+#define ROMTYPE_HARDFRAME 0x0010005e
+#define ROMTYPE_ATEAM 0x0010005f
#define ROMTYPE_NOT 0x00800000
#define ROMTYPE_QUAD 0x01000000
bool ossi_init(struct autoconfig_info*);
void ossi_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
+bool hardframe_init(struct autoconfig_info*);
+void hardframe_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc);
+
uae_u8 idescsi_scsi_get(uaecptr addr);
void idescsi_scsi_put(uaecptr addr, uae_u8 v);
return NULL;
}
-#define NEXT_ROM_ID 173
+#define NEXT_ROM_ID 175
#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 },
0xb0814aca, 0xb817672c, 0x1beb86c6, 0x840aa4bd, 0xf4640835, 0x1ed103f4, NULL, NULL },
{ _T("Expansion Systems Dataflyer+ v2.1"), 2, 1, 2, 1, _T("DATAFLYERPLUS\0"), 32768, 169, 0, 0, ROMTYPE_DATAFLYER, 0, 0, NULL,
0xc49daa65, 0x20275716, 0xdc7eb00e, 0x5dc53680, 0xb5c8a90a, 0x7c00e390, NULL, NULL },
+ { _T("Microbotics HardFrame v1.5"), 1, 5, 1, 5, _T("HARDFRAME\0"), 32768, 173, 0, 0, ROMTYPE_HARDFRAME, 0, 0, NULL,
+ 0x8d144212, 0xc5a4f497, 0x5216c1b1, 0xe08760d0, 0x0bd579ef, 0xea226354, NULL, NULL },
+ { _T("Mainhattan Data A-Team v1.8"), 1, 8, 1, 8, _T("ATEAM\0"), 65536, 174, 0, 0, ROMTYPE_ATEAM, 0, 0, NULL,
+ 0x4fe08a5d, 0x007e5c61, 0x4048f598, 0x6d14011d, 0x23a41435, 0x5e0a2259, 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_SCRAM 28
#define NCR5380_OSSI 29
#define NCR5380_DATAFLYERPLUS 30
-#define NCR_LAST 31
+#define NONCR_HARDFRAME 31
+#define NCR_LAST 32
extern int log_scsiemu;
struct soft_scsi
{
- uae_u8 regs[8 + 1];
+ uae_u8 regs[32];
uae_u8 regs_400[2];
int c400_count;
+ uae_u8 aic_reg;
struct raw_scsi rscsi;
bool irq;
bool intena;
case SCSI_SIGNAL_PHASE_MESSAGE_OUT:
sd->msgout[sd->offset++] = data;
len = getmsglen(sd->msgout, sd->offset);
+#if RAW_SCSI_DEBUG
write_log(_T("raw_scsi_put_data got message %02x (%d/%d)\n"), data, sd->offset, len);
+#endif
if (sd->offset >= len) {
+#if RAW_SCSI_DEBUG
write_log(_T("raw_scsi_put_data got message %02x (%d bytes)\n"), sd->msgout[0], len);
+#endif
if ((sd->msgout[0] & (0x80 | 0x20)) == 0x80)
rs->msglun = sd->msgout[0] & 7;
scsi_start_transfer(sd);
}
}
+uae_u8 aic_bget_dma(struct soft_scsi *scsi, bool *phaseerr);
+void aic_bput_dma(struct soft_scsi *scsi, uae_u8 v, bool *phaseerr);
+
+static void hardframe_do_dma(struct soft_scsi *ncr)
+{
+ int len = ncr->dmac_length;
+ for (int i = 0; i < len; i++) {
+ bool phaseerr;
+ if (ncr->dmac_direction < 0) {
+ uae_u8 v = aic_bget_dma(ncr, &phaseerr);
+ if (phaseerr)
+ break;
+ x_put_byte(ncr->dmac_address, v);
+ } else if (ncr->dmac_direction > 0) {
+ uae_u8 v = x_get_byte(ncr->dmac_address);
+ aic_bput_dma(ncr, v, &phaseerr);
+ if (phaseerr)
+ break;
+ }
+ ncr->dmac_length--;
+ ncr->dmac_address++;
+ }
+}
+
static void xebec_do_dma(struct soft_scsi *ncr)
{
struct raw_scsi *rs = &ncr->rscsi;
xebec_do_dma(ncr);
}
+
+ if (ncr->type == NONCR_HARDFRAME) {
+
+ hardframe_do_dma(ncr);
+
+ }
+
ncr->dmac_active = 0;
}
}
+// AIC-6250
+
+static void aic_int(struct soft_scsi *scsi, uae_u8 mask)
+{
+ scsi->regs[16 + 8] |= mask;
+ if ((scsi->regs[16 + 8] & scsi->regs[3]) & 0x1f) {
+ scsi->irq = true;
+ ncr80_rethink();
+ } else {
+ scsi->irq = false;
+ }
+}
+
+static bool aic_phase_match(struct soft_scsi *scsi)
+{
+ struct raw_scsi *r = &scsi->rscsi;
+ uae_u8 phase = r->bus_phase;
+ bool cd = (phase & SCSI_IO_COMMAND) != 0;
+ bool io = (phase & SCSI_IO_DIRECTION) != 0;
+ bool msg = (phase & SCSI_IO_MESSAGE) != 0;
+ if (phase >= 0 &&
+ ((scsi->regs[9] >> 5) & 1) == msg &&
+ ((scsi->regs[9] >> 6) & 1) == io &&
+ ((scsi->regs[9] >> 7) & 1) == cd) {
+ return true;
+ }
+ return false;
+}
+
+static void aic_reg_inc(struct soft_scsi *scsi)
+{
+ if (scsi->aic_reg >= 8)
+ return;
+ scsi->aic_reg++;
+}
+
+static uae_u8 aic_bget_reg(struct soft_scsi *scsi)
+{
+ return scsi->aic_reg & 15;
+}
+
+static uae_u8 aic_bget_dma(struct soft_scsi *scsi, bool *phaseerr)
+{
+ struct raw_scsi *r = &scsi->rscsi;
+ if (!aic_phase_match(scsi)) {
+ *phaseerr = true;
+ return 0;
+ }
+ *phaseerr = false;
+ return raw_scsi_get_data(r, true);
+}
+
+static uae_u8 aic_bget_data(struct soft_scsi *scsi)
+{
+ struct raw_scsi *r = &scsi->rscsi;
+ int reg = scsi->aic_reg;
+ uae_u8 v = scsi->regs[reg];
+
+ aic_reg_inc(scsi);
+
+ switch (reg)
+ {
+ case 0:
+ v = (scsi->dmac_length >> 0) & 0xff;
+ break;
+ case 1:
+ v = (scsi->dmac_length >> 8) & 0xff;
+ break;
+ case 2:
+ v = (scsi->dmac_length >> 16) & 0xff;
+ break;
+ case 6: // REVISION CONTROL
+ v = 2;
+ break;
+ case 7: // STATUS 0
+ {
+ v = scsi->regs[reg + 16] & 2;
+ if (r->bus_phase == SCSI_SIGNAL_PHASE_FREE)
+ v |= 0x10; // BUS FREE
+ if (raw_scsi_get_signal_phase(r) & SCSI_IO_REQ)
+ v |= 0x04; // SCSI REQ ON
+ if (scsi->dmac_length == 0)
+ v |= 0x01; // DMA BYTE COUNT ZERO
+ if ((raw_scsi_get_signal_phase(r) & SCSI_IO_REQ) && !aic_phase_match(scsi))
+ v |= 0x20; // PHASE MISMATCH
+ }
+ break;
+ case 8: // STATUS 1
+ {
+ v = scsi->regs[reg + 16] | 0x40;
+ if (scsi->regs[8] & 2) { // SCSI RESET OUT
+ v |= 0x20; // SCSI RESET IN
+ } else {
+ v &= ~0x20;
+ }
+ scsi->regs[reg + 16] = v;
+ }
+ break;
+ case 9: // SCSI SIGNAL
+ {
+ uae_u8 t = raw_scsi_get_signal_phase(r);
+ v = 0;
+ if (t & SCSI_IO_BUSY)
+ v |= 0x04;
+ if (t & SCSI_IO_ATN)
+ v |= 0x10;
+ if (t & SCSI_IO_SEL)
+ v |= 0x08;
+ if (t & SCSI_IO_REQ)
+ v |= 0x02;
+ if (t & SCSI_IO_DIRECTION)
+ v |= 0x40;
+ if (t & SCSI_IO_COMMAND)
+ v |= 0x80;
+ if (t & SCSI_IO_MESSAGE)
+ v |= 0x20;
+ if (r->ack)
+ v |= 0x01;
+ }
+ break;
+ case 10: // SCSI ID DATA
+ v = scsi->regs[16 + 10];
+ break;
+ case 13:
+ {
+ // SCSI ID (4 to 7 only)
+ int vv = scsi->rc->device_id - 4;
+ if (vv < 0)
+ vv = 0;
+ vv ^= 3;
+ vv = (vv >> 1) | (vv << 1);
+ v = (vv & 3) << 5;
+ }
+ break;
+ }
+ return v;
+}
+
+static void aic_bput_reg(struct soft_scsi *scsi, uae_u8 v)
+{
+ scsi->aic_reg = v & 15;
+}
+
+static void aic_bput_dma(struct soft_scsi *scsi, uae_u8 v, bool *phaseerr)
+{
+ struct raw_scsi *r = &scsi->rscsi;
+ if (!aic_phase_match(scsi)) {
+ *phaseerr = true;
+ return;
+ }
+ *phaseerr = false;
+ raw_scsi_put_data(r, v, true);
+}
+
+static void aic_bput_data(struct soft_scsi *scsi, uae_u8 v)
+{
+ struct raw_scsi *r = &scsi->rscsi;
+ int reg = scsi->aic_reg;
+
+ aic_reg_inc(scsi);
+
+ switch (reg)
+ {
+ case 0:
+ scsi->dmac_length &= 0xffff00;
+ scsi->dmac_length |= v << 0;
+ break;
+ case 1:
+ scsi->dmac_length &= 0xff00ff;
+ scsi->dmac_length |= v << 8;
+ break;
+ case 2:
+ scsi->dmac_length &= 0x00ffff;
+ scsi->dmac_length |= v << 16;
+ break;
+ case 3: // INT MSK
+ // cleared interrupt mask clears request
+ scsi->regs[16 + 8] &= v | ~0x1f;
+ if (v & 0x40) { // ARB/SEL START
+ raw_scsi_put_data(r, scsi->regs[10], false);
+ raw_scsi_set_signal_phase(r, false, true, (v & 0x20) != 0);
+ raw_scsi_set_signal_phase(r, true, false, false);
+ aic_int(scsi, 0x08); // COMMAND DONE
+ scsi->regs[11] = scsi->regs[10]; // SOURCE AND DESTINATION ID = DATA
+ v &= ~0x40;
+ }
+ aic_int(scsi, 0);
+ break;
+ case 5:
+ if (v & 1) { // DMA XFER EN
+ scsi->dma_direction = (v & 2) ? 1 : -1;
+ dma_check(scsi);
+ aic_int(scsi, 0x08); // COMMAND DONE
+ }
+ break;
+ case 8: // CONTROL
+ if (v & 2) { // SCSI RESET OUT
+ raw_scsi_reset(r);
+ }
+ if (v & 0x80) { // AUTO SCSI PIO REQ
+ if (aic_phase_match(scsi)) {
+ int phase = r->bus_phase;
+ bool io = (phase & SCSI_IO_DIRECTION) != 0;
+ scsi->regs[16 + 7] &= ~0x02;
+ if (!io) {
+ raw_scsi_put_data(r, scsi->regs[10], true);
+ } else {
+ scsi->regs[16 + 10] = raw_scsi_get_data(r, true);
+ }
+ aic_int(scsi, 0x08); // COMMAND DONE
+ if (phase != r->bus_phase)
+ scsi->regs[16 + 7] |= 0x02; // SCSI PHASE CHG/ATN
+ v &= ~0x80;
+ } else {
+ aic_int(scsi, 0x10); // ERROR
+ }
+ }
+ break;
+ case 9: // SCSI SIGNAL
+
+ break;
+ }
+ scsi->regs[reg] = v;
+}
+
// NCR 53C80/MISC SCSI-LIKE
void x86_doirq(uint8_t irqnum);
return (addr >> 1) & 7;
}
-static uae_u8 read_supra_dma(struct soft_scsi *ncr, uaecptr addr)
+static uae_u8 read_684xx_dma(struct soft_scsi *ncr, uaecptr addr)
{
uae_u8 val = 0;
- addr &= 0x1f;
+ addr &= 0x3f;
switch (addr)
{
case 0:
val = 0;
break;
}
-
- write_log(_T("SUPRA DMA GET %08x %02x %08x\n"), addr, val, M68K_GETPC);
+#if NCR5380_DEBUG > 0
+ write_log(_T("684xx DMA GET %08x %02x %08x\n"), addr, val, M68K_GETPC);
+#endif
return val;
}
-static void write_supra_dma(struct soft_scsi *ncr, uaecptr addr, uae_u8 val)
+static void write_684xx_dma(struct soft_scsi *ncr, uaecptr addr, uae_u8 val)
{
- write_log(_T("SUPRA DMA PUT %08x %02x %08x\n"), addr, val, M68K_GETPC);
+#if NCR5380_DEBUG > 0
+ write_log(_T("684xx DMA PUT %08x %02x %08x\n"), addr, val, M68K_GETPC);
+#endif
- addr &= 0x1f;
+ addr &= 0x3f;
switch (addr)
{
case 5: // OCR
addr &= ncr->board_mask;
- if (ncr->type == NCR5380_SUPRA) {
+ if (ncr->type == NONCR_HARDFRAME) {
+
+ if (addr == 0xc0) {
+ v = aic_bget_reg(ncr);
+ } else if (addr == 0xc2) {
+ v = aic_bget_data(ncr);
+ } else if (addr == 0x40) {
+ v = ncr->irq ? 0x80 : 0x00;
+ } else if (addr == 0x42) {
+ v = ncr->intena ? 0x10 : 0x00;
+ } else if (addr >= 0x80 && addr <= 0x9f) {
+ v = read_684xx_dma(ncr, addr & 31);
+ } else {
+ v = ncr->rom[addr];
+ }
+
+ } else if (ncr->type == NCR5380_SUPRA) {
if (ncr->subtype == 4) {
if ((addr & 0xc000) == 0xc000) {
- v = read_supra_dma(ncr, addr);
+ v = read_684xx_dma(ncr, addr);
} else if (addr & 0x8000) {
addresstype = (addr & 1) ? 0 : 1;
}
}
#if NCR5380_DEBUG > 1
- if (1 || origaddr >= 0x8000)
+ if (origaddr < 0x100)
write_log(_T("GET %08x %02x %d %08x %d\n"), origaddr, v, reg, M68K_GETPC, regs.intmask);
#endif
addr &= ncr->board_mask;
- if (ncr->type == NCR5380_SUPRA) {
+ if (ncr->type == NONCR_HARDFRAME) {
+
+ if (addr == 0xc0) {
+ aic_bput_reg(ncr, val);
+ } else if (addr == 0xc2) {
+ aic_bput_data(ncr, val);
+ } else if (addr == 0x42) {
+ ncr->intena = (val & 0x10) != 0;
+ } else if (addr >= 0x80 && addr <= 0x9f) {
+ write_684xx_dma(ncr, addr & 31, val);
+ }
+
+ } else if (ncr->type == NCR5380_SUPRA) {
if (ncr->subtype == 4) {
if ((addr & 0xc000) == 0xc000) {
- write_supra_dma(ncr, addr, val);
+ write_684xx_dma(ncr, addr, val);
} else if (addr & 0x8000) {
addresstype = (addr & 1) ? 0 : 1;
}
{
generic_soft_scsi_add(ch, ci, rc, NCR5380_DATAFLYERPLUS, 65536, -1, ROMTYPE_DATAFLYER);
}
+
+bool hardframe_init(struct autoconfig_info *aci)
+{
+ if (!aci->doinit) {
+ load_rom_rc(aci->rc, ROMTYPE_HARDFRAME, 32768, aci->rc->autoboot_disabled ? 64 : 0, aci->autoconfig_raw, 128, LOADROM_EVENONLY_ODDONE);
+ return true;
+ }
+
+ struct soft_scsi *scsi = getscsi(aci->rc);
+ if (!scsi)
+ return false;
+
+ load_rom_rc(aci->rc, ROMTYPE_HARDFRAME, 32768, 0, scsi->rom, 65536, LOADROM_EVENONLY_ODDONE);
+ if (aci->rc->autoboot_disabled)
+ memcpy(scsi->rom, scsi->rom + 128, 128);
+ memcpy(scsi->acmemory, scsi->rom, sizeof scsi->acmemory);
+ aci->addrbank = scsi->bank;
+ return true;
+}
+
+void hardframe_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc)
+{
+ generic_soft_scsi_add(ch, ci, rc, NONCR_HARDFRAME, 65536, 65536, ROMTYPE_HARDFRAME);
+}