From e24ea0f24152875fafc220784abcb43cfc2a0089 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sun, 13 Jan 2019 22:17:35 +0200 Subject: [PATCH] Trumpcard and Trumpcard 500AT emulation. Trumpcard *.driver file ROM image extraction. --- expansion.cpp | 18 +++++++ idecontrollers.cpp | 102 +++++++++++++++++++++++++++++++++++++-- include/idecontrollers.h | 3 ++ include/rommgr.h | 2 + include/scsi.h | 3 ++ rommgr.cpp | 49 +++++++++++++++++++ scsi.cpp | 51 ++++++++++++++++---- 7 files changed, 214 insertions(+), 14 deletions(-) diff --git a/expansion.cpp b/expansion.cpp index 5793a518..c1259fa2 100644 --- a/expansion.cpp +++ b/expansion.cpp @@ -5046,6 +5046,15 @@ const struct expansionromtype expansionroms[] = { false, 4, buddha_settings, { 0xd1, 0x00, 0x00, 0x00, 0x12, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00 }, }, + { + _T("trumpcard"), _T("Trumpcard"), _T("IVS"), + NULL, trumpcard_init, NULL, trumpcard_add_scsi_unit, ROMTYPE_IVSTC, 0, 0, BOARD_AUTOCONFIG_Z2, false, + NULL, 0, + true, EXPANSIONTYPE_SCSI, + 2112, 4, 0, false, NULL, + true, 0, NULL, + { 0xd1, 0x30, 0x00, 0x00, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00 }, + }, { _T("trumpcardpro"), _T("Grand Slam"), _T("IVS"), NULL, trumpcardpro_init, NULL, trumpcardpro_add_scsi_unit, ROMTYPE_IVSTPRO, 0, 0, BOARD_AUTOCONFIG_Z2, false, @@ -5055,6 +5064,15 @@ const struct expansionromtype expansionroms[] = { true, 0, NULL, { 0xd1, 0x34, 0x00, 0x00, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00 }, }, + { + _T("trumpcardat"), _T("Trumpcard 500AT"), _T("IVS"), + NULL, trumpcard500at_init, NULL, trumpcard500at_add_ide_unit, ROMTYPE_IVST500AT, 0, 0, BOARD_AUTOCONFIG_Z2, false, + NULL, 0, + true, EXPANSIONTYPE_IDE, + 2112, 4, 0, false, NULL, + true, 0, NULL, + { 0xd1, 0x31, 0x00, 0x00, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00 }, + }, { _T("kommos"), _T("Kommos A500/A2000 SCSI"), _T("Jürgen Kommos"), NULL, kommos_init, NULL, kommos_add_scsi_unit, ROMTYPE_KOMMOS, 0, 0, BOARD_NONAUTOCONFIG_BEFORE, true, diff --git a/idecontrollers.cpp b/idecontrollers.cpp index aa699e39..60f0a5d4 100644 --- a/idecontrollers.cpp +++ b/idecontrollers.cpp @@ -52,7 +52,8 @@ #define FASTATA4K_IDE (ATEAM_IDE + MAX_DUPLICATE_EXPANSION_BOARDS) #define ELSATHD_IDE (FASTATA4K_IDE + 2 * MAX_DUPLICATE_EXPANSION_BOARDS) #define ACCESSX_IDE (ELSATHD_IDE + MAX_DUPLICATE_EXPANSION_BOARDS) -#define TOTAL_IDE (ACCESSX_IDE + 2 * MAX_DUPLICATE_EXPANSION_BOARDS) +#define IVST500AT_IDE (ACCESSX_IDE + 2 * MAX_DUPLICATE_EXPANSION_BOARDS) +#define TOTAL_IDE (IVST500AT_IDE + MAX_DUPLICATE_EXPANSION_BOARDS) #define ALF_ROM_OFFSET 0x0100 #define GVP_IDE_ROM_OFFSET 0x8000 @@ -110,6 +111,7 @@ static struct ide_board *arriba_board[MAX_DUPLICATE_EXPANSION_BOARDS]; static struct ide_board *fastata4k_board[MAX_DUPLICATE_EXPANSION_BOARDS]; static struct ide_board *elsathd_board[MAX_DUPLICATE_EXPANSION_BOARDS]; static struct ide_board *accessx_board[MAX_DUPLICATE_EXPANSION_BOARDS]; +static struct ide_board *ivst500at_board[MAX_DUPLICATE_EXPANSION_BOARDS]; static struct ide_hdf *idecontroller_drive[TOTAL_IDE * 2]; static struct ide_thread_state idecontroller_its; @@ -574,6 +576,19 @@ static int get_accessx_reg(uaecptr addr, struct ide_board *board, int *portnum) return reg; } +static int get_ivst500at_reg(uaecptr addr, struct ide_board *board, int *portnum) +{ + *portnum = 0; + if (addr & 0x8000) + return -1; + if (!(addr & 1)) + return -1; + int reg = (addr >> 2) & 7; + if (addr & 0x2000) + reg |= IDE_SECONDARY; + return reg; +} + static int getidenum(struct ide_board *board, struct ide_board **arr) { for (int i = 0; i < MAX_DUPLICATE_EXPANSION_BOARDS; i++) { @@ -591,7 +606,7 @@ static uae_u32 ide_read_byte(struct ide_board *board, uaecptr addr) addr &= board->mask; #if DEBUG_IDE - if (0 || (addr & 0x8000)) + if (0 || !(addr & 0x8000)) write_log(_T("IDE IO BYTE READ %08x %08x\n"), addr, M68K_GETPC); #endif @@ -891,6 +906,18 @@ static uae_u32 ide_read_byte(struct ide_board *board, uaecptr addr) v = board->rom[offset]; } + } else if (board->type == IVST500AT_IDE) { + + int portnum; + int reg = get_ivst500at_reg(addr, board, &portnum); + if (reg >= 0) { + if (board->ide[portnum]) + v = get_ide_reg_multi(board, reg, portnum, 1); + } else if (board->rom && (addr & 0x8000)) { + int offset = addr & 0x7fff; + v = board->rom[offset]; + } + } return v; @@ -1144,12 +1171,26 @@ static uae_u32 ide_read_word(struct ide_board *board, uaecptr addr) v <<= 8; v |= board->rom[(offset + 1) & board->rom_mask]; } + + } else if (board->type == IVST500AT_IDE) { + + int portnum; + int reg = get_ivst500at_reg(addr, board, &portnum); + if (reg == 0 || addr == 0 || addr == 2) { + v = get_ide_reg_multi(board, IDE_DATA, portnum, 1); + } else if (board->rom && (addr & 0x8000)) { + int offset = addr & 0x7fff; + v = board->rom[(offset + 0) & board->rom_mask]; + v <<= 8; + v |= board->rom[(offset + 1) & board->rom_mask]; + } + } } #if DEBUG_IDE - if (0 || (addr & 0x8000)) + if (0 || !(addr & 0x8000)) write_log(_T("IDE IO WORD READ %08x %04x %08x\n"), addr, v, M68K_GETPC); #endif @@ -1162,7 +1203,7 @@ static void ide_write_byte(struct ide_board *board, uaecptr addr, uae_u8 v) addr &= board->mask; #if DEBUG_IDE - if (0 || (addr & 0x8000)) + if (0 || !(addr & 0x8000)) write_log(_T("IDE IO BYTE WRITE %08x=%02x %08x\n"), addr, v, M68K_GETPC); #endif @@ -1408,6 +1449,14 @@ static void ide_write_byte(struct ide_board *board, uaecptr addr, uae_u8 v) put_ide_reg_multi(board, reg, v, portnum, 1); } + } else if (board->type == IVST500AT_IDE) { + + int portnum; + int reg = get_ivst500at_reg(addr, board, &portnum); + if (board->ide[portnum]) { + put_ide_reg_multi(board, reg, v, portnum, 1); + } + } } @@ -1418,7 +1467,7 @@ static void ide_write_word(struct ide_board *board, uaecptr addr, uae_u16 v) addr &= board->mask; #if DEBUG_IDE - if (0 || (addr & 0x8000)) + if (0 || !(addr & 0x8000)) write_log(_T("IDE IO WORD WRITE %08x=%04x %08x\n"), addr, v, M68K_GETPC); #endif @@ -1584,6 +1633,14 @@ static void ide_write_word(struct ide_board *board, uaecptr addr, uae_u16 v) if (!reg) { put_ide_reg_multi(board, IDE_DATA, v, portnum, 1); } + + } else if (board->type == IVST500AT_IDE) { + + int portnum; + int reg = get_ivst500at_reg(addr, board, &portnum); + if (!reg || addr == 0 || addr == 2) { + put_ide_reg_multi(board, IDE_DATA, v, portnum, 1); + } } } } @@ -2475,6 +2532,41 @@ void accessx_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfi add_ide_standard_unit(ch, ci, rc, accessx_board, ACCESSX_IDE, false, false, 4); } +bool trumpcard500at_init(struct autoconfig_info *aci) +{ + const struct expansionromtype *ert = get_device_expansion_rom(ROMTYPE_IVST500AT); + if (!aci->doinit) { + aci->autoconfigp = ert->autoconfig; + return true; + } + + struct ide_board *ide = getide(aci); + + ide->bank = &ide_bank_generic; + ide->mask = 65536 - 1; + ide->rom_size = 32768; + ide->rom_mask = 32768 - 1; + ide->keepautoconfig = false; + + ide->rom = xcalloc(uae_u8, 32768); + load_rom_rc(aci->rc, ROMTYPE_IVST500AT, 16384, 0, ide->rom, 32768, LOADROM_EVENONLY_ODDONE); + + for (int i = 0; i < 16; i++) { + uae_u8 b = ert->autoconfig[i]; + if (i == 0 && aci->rc->autoboot_disabled) + b &= ~0x10; + ew(ide, i * 4, b); + } + + aci->addrbank = ide->bank; + return true; +} + +void trumpcard500at_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc) +{ + add_ide_standard_unit(ch, ci, rc, ivst500at_board, IVST500AT_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 d80726f7..6313e5e1 100644 --- a/include/idecontrollers.h +++ b/include/idecontrollers.h @@ -57,6 +57,9 @@ void elsathd_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfi bool accessx_init(struct autoconfig_info *aci); void accessx_add_ide_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc); +bool trumpcard500at_init(struct autoconfig_info *aci); +void trumpcard500at_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 c7ddb6e8..17a2dbb9 100644 --- a/include/rommgr.h +++ b/include/rommgr.h @@ -181,6 +181,8 @@ extern int decode_cloanto_rom_do (uae_u8 *mem, int size, int real_size); #define ROMTYPE_X86MOUSE 0x00100076 #define ROMTYPE_ACCESSX 0x00100077 #define ROMTYPE_OVERDRIVE 0x00100078 +#define ROMTYPE_IVSTC 0x00100079 +#define ROMTYPE_IVST500AT 0x0010007a #define ROMTYPE_NOT 0x00800000 #define ROMTYPE_QUAD 0x01000000 diff --git a/include/scsi.h b/include/scsi.h index 75029c70..9e346911 100644 --- a/include/scsi.h +++ b/include/scsi.h @@ -259,6 +259,9 @@ void omtiadapter_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconf bool phoenixboard_init(struct autoconfig_info *aci); void phoenixboard_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc); +bool trumpcard_init(struct autoconfig_info*); +void trumpcard_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc); + bool trumpcardpro_init(struct autoconfig_info*); void trumpcardpro_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc); diff --git a/rommgr.cpp b/rommgr.cpp index 4c136eca..60f67f53 100644 --- a/rommgr.cpp +++ b/rommgr.cpp @@ -2381,6 +2381,51 @@ struct boardromconfig *get_boardromconfig(struct uae_prefs *p, int romtype, int return NULL; } +static struct zfile *parse_trumpcard_driver(struct zfile *z) +{ + int size; + uae_u8 *d = zfile_getdata(z, 0x24, -1, &size); + if (!d) + return z; + struct zfile *zd = zfile_fopen_empty(NULL, zfile_getname(z), 16384); + int i, out; + out = 0; + for (i = 0; i < size - 4; i++) { + if (d[i] == 0x4e && d[i + 1] == 0x71 && d[i + 2] == 0x4e && d[i + 3] == 0x71) + break; + uae_u8 v; + v = (d[i] & 0xf0) | 0x0f; + zfile_fwrite(&v, 1, 1, zd); + v = (d[i] << 4) | 0x0f; + zfile_fwrite(&v, 1, 1, zd); + out += 2; + } + int datastart = i; + for (; i < size - 4; i += 2) { + if (d[i] == 0x66 && d[i + 1] == 0x66 && d[i + 2] == 0x99 && d[i + 3] == 0x99) { + zfile_fwrite(&d[datastart], i - datastart + 4, 1, zd); + out += i - datastart + 4; + break; + } + } + uae_u8 zero = 0; + while (out & 15) { + zfile_fwrite(&zero, 1, 1, zd); + out++; + } + for (i = 0; i < 16; i++) { + zfile_fwrite(&zero, 1, 1, zd); + out++; + } + zero = 0xff; + while (out < 16384) { + zfile_fwrite(&zero, 1, 1, zd); + out++; + } + xfree(d); + return zd; +} + bool load_rom_rc(struct romconfig *rc, uae_u32 romtype, int maxfilesize, int fileoffset, uae_u8 *rom, int maxromsize, int flags) { if (flags & LOADROM_ONEFILL) @@ -2390,6 +2435,10 @@ bool load_rom_rc(struct romconfig *rc, uae_u32 romtype, int maxfilesize, int fil struct zfile *f = read_device_from_romconfig(rc, romtype); if (!f) return false; + TCHAR *ext = _tcsrchr(zfile_getname(f), '.'); + if ((romtype == ROMTYPE_IVSTPRO || romtype == ROMTYPE_IVSTC || romtype == ROMTYPE_IVST500AT) && ext && !_tcsicmp(ext, _T(".driver"))) { + f = parse_trumpcard_driver(f); + } zfile_fseek(f, fileoffset, SEEK_SET); int cnt = 0; int pos = 0; diff --git a/scsi.cpp b/scsi.cpp index 033a306e..6a75d1f6 100644 --- a/scsi.cpp +++ b/scsi.cpp @@ -75,7 +75,8 @@ #define NCR5380_FASTTRAK 40 #define NCR5380_12GAUGE 41 #define NCR5380_OVERDRIVE 42 -#define NCR_LAST 43 +#define NCR5380_TRUMPCARD 43 +#define NCR_LAST 44 extern int log_scsiemu; @@ -839,6 +840,7 @@ struct soft_scsi bool dma_started; bool dma_controller; bool dma_drq; + bool dma_autodack; struct romconfig *rc; struct soft_scsi **self_ptr; @@ -1915,7 +1917,10 @@ uae_u8 ncr5380_bget(struct soft_scsi *scsi, int reg) } if (scsi->dma_drq || (scsi->dma_active && !scsi->dma_controller && r->bus_phase == (scsi->regs[3] & 7))) { scsi->dma_drq = true; - v |= 1 << 6; + if (scsi->dma_autodack && r->bus_phase != (scsi->regs[3] & 7)) + scsi->dma_drq = false; + if (scsi->dma_drq) + v |= 1 << 6; } if (scsi->regs[2] & 4) { // monitor busy @@ -3392,7 +3397,7 @@ static uae_u32 ncr80_bget2(struct soft_scsi *ncr, uaecptr addr, int size) v = ncr5380_bget(ncr, reg); } - } else if (ncr->type == NCR5380_TRUMPCARDPRO || ncr->type == NCR5380_IVSVECTOR) { + } else if (ncr->type == NCR5380_TRUMPCARDPRO || ncr->type == NCR5380_IVSVECTOR || ncr->type == NCR5380_TRUMPCARD) { reg = trumpcardpro_reg(ncr, addr, ncr->type == NCR5380_IVSVECTOR); if (reg >= 0) { @@ -3401,7 +3406,7 @@ static uae_u32 ncr80_bget2(struct soft_scsi *ncr, uaecptr addr, int size) } else { v = ncr5380_bget(ncr, reg); } - } else if ((addr & 0x8000) && ncr->type == NCR5380_TRUMPCARDPRO) { + } else if ((addr & 0x8000) && ncr->type != NCR5380_IVSVECTOR) { if (!ncr->rc->autoboot_disabled) v = ncr->rom[addr & 0x7fff]; } else if (addr == 0x100 && ncr->type == NCR5380_IVSVECTOR) { @@ -3418,15 +3423,14 @@ static uae_u32 ncr80_bget2(struct soft_scsi *ncr, uaecptr addr, int size) v ^= 0xff & ~0x40; } else if (addr > 0x100 && ncr->type == NCR5380_IVSVECTOR) { v = ncr->rom[addr]; - } else if ((addr & 0xe0) == 0xc0) { + } else if ((addr & 0xe0) == 0xc0 && ncr->type != NCR5380_TRUMPCARD) { struct raw_scsi *rs = &ncr->rscsi; uae_u8 t = raw_scsi_get_signal_phase(rs); v = ncr->irq && ncr->intena ? 4 : 0; // actually this is buffer empty/full v |= (t & SCSI_IO_DIRECTION) ? 2 : 0; v |= ((ncr->rc->device_id ^ 7) & 7) << 3; - - } else if ((addr & 0xe0) == 0xa0) { + } else if ((addr & 0xe0) == 0xa0 && ncr->type != NCR5380_TRUMPCARD) { // long data port if (ncr->dma_active) v = ncr5380_bget(ncr, 8); @@ -3827,7 +3831,7 @@ static void ncr80_bput2(struct soft_scsi *ncr, uaecptr addr, uae_u32 val, int si if (reg >= 0) ncr5380_bput(ncr, reg, val); - } else if (ncr->type == NCR5380_TRUMPCARDPRO || ncr->type == NCR5380_IVSVECTOR) { + } else if (ncr->type == NCR5380_TRUMPCARDPRO || ncr->type == NCR5380_IVSVECTOR || ncr->type == NCR5380_TRUMPCARD) { reg = trumpcardpro_reg(ncr, addr, ncr->type == NCR5380_IVSVECTOR); if (reg >= 0) { @@ -3849,7 +3853,7 @@ static void ncr80_bput2(struct soft_scsi *ncr, uaecptr addr, uae_u32 val, int si cpu_fallback(1); } } - } else if ((addr & 0xe0) == 0xa0) { + } else if ((addr & 0xe0) == 0xa0 && ncr->type != NCR5380_TRUMPCARD) { // word data port if (ncr->dma_active) ncr5380_bput(ncr, 8, val); @@ -4419,6 +4423,35 @@ void trumpcardpro_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct ro generic_soft_scsi_add(ch, ci, rc, NCR5380_TRUMPCARDPRO, 65536, 32768, NCR5380_TRUMPCARDPRO); } +bool trumpcard_init(struct autoconfig_info *aci) +{ + const struct expansionromtype *ert = get_device_expansion_rom(ROMTYPE_IVSTC); + aci->autoconfigp = ert->autoconfig; + if (!aci->doinit) + return true; + + struct soft_scsi *scsi = getscsi(aci->rc); + if (!scsi) + return false; + + scsi->intena = true; + scsi->dma_autodack = true; + + load_rom_rc(aci->rc, ROMTYPE_IVSTC, 16384, 0, scsi->rom, 32768, 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 trumpcard_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc) +{ + generic_soft_scsi_add(ch, ci, rc, NCR5380_TRUMPCARD, 65536, 32768, NCR5380_TRUMPCARD); +} + bool rochard_scsi_init(struct romconfig *rc, uaecptr baseaddress) { struct soft_scsi *scsi = getscsi(rc); -- 2.47.3