From 8d6d822c67670440ace687dc4560ad2c809a203f Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Mon, 13 Aug 2018 21:00:03 +0300 Subject: [PATCH] CSA 12 Gauge emulation. --- cpuboard.cpp | 57 +++++++++++++++++++++++++++++++++++++ expansion.cpp | 11 +++++++ gencpu.cpp | 42 ++++++++++++++++----------- include/cpuboard.h | 1 + include/newcpu.h | 10 +++++++ include/rommgr.h | 1 + include/scsi.h | 3 ++ newcpu.cpp | 39 +++++++++++++++++++++++++ rommgr.cpp | 2 ++ scsi.cpp | 71 +++++++++++++++++++++++++++++++++++++++++++++- 10 files changed, 219 insertions(+), 18 deletions(-) diff --git a/cpuboard.cpp b/cpuboard.cpp index 49cfc974..4b8019b3 100644 --- a/cpuboard.cpp +++ b/cpuboard.cpp @@ -38,6 +38,7 @@ // ROM expansion board diagrom call // 00F83B7C 3.1 A4000 +// 00F83B7C 3.0 A1200 // 00F83C96 3.1 A1200 // 00FC4E28 1.3 @@ -335,6 +336,10 @@ static bool is_ivsvector(struct uae_prefs *p) { return ISCPUBOARDP(p, BOARD_IVS, BOARD_IVS_SUB_VECTOR); } +static bool is_12gauge(struct uae_prefs *p) +{ + return ISCPUBOARDP(p, BOARD_CSA, BOARD_CSA_SUB_12GAUGE); +} static bool is_magnum40(struct uae_prefs *p) { return ISCPUBOARDP(p, BOARD_CSA, BOARD_CSA_SUB_MAGNUM40); @@ -1549,6 +1554,10 @@ void cpuboard_map(void) if (is_magnum40(&currprefs)) { map_banks(&blizzardio_bank, 0x0c0c0000 >> 16, 0x10000 >> 16, 0); } + if (is_12gauge(&currprefs)) { + map_banks(&cpuboardmem1_bank, cpuboardmem1_bank.start >> 16, 0x01000000 >> 16, (cpuboard_size / 2) >> 16); + map_banks(&cpuboardmem2_bank, cpuboardmem2_bank.start >> 16, 0x01000000 >> 16, (cpuboard_size / 2) >> 16); + } if (is_blizzard1230mk2(&currprefs) || is_blizzard1230mk3(&currprefs)) { map_banks(&blizzardram_bank, blizzardram_bank.start >> 16, cpuboard_size >> 16, 0); @@ -2041,8 +2050,26 @@ static void cpuboard_init_2(void) cpuboardmem2_bank.mask = cpuboard_size - 1; mapped_malloc(&cpuboardmem2_bank); + } else if (is_12gauge(&currprefs)) { + + cpuboardmem1_bank.start = 0x08000000; + cpuboardmem1_bank.reserved_size = cpuboard_size / 2; + cpuboardmem1_bank.mask = cpuboardmem1_bank.reserved_size - 1; + + cpuboardmem2_bank.start = 0x09000000; + cpuboardmem2_bank.reserved_size = cpuboard_size / 2; + cpuboardmem2_bank.mask = cpuboardmem2_bank.reserved_size - 1; + + if (cpuboard_size) { + cpuboardmem1_bank.label = _T("*"); + mapped_malloc(&cpuboardmem1_bank); + cpuboardmem2_bank.label = _T("*"); + mapped_malloc(&cpuboardmem2_bank); + } + } + if (!cpuboardmem1_bank.baseaddr) cpuboardmem1_bank.reserved_size = 0; if (!cpuboardmem2_bank.baseaddr) @@ -2239,6 +2266,33 @@ bool cpuboard_io_special(int addr, uae_u32 *val, int size, bool write) return false; } +bool cpuboard_fc_check(uaecptr addr, uae_u32 *v, int size, bool write) +{ + if (!currprefs.cpuboard_type) + return false; + + if (is_12gauge(&currprefs)) { + if ((addr == 0xc0000 || addr == 0xc0001) && size == 0) { + uae_u8 val = 0; + if (!write) { + if (addr == 0xc0000) + val = 0x00; + if (addr == 0xc0001) + val = 0x40; // bit 6 set = scsi driver at base+$c000 (0 = $8000000) + *v = val; + } + if (write) + write_log(_T("12GAUGE W %08x = %02x\n"), addr, (*v) & 0xff); + else + write_log(_T("12GAUGE R %08x = %02x\n"), addr, (*v) & 0xff); + return true; + } + return false; + } + + return false; +} + static void fixserial(struct uae_prefs *p, uae_u8 *rom, int size) { uae_u8 value1 = rom[16]; @@ -2415,6 +2469,9 @@ bool cpuboard_autoconfig_init(struct autoconfig_info *aci) case BOARD_CSA: switch(p->cpuboard_subtype) { + case BOARD_CSA_SUB_12GAUGE: + aci->addrbank = &expamem_null; + return true; case BOARD_CSA_SUB_MAGNUM40: aci->addrbank = &expamem_null; return true; diff --git a/expansion.cpp b/expansion.cpp index 520acb1e..26d29e3e 100644 --- a/expansion.cpp +++ b/expansion.cpp @@ -6009,6 +6009,17 @@ static const struct cpuboardsubtype csa_sub[] = { ncr710_magnum40_autoconfig_init, NULL, BOARD_AUTOCONFIG_Z2, 1, magnum40_settings, NULL }, + { + _T("Twelve Gauge"), + _T("twelvegauge"), + ROMTYPE_CB_12GAUGE, 0, + twelvegauge_add_scsi_unit, EXPANSIONTYPE_SCSI, + BOARD_MEMORY_CUSTOM_32, + 32 * 1024 * 1024, + 0, + twelvegauge_init, NULL, BOARD_AUTOCONFIG_Z2, 1, + NULL, NULL + }, { NULL } diff --git a/gencpu.cpp b/gencpu.cpp index 46db1563..e7811e3b 100644 --- a/gencpu.cpp +++ b/gencpu.cpp @@ -1656,6 +1656,9 @@ static void genamode2x (amodes mode, const char *reg, wordsizes size, const char irc2ir (true); if (getv == 1) { + const char *srcbx = !(flags & GF_FC) ? srcb : "sfc_nommu_get_byte"; + const char *srcwx = !(flags & GF_FC) ? srcw : "sfc_nommu_get_word"; + const char *srclx = !(flags & GF_FC) ? srcl : "sfc_nommu_get_long"; start_brace (); if (using_mmu) { if (flags & GF_FC) { @@ -1675,21 +1678,21 @@ static void genamode2x (amodes mode, const char *reg, wordsizes size, const char } } else if (using_ce020 || using_prefetch_020) { switch (size) { - case sz_byte: insn_n_cycles += 4; printf ("\tuae_s8 %s = %s (%sa);\n", name, srcb, name); count_read++; break; - case sz_word: insn_n_cycles += 4; printf ("\tuae_s16 %s = %s (%sa);\n", name, srcw, name); count_read++; break; - case sz_long: insn_n_cycles += 8; printf ("\tuae_s32 %s = %s (%sa);\n", name, srcl, name); count_read += 2; break; + case sz_byte: insn_n_cycles += 4; printf ("\tuae_s8 %s = %s (%sa);\n", name, srcbx, name); count_read++; break; + case sz_word: insn_n_cycles += 4; printf ("\tuae_s16 %s = %s (%sa);\n", name, srcwx, name); count_read++; break; + case sz_long: insn_n_cycles += 8; printf ("\tuae_s32 %s = %s (%sa);\n", name, srclx, name); count_read += 2; break; default: term (); } } else if (using_ce || using_prefetch) { switch (size) { - case sz_byte: insn_n_cycles += 4; printf ("\tuae_s8 %s = %s (%sa);\n", name, srcb, name); count_read++; break; - case sz_word: insn_n_cycles += 4; printf ("\tuae_s16 %s = %s (%sa);\n", name, srcw, name); count_read++; break; + case sz_byte: insn_n_cycles += 4; printf ("\tuae_s8 %s = %s (%sa);\n", name, srcbx, name); count_read++; break; + case sz_word: insn_n_cycles += 4; printf ("\tuae_s16 %s = %s (%sa);\n", name, srcwx, name); count_read++; break; case sz_long: { insn_n_cycles += 8; if ((flags & GF_REVERSE) && mode == Apdi) - printf("\tuae_s32 %s = %s (%sa + 2); %s |= %s (%sa) << 16;\n", name, srcw, name, name, srcw, name); + printf("\tuae_s32 %s = %s (%sa + 2); %s |= %s (%sa) << 16;\n", name, srcwx, name, name, srcw, name); else - printf("\tuae_s32 %s = %s (%sa) << 16; %s |= %s (%sa + 2);\n", name, srcw, name, name, srcw, name); + printf("\tuae_s32 %s = %s (%sa) << 16; %s |= %s (%sa + 2);\n", name, srcwx, name, name, srcw, name); count_read += 2; break; } @@ -1697,9 +1700,9 @@ static void genamode2x (amodes mode, const char *reg, wordsizes size, const char } } else { switch (size) { - case sz_byte: insn_n_cycles += 4; printf ("\tuae_s8 %s = %s (%sa);\n", name, srcb, name); count_read++; break; - case sz_word: insn_n_cycles += 4; printf ("\tuae_s16 %s = %s (%sa);\n", name, srcw, name); count_read++; break; - case sz_long: insn_n_cycles += 8; printf ("\tuae_s32 %s = %s (%sa);\n", name, srcl, name); count_read += 2; break; + case sz_byte: insn_n_cycles += 4; printf ("\tuae_s8 %s = %s (%sa);\n", name, srcbx, name); count_read++; break; + case sz_word: insn_n_cycles += 4; printf ("\tuae_s16 %s = %s (%sa);\n", name, srcwx, name); count_read++; break; + case sz_long: insn_n_cycles += 8; printf ("\tuae_s32 %s = %s (%sa);\n", name, srclx, name); count_read += 2; break; default: term (); } } @@ -1870,6 +1873,10 @@ static void genastore_2 (const char *from, amodes mode, const char *reg, wordsiz case absl: case PC16: case PC8r: + { + const char *dstbx = !(flags & GF_FC) ? dstb : "dfc_nommu_put_byte"; + const char *dstwx = !(flags & GF_FC) ? dstw : "dfc_nommu_put_word"; + const char *dstlx = !(flags & GF_FC) ? dstl : "dfc_nommu_put_long"; if (!(flags & GF_NOFAULTPC)) gen_set_fault_pc (); if (using_mmu) { @@ -1905,19 +1912,19 @@ static void genastore_2 (const char *from, amodes mode, const char *reg, wordsiz } else if (using_ce020 || using_prefetch_020) { switch (size) { case sz_byte: - printf ("\t%s (%sa, %s);\n", dstb, to, from); + printf ("\t%s (%sa, %s);\n", dstbx, to, from); count_write++; break; case sz_word: if (cpu_level < 2 && (mode == PC16 || mode == PC8r)) term (); - printf ("\t%s (%sa, %s);\n", dstw, to, from); + printf ("\t%s (%sa, %s);\n", dstwx, to, from); count_write++; break; case sz_long: if (cpu_level < 2 && (mode == PC16 || mode == PC8r)) term (); - printf ("\t%s (%sa, %s);\n", dstl, to, from); + printf ("\t%s (%sa, %s);\n", dstlx, to, from); count_write += 2; break; default: @@ -1958,14 +1965,14 @@ static void genastore_2 (const char *from, amodes mode, const char *reg, wordsiz switch (size) { case sz_byte: insn_n_cycles += 4; - printf ("\t%s (%sa, %s);\n", dstb, to, from); + printf ("\t%s (%sa, %s);\n", dstbx, to, from); count_write++; break; case sz_word: insn_n_cycles += 4; if (cpu_level < 2 && (mode == PC16 || mode == PC8r)) term (); - printf ("\t%s (%sa, %s);\n", dstw, to, from); + printf ("\t%s (%sa, %s);\n", dstwx, to, from); count_write++; break; case sz_long: @@ -1973,9 +1980,9 @@ static void genastore_2 (const char *from, amodes mode, const char *reg, wordsiz if (cpu_level < 2 && (mode == PC16 || mode == PC8r)) term (); if (store_dir) - printf ("\t%s (%sa + 2, %s); %s (%sa, %s >> 16);\n", dstw, to, from, dstw, to, from); + printf ("\t%s (%sa + 2, %s); %s (%sa, %s >> 16);\n", dstwx, to, from, dstwx, to, from); else - printf ("\t%s (%sa, %s >> 16); %s (%sa + 2, %s);\n", dstw, to, from, dstw, to, from); + printf ("\t%s (%sa, %s >> 16); %s (%sa + 2, %s);\n", dstwx, to, from, dstwx, to, from); count_write += 2; break; default: @@ -2007,6 +2014,7 @@ static void genastore_2 (const char *from, amodes mode, const char *reg, wordsiz } } break; + } case imm: case imm0: case imm1: diff --git a/include/cpuboard.h b/include/cpuboard.h index 061d126e..8ce44f41 100644 --- a/include/cpuboard.h +++ b/include/cpuboard.h @@ -105,6 +105,7 @@ void blizzardppc_irq_setonly(int id, int level); #define BOARD_CSA 14 #define BOARD_CSA_SUB_MAGNUM40 0 +#define BOARD_CSA_SUB_12GAUGE 1 #define BOARD_HARDITAL 15 #define BOARD_HARDITAL_SUB_TQM 0 diff --git a/include/newcpu.h b/include/newcpu.h index 0ef777c7..7cdb4cf8 100644 --- a/include/newcpu.h +++ b/include/newcpu.h @@ -615,6 +615,13 @@ extern uae_u32 next_ilong_cache040(void); extern uae_u32 get_word_icache040(uaecptr addr); extern uae_u32 get_long_icache040(uaecptr addr); +extern uae_u32 sfc_nommu_get_byte(uaecptr); +extern uae_u32 sfc_nommu_get_word(uaecptr); +extern uae_u32 sfc_nommu_get_long(uaecptr); +extern void dfc_nommu_put_byte(uaecptr, uae_u32); +extern void dfc_nommu_put_word(uaecptr, uae_u32); +extern void dfc_nommu_put_long(uaecptr, uae_u32); + extern void (*x_do_cycles)(unsigned long); extern void (*x_do_cycles_pre)(unsigned long); extern void (*x_do_cycles_post)(unsigned long, uae_u32); @@ -795,4 +802,7 @@ void cpu_semaphore_release(void); bool execute_other_cpu(int until); void execute_other_cpu_single(void); +uae_u32 process_cpu_indirect_memory_read(uae_u32 addr, int size); +void process_cpu_indirect_memory_write(uae_u32 addr, uae_u32 data, int size); + #endif /* UAE_NEWCPU_H */ diff --git a/include/rommgr.h b/include/rommgr.h index 60782a6c..6c988b96 100644 --- a/include/rommgr.h +++ b/include/rommgr.h @@ -49,6 +49,7 @@ extern int decode_cloanto_rom_do (uae_u8 *mem, int size, int real_size); #define ROMTYPE_CB_A1230S2 0x0004001c #define ROMTYPE_CB_TYPHOON2 0x0004001d #define ROMTYPE_CB_QUIKPAK 0x0004001e +#define ROMTYPE_CB_12GAUGE 0x0004001f #define ROMTYPE_FREEZER 0x00080000 #define ROMTYPE_AR 0x00080001 diff --git a/include/scsi.h b/include/scsi.h index fc21b082..8e47c90e 100644 --- a/include/scsi.h +++ b/include/scsi.h @@ -176,6 +176,9 @@ uae_u8 ivsvector_scsi_bget(uaecptr addr); void ivsvector_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc); bool ivsvector_init(struct autoconfig_info *aci); +void twelvegauge_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc); +bool twelvegauge_init(struct autoconfig_info *aci); + void soft_scsi_free(void); void soft_scsi_reset(void); diff --git a/newcpu.cpp b/newcpu.cpp index 6176bf73..c35e9143 100644 --- a/newcpu.cpp +++ b/newcpu.cpp @@ -10916,3 +10916,42 @@ void fill_prefetch (void) regs.irc = x_get_word (pc + 2); } } + +extern bool cpuboard_fc_check(uaecptr addr, uae_u32 *v, int size, bool write); + +uae_u32 sfc_nommu_get_byte(uaecptr addr) +{ + uae_u32 v; + if (!cpuboard_fc_check(addr, &v, 0, false)) + v = x_get_byte(addr); + return v; +} +uae_u32 sfc_nommu_get_word(uaecptr addr) +{ + uae_u32 v; + if (!cpuboard_fc_check(addr, &v, 1, false)) + v = x_get_word(addr); + return v; +} +uae_u32 sfc_nommu_get_long(uaecptr addr) +{ + uae_u32 v; + if (!cpuboard_fc_check(addr, &v, 2, false)) + v = x_get_long(addr); + return v; +} +void dfc_nommu_put_byte(uaecptr addr, uae_u32 v) +{ + if (!cpuboard_fc_check(addr, &v, 0, true)) + x_put_byte(addr, v); +} +void dfc_nommu_put_word(uaecptr addr, uae_u32 v) +{ + if (!cpuboard_fc_check(addr, &v, 1, true)) + x_put_word(addr, v); +} +void dfc_nommu_put_long(uaecptr addr, uae_u32 v) +{ + if (!cpuboard_fc_check(addr, &v, 2, true)) + x_put_long(addr, v); +} diff --git a/rommgr.cpp b/rommgr.cpp index 6670ba37..2c253621 100644 --- a/rommgr.cpp +++ b/rommgr.cpp @@ -405,6 +405,8 @@ static struct romdata roms[] = { ALTROMPN(225, 1, 2, 8192, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x7989684f, 0x9dc4d885, 0x242bf7eb, 0xe75a01b2, 0x483c9e3c, 0x8013896b) { _T("CSA Magnum 040"), 0, 0, 0, 0, _T("MAGNUM040\0"), 65536, 226, 0, 0, ROMTYPE_CB_MAGNUM40, 0, 0, NULL, 0xb94e805b, 0x4c1859ba,0x7ea2cedb,0xf5251bed,0xfbb76e6c,0x0617300e }, + { _T("CSA Twelve Gauge"), 0, 0, 0, 0, _T("12GAUGE\0"), 32768, 241, 0, 0, ROMTYPE_CB_12GAUGE, 0, 0, NULL, + 0x2a74074d, 0xc1f29093,0x491339cd,0xdc81f994,0x0f0965df,0xa3a193f2 }, { _T("Hardital TQM"), 0, 0, 0, 0, _T("TQM\0"), 32768, 228, 0, 0, ROMTYPE_CB_TQM, 0, 0, NULL, 0x3bc9b90c, 0x24fa6ab8, 0x5ca64ae6, 0x43851a85, 0xa473ff0c, 0x5a48f272, NULL, NULL }, { _T("MacroSystem Falcon 040 (No SCSI)"), 0, 0, 0, 0, _T("FALCON040\0"), 131072, 229, 0, 0, ROMTYPE_CB_FALCON40, 0, 0, NULL, diff --git a/scsi.cpp b/scsi.cpp index f0585648..5574ad35 100644 --- a/scsi.cpp +++ b/scsi.cpp @@ -72,7 +72,8 @@ #define NCR5380_EVESHAMREF 38 #define OMTI_PROFEX 39 #define NCR5380_FASTTRAK 40 -#define NCR_LAST 41 +#define NCR5380_12GAUGE 41 +#define NCR_LAST 42 extern int log_scsiemu; @@ -857,6 +858,10 @@ struct soft_scsi // sasi bool active_select; bool wait_select; + + // 12 Gauge needs this (Driver has buggy BSY test) + bool busy_delayed_hack; + int busy_delayed_hack_cnt; }; @@ -1839,6 +1844,7 @@ uae_u8 ncr5380_bget(struct soft_scsi *scsi, int reg) break; case 4: { + uae_u8 oldv = v; uae_u8 t = raw_scsi_get_signal_phase(r); v = 0; if (t & SCSI_IO_BUSY) @@ -1851,6 +1857,15 @@ uae_u8 ncr5380_bget(struct soft_scsi *scsi, int reg) v |= r->bus_phase << 2; if (scsi->regs[1] & 0x80) v |= 0x80; + + scsi->regs[reg] = v; + if (scsi->busy_delayed_hack && !(v & (1 << 6)) && (oldv & (1 << 6))) { + scsi->busy_delayed_hack_cnt = 2; + } + if (scsi->busy_delayed_hack_cnt > 0) { + scsi->busy_delayed_hack_cnt--; + v |= 1 << 6; + } } break; case 5: @@ -2648,6 +2663,17 @@ static int kronos_reg(uaecptr addr) return addr & 7; } +static int twelvegauge_reg(struct soft_scsi *ncr, uaecptr addr) +{ + if (addr & 0x8000) + return -1; + if (!(addr & 0x2000)) + return -1; + if (addr & 0x100) + return 8; + return (addr >> 4) & 7; +} + static uae_u8 read_684xx_dma(struct soft_scsi *ncr, uaecptr addr) { uae_u8 val = 0; @@ -3349,6 +3375,15 @@ static uae_u32 ncr80_bget2(struct soft_scsi *ncr, uaecptr addr, int size) v = ncr->rom[addr & 0x7fff]; } + } else if (ncr->type == NCR5380_12GAUGE) { + + reg = twelvegauge_reg(ncr, addr); + if (reg >= 0) { + v = ncr5380_bget(ncr, reg); + } else { + v = ncr->rom[addr & 0x7fff]; + } + } #if NCR5380_DEBUG > 1 @@ -3744,6 +3779,12 @@ static void ncr80_bput2(struct soft_scsi *ncr, uaecptr addr, uae_u32 val, int si reg = fasttrak_reg(ncr, addr); if (reg >= 0) ncr5380_bput(ncr, reg, val); + + } else if (ncr->type == NCR5380_12GAUGE) { + + reg = twelvegauge_reg(ncr, addr); + if (reg >= 0) + ncr5380_bput(ncr, reg, val); } #if NCR5380_DEBUG > 1 @@ -4799,6 +4840,34 @@ void phoenixboard_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct ro generic_soft_scsi_add(ch, ci, rc, NCR5380_PHOENIXBOARD, 65536, 32768, ROMTYPE_PHOENIXB); } +void twelvegauge_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc) +{ + generic_soft_scsi_add(ch, ci, rc, NCR5380_12GAUGE, 65536, 65536, ROMTYPE_CB_12GAUGE); +} + +bool twelvegauge_init(struct autoconfig_info *aci) +{ + const struct expansionromtype *ert = get_device_expansion_rom(ROMTYPE_CB_12GAUGE); + if (!aci->doinit) { + load_rom_rc(aci->rc, ROMTYPE_CB_12GAUGE, 32768, 0, aci->autoconfig_raw, 128, 0); + return true; + } + + struct soft_scsi *scsi = getscsi(aci->rc); + if (!scsi) + return false; + + scsi->intena = true; + scsi->busy_delayed_hack = true; + + load_rom_rc(aci->rc, ROMTYPE_CB_12GAUGE, 32768, 0, scsi->rom, 32768, 0); + memcpy(scsi->acmemory, scsi->rom, sizeof scsi->acmemory); + + aci->addrbank = scsi->bank; + + return true; +} + void ivsvector_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc) { generic_soft_scsi_add(ch, ci, rc, NCR5380_IVSVECTOR, 65536, 65536, ROMTYPE_CB_VECTOR); -- 2.47.3