From: Toni Wilen Date: Sun, 13 Nov 2016 13:13:47 +0000 (+0200) Subject: HardFrame and A-Team HD controllers. X-Git-Tag: 3400~27 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=87952ad981183dd9c05a9dda9dd30bde3ae46407;p=francis%2Fwinuae.git HardFrame and A-Team HD controllers. --- diff --git a/expansion.cpp b/expansion.cpp index 94a4354f..ba86c427 100644 --- a/expansion.cpp +++ b/expansion.cpp @@ -245,6 +245,7 @@ static bool ks11orolder(void) /* 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*); @@ -331,6 +332,14 @@ static void addextrachip (uae_u32 sysbase) 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, @@ -509,6 +518,10 @@ static void call_card_init(int index) } } + 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; @@ -601,6 +614,42 @@ void expamem_next(addrbank *mapped, addrbank *next) } } +// 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) { @@ -1621,6 +1670,7 @@ static bool expamem_init_fastcard_2(struct autoconfig_info *aci, int zorro) 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)) { @@ -1639,6 +1689,11 @@ static bool expamem_init_fastcard_2(struct autoconfig_info *aci, int zorro) 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; } @@ -4525,6 +4580,12 @@ const struct expansionromtype expansionroms[] = { 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, @@ -4537,6 +4598,14 @@ const struct expansionromtype expansionroms[] = { 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, diff --git a/ide.cpp b/ide.cpp index f4e11411..f51693f1 100644 --- a/ide.cpp +++ b/ide.cpp @@ -619,7 +619,7 @@ static void process_rw_command (struct ide_hdf *ide) 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) @@ -1297,8 +1297,8 @@ static void *ide_thread (void *idedata) 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); diff --git a/idecontrollers.cpp b/idecontrollers.cpp index 3922c192..57cc23f6 100644 --- a/idecontrollers.cpp +++ b/idecontrollers.cpp @@ -46,7 +46,8 @@ #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 @@ -99,6 +100,7 @@ static struct ide_board *x86_at_ide_board[MAX_DUPLICATE_EXPANSION_BOARDS]; 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; @@ -489,6 +491,22 @@ static int get_golemfast_reg(uaecptr addr, struct ide_board *board) 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++) { @@ -738,6 +756,18 @@ static uae_u32 ide_read_byte(struct ide_board *board, uaecptr addr) 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]; + } + } } @@ -928,6 +958,12 @@ static uae_u32 ide_read_word(struct ide_board *board, uaecptr addr) 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); + } + } } @@ -1104,6 +1140,22 @@ static void ide_write_byte(struct ide_board *board, uaecptr addr, uae_u8 v) 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); + } + } + } } @@ -1241,6 +1293,12 @@ static void ide_write_word(struct ide_board *board, uaecptr addr, uae_u16 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); + } + } } } @@ -1918,6 +1976,43 @@ void dataflyerplus_add_idescsi_unit(int ch, struct uaedev_config_info *ci, struc } } +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) { diff --git a/include/idecontrollers.h b/include/idecontrollers.h index 38d5e222..a0ada852 100644 --- a/include/idecontrollers.h +++ b/include/idecontrollers.h @@ -42,6 +42,9 @@ void buddha_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig 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; diff --git a/include/rommgr.h b/include/rommgr.h index 68625360..5fa4af7b 100644 --- a/include/rommgr.h +++ b/include/rommgr.h @@ -144,6 +144,8 @@ extern int decode_cloanto_rom_do (uae_u8 *mem, int size, int real_size); #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 diff --git a/include/scsi.h b/include/scsi.h index 37052973..0636614b 100644 --- a/include/scsi.h +++ b/include/scsi.h @@ -258,6 +258,9 @@ void scram5380_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romco 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); diff --git a/rommgr.cpp b/rommgr.cpp index e710e99d..67854fe1 100644 --- a/rommgr.cpp +++ b/rommgr.cpp @@ -95,7 +95,7 @@ struct romdata *getromdatabypath (const TCHAR *path) 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 }, @@ -475,6 +475,10 @@ static struct romdata roms[] = { 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") }, diff --git a/scsi.cpp b/scsi.cpp index 8c089400..b6f917f2 100644 --- a/scsi.cpp +++ b/scsi.cpp @@ -59,7 +59,8 @@ #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; @@ -731,9 +732,10 @@ struct raw_scsi 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; @@ -1220,9 +1222,13 @@ static void raw_scsi_write_data(struct raw_scsi *rs, uae_u8 data) 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); @@ -1356,6 +1362,30 @@ static void supra_do_dma(struct soft_scsi *ncr) } } +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; @@ -1387,10 +1417,242 @@ static void dma_check(struct soft_scsi *ncr) 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); @@ -2171,11 +2433,11 @@ static int dataflyerplus_reg(uaecptr addr) 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: @@ -2185,16 +2447,19 @@ static uae_u8 read_supra_dma(struct soft_scsi *ncr, uaecptr addr) 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 @@ -2312,11 +2577,27 @@ static uae_u32 ncr80_bget2(struct soft_scsi *ncr, uaecptr addr, int size) 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; } @@ -2747,7 +3028,7 @@ static uae_u32 ncr80_bget2(struct soft_scsi *ncr, uaecptr addr, int size) } #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 @@ -2762,11 +3043,23 @@ static void ncr80_bput2(struct soft_scsi *ncr, uaecptr addr, uae_u32 val, int si 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; } @@ -4143,3 +4436,27 @@ void dataflyerplus_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct r { 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); +}