From: Toni Wilen Date: Fri, 26 Jun 2015 15:54:28 +0000 (+0300) Subject: SASI emulation, Tecmar and Xebec. X-Git-Tag: 3200~166 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=4d739946eaae068ff788da6ca0cc4262c39cc726;p=francis%2Fwinuae.git SASI emulation, Tecmar and Xebec. --- diff --git a/expansion.cpp b/expansion.cpp index 417212db..67f8e379 100644 --- a/expansion.cpp +++ b/expansion.cpp @@ -40,6 +40,13 @@ #include "specialmonitors.h" #include "pci.h" +// More information in first revision HRM Appendix_G +#define BOARD_PROTOAUTOCONFIG 1 + +#define BOARD_AUTOCONFIG_Z2 2 +#define BOARD_AUTOCONFIG_Z3 3 +#define BOARD_NONAUTOCONFIG 4 + #define EXP_DEBUG 0 #define MAX_EXPANSION_BOARD_SPACE 16 @@ -69,7 +76,9 @@ #define rom_card 0x10 /* ROM vector is valid */ #define add_memory 0x20 /* Link RAM into free memory list */ -#define zorroII 0xc0 /* Type of Expansion Card */ +/* Type of Expansion Card */ +#define protoautoconfig 0x40 +#define zorroII 0xc0 #define zorroIII 0x80 /* ********************************************************** */ @@ -386,7 +395,7 @@ static void call_card_init(int index) } code = expamem_read(0); - if ((code & 0xc0) == 0xc0) { + if ((code & 0xc0) == zorroII) { // Z2 code &= 7; if (code == 0) @@ -397,7 +406,7 @@ static void call_card_init(int index) expamem_board_size = expamem_z2_size; expamem_board_pointer = expamem_z2_pointer; - } else { + } else if ((code & 0xc0) == zorroIII) { // Z3 if (expamem_z3_sum < Z3BASE_UAE) { expamem_z3_sum = currprefs.z3autoconfig_start; @@ -428,6 +437,16 @@ static void call_card_init(int index) expamem_board_size = expamem_z3_size; expamem_board_pointer = expamem_z3_pointer; + + } else if ((code & 0xc0) == 0x40) { + // 0x40 = "Box without init/diagnostic code" + // proto autoconfig "box" size. + //expamem_z2_size = (1 << ((code >> 3) & 7)) * 4096; + // much easier this way, all old-style boards were made for + // A1000 and didn't have passthrough connector. + expamem_z2_size = 65536; + expamem_board_size = expamem_z2_size; + expamem_board_pointer = expamem_z2_pointer; } if (ab) { @@ -467,7 +486,7 @@ static void boardmessage(addrbank *mapped, bool success) size /= 1024; } write_log (_T("Card %d: Z%d 0x%08x %4d%c %s %s%s\n"), - ecard + 1, (type & 0xc0) == zorroII ? 2 : 3, + ecard + 1, (type & 0xc0) == zorroII ? 2 : ((type & 0xc0) == zorroIII ? 3 : 1), expamem_board_pointer, size, sizemod, type & rom_card ? _T("ROM") : (type & add_memory ? _T("RAM") : _T("IO ")), mapped->name, @@ -642,34 +661,47 @@ static void REGPARAM2 expamem_bput (uaecptr addr, uae_u32 value) } if (ecard >= cardno) return; - switch (addr & 0xff) { - case 0x48: - if (expamem_type() == zorroII) { - expamem_hi = value & 0xff; - expamem_z2_pointer = (expamem_hi | (expamem_lo >> 4)) << 16; + if (expamem_type() == protoautoconfig) { + switch (addr & 0xff) { + case 0x22: + expamem_hi = value & 0x7f; + expamem_z2_pointer = 0xe80000 | (expamem_hi * 4096); expamem_board_pointer = expamem_z2_pointer; if (cards[ecard].map) { expamem_next(cards[ecard].map(), NULL); return; } - } else { - expamem_lo = value & 0xff; + break; } - break; + } else { + switch (addr & 0xff) { + case 0x48: + if (expamem_type() == zorroII) { + expamem_hi = value & 0xff; + expamem_z2_pointer = (expamem_hi | (expamem_lo >> 4)) << 16; + expamem_board_pointer = expamem_z2_pointer; + if (cards[ecard].map) { + expamem_next(cards[ecard].map(), NULL); + return; + } + } else { + expamem_lo = value & 0xff; + } + break; - case 0x4a: - if (expamem_type () == zorroII) - expamem_lo = value & 0xff; - break; + case 0x4a: + if (expamem_type () == zorroII) + expamem_lo = value & 0xff; + break; - case 0x4c: - if (cards[ecard].map) { - expamem_next(expamem_bank_current, NULL); - return; + case 0x4c: + if (cards[ecard].map) { + expamem_next(expamem_bank_current, NULL); + return; + } + break; } - break; } - if (expamem_bank_current && expamem_bank_current != &expamem_bank) expamem_bank_current->bput(addr, value); } @@ -1842,11 +1874,11 @@ void expamem_reset (void) } // add possible non-autoconfig boards - add_cpu_expansions(1); + add_cpu_expansions(BOARD_NONAUTOCONFIG); bool fastmem_after = false; if (currprefs.fastmem_autoconfig) { - fastmem_after = add_fastram_after_expansion(2); + fastmem_after = add_fastram_after_expansion(BOARD_AUTOCONFIG_Z2); if (!fastmem_after && fastmem_bank.baseaddr != NULL && (fastmem_bank.allocated <= 262144 || currprefs.chipmem_size <= 2 * 1024 * 1024)) { cards[cardno].flags = 0; cards[cardno].name = _T("Z2Fast"); @@ -1871,8 +1903,8 @@ void expamem_reset (void) } // immediately after Z2Fast so that they can be emulated as A590/A2091 with fast ram. - add_cpu_expansions(2); - add_expansions(2); + add_cpu_expansions(BOARD_AUTOCONFIG_Z2); + add_expansions(BOARD_AUTOCONFIG_Z2); if (fastmem_after && currprefs.fastmem_autoconfig) { if (fastmem_bank.baseaddr != NULL && (fastmem_bank.allocated <= 262144 || currprefs.chipmem_size <= 2 * 1024 * 1024)) { @@ -1964,7 +1996,7 @@ void expamem_reset (void) /* Z3 boards last */ if (!currprefs.address_space_24) { - add_cpu_expansions(3); + add_cpu_expansions(BOARD_AUTOCONFIG_Z3); if (z3fastmem_bank.baseaddr != NULL) { z3num = 0; @@ -2004,15 +2036,15 @@ void expamem_reset (void) } #endif - add_expansions(3); + add_expansions(BOARD_AUTOCONFIG_Z3); } - // zorro == 1: non-autoconfig/hardwired - add_expansions(1); + add_expansions(BOARD_NONAUTOCONFIG); expamem_z3_pointer = 0; expamem_z3_sum = 0; + expamem_z2_pointer = 0; if (cardno == 0 || savestate_state) expamem_init_clear_zero (); else @@ -2410,125 +2442,131 @@ const struct expansionromtype expansionroms[] = { NULL, 0, false, EXPANSIONTYPE_SCSI | EXPANSIONTYPE_IDE }, - { - _T("cpuboard_ext"), _T("SCSI Kit IV"), _T("Blizzard"), - NULL, NULL, NULL, ROMTYPE_CPUBOARDEXT, ROMTYPE_CPUBOARD, 0, 0, true, - NULL, 0, - false, EXPANSIONTYPE_SCSI - }, { _T("grex"), _T("G-REX"), _T("DCE"), - grex_init, NULL, NULL, ROMTYPE_GREX | ROMTYPE_NOT, 0, 0, 1, true, - }, - { - _T("prometheus"), _T("Prometheus"), _T("Matay"), - prometheus_init, NULL, NULL, ROMTYPE_PROMETHEUS | ROMTYPE_NOT, 0, 0, 3, false, + grex_init, NULL, NULL, ROMTYPE_GREX | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG, true, + NULL, 0, + false, EXPANSIONTYPE_PCI_BRIDGE }, { _T("mediator"), _T("Mediator"), _T("Elbox"), - mediator_init, mediator_init2, NULL, ROMTYPE_MEDIATOR | ROMTYPE_NOT, 0, 0, 3, false, + mediator_init, mediator_init2, NULL, ROMTYPE_MEDIATOR | ROMTYPE_NOT, 0, 0, BOARD_AUTOCONFIG_Z3, false, mediator_sub, 0, - false, 0, + false, EXPANSIONTYPE_PCI_BRIDGE, 0, 0, 0, false, NULL, false, mediator_settings }, { - _T("a2090a"), _T("A2090a"), _T("Commodore"), - a2090_init, NULL, a2090_add_scsi_unit, ROMTYPE_A2090 | ROMTYPE_NONE, 0, 0, 2, false, + _T("prometheus"), _T("Prometheus"), _T("Matay"), + prometheus_init, NULL, NULL, ROMTYPE_PROMETHEUS | ROMTYPE_NOT, 0, 0, BOARD_AUTOCONFIG_Z3, false, NULL, 0, - true, EXPANSIONTYPE_SCSI - }, - { - _T("a2091"), _T("A590/A2091"), _T("Commodore"), - a2091_init, NULL, a2091_add_scsi_unit, ROMTYPE_A2091 | ROMTYPE_NONE, 0, 0, 2, false, - a2091_sub, 1, - true, EXPANSIONTYPE_SCSI, - 0, 0, 0, true, NULL + false, EXPANSIONTYPE_PCI_BRIDGE }, { - _T("a4091"), _T("A4091"), _T("Commodore"), - ncr710_a4091_autoconfig_init, NULL, a4091_add_scsi_unit, ROMTYPE_A4091, 0, 0, 3, false, + _T("apollo"), _T("Apollo"), _T("ACT"), + apollo_init_hd, NULL, apollo_add_scsi_unit, ROMTYPE_APOLLO, 0, 0, BOARD_AUTOCONFIG_Z2, false, NULL, 0, - false, EXPANSIONTYPE_SCSI, - 0, 0, 0, false, NULL, - true + false, EXPANSIONTYPE_SCSI | EXPANSIONTYPE_IDE, + 8738, 0, 0 }, { - _T("fastlane"), _T("Fastlane"), _T("Phase 5"), - ncr_fastlane_autoconfig_init, NULL, fastlane_add_scsi_unit, ROMTYPE_FASTLANE, 0, 0, 3, false, + _T("add500"), _T("ADD-500"), _T("Archos"), + add500_init, NULL, add500_add_scsi_unit, ROMTYPE_ADD500, 0, 0, BOARD_AUTOCONFIG_Z2, false, NULL, 0, false, EXPANSIONTYPE_SCSI, - 8512, 10, 0, false, fastlane_memory_callback - }, - { - _T("gvp1"), _T("Series I"), _T("GVP"), - gvp_init_s1, NULL, gvp_s1_add_scsi_unit, ROMTYPE_GVPS1 | ROMTYPE_NONE, ROMTYPE_GVPS12, 0, 2, false, - gvp1_sub, 1, - true, EXPANSIONTYPE_SCSI + 8498, 27, 0, true, NULL }, { - _T("gvp"), _T("Series II"), _T("GVP"), - gvp_init_s2, NULL, gvp_s2_add_scsi_unit, ROMTYPE_GVPS2 | ROMTYPE_NONE, ROMTYPE_GVPS12, 0, 2, false, + _T("blizzardscsikitiv"), _T("SCSI Kit IV"), _T("Blizzard"), + NULL, NULL, cpuboard_ncr9x_add_scsi_unit, ROMTYPE_BLIZKIT4, 0, 0, 0, true, NULL, 0, - true, EXPANSIONTYPE_SCSI, - 2017, 10, 0 + false, EXPANSIONTYPE_SCSI }, { _T("oktagon2008"), _T("Oktagon 2008"), _T("BSC/Alfa Data"), - ncr_oktagon_autoconfig_init, NULL, oktagon_add_scsi_unit, ROMTYPE_OKTAGON, 0, 0, 2, false, + ncr_oktagon_autoconfig_init, NULL, oktagon_add_scsi_unit, ROMTYPE_OKTAGON, 0, 0, BOARD_AUTOCONFIG_Z2, false, NULL, 0, true, EXPANSIONTYPE_SCSI }, { _T("alfapower"), _T("AlfaPower/AT-Bus 2008"), _T("BSC/Alfa Data"), - alf_init, NULL, alf_add_ide_unit, ROMTYPE_ALFA, 0, 0, 2, false, + alf_init, NULL, alf_add_ide_unit, ROMTYPE_ALFA, 0, 0, BOARD_AUTOCONFIG_Z2, false, NULL, 0, false, EXPANSIONTYPE_IDE, 2092, 8, 0 }, { _T("alfapowerplus"), _T("AlfaPower Plus"), _T("BSC/Alfa Data"), - alf_init, NULL, alf_add_ide_unit, ROMTYPE_ALFAPLUS, 0, 0, 2, false, + alf_init, NULL, alf_add_ide_unit, ROMTYPE_ALFAPLUS, 0, 0, BOARD_AUTOCONFIG_Z2, false, NULL, 0, false, EXPANSIONTYPE_IDE, 2092, 8, 0 }, { - _T("apollo"), _T("Apollo"), _T("ACT"), - apollo_init_hd, NULL, apollo_add_scsi_unit, ROMTYPE_APOLLO, 0, 0, 2, false, + _T("cltda1000scsi"), _T("A1000/A2000 SCSI"), _T("C-Ltd"), + cltda1000scsi_init, NULL, cltda1000scsi_add_scsi_unit, ROMTYPE_CLTDSCSI | ROMTYPE_NOT, 0, 0, BOARD_AUTOCONFIG_Z2, false, NULL, 0, - false, EXPANSIONTYPE_SCSI | EXPANSIONTYPE_IDE, - 8738, 0, 0 + false, EXPANSIONTYPE_SCSI, + 0, 0, 0, false, NULL, + false, NULL, + { 0xc1, 0x0c, 0x00, 0x00, 0x03, 0xec, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, }, { - _T("masoboshi"), _T("MasterCard"), _T("Masoboshi"), - masoboshi_init, NULL, masoboshi_add_idescsi_unit, ROMTYPE_MASOBOSHI | ROMTYPE_NONE, 0, 0, 2, false, - masoboshi_sub, 0, - true, EXPANSIONTYPE_SCSI | EXPANSIONTYPE_IDE + _T("a2090a"), _T("A2090a"), _T("Commodore"), + a2090_init, NULL, a2090_add_scsi_unit, ROMTYPE_A2090 | ROMTYPE_NONE, 0, 0, BOARD_AUTOCONFIG_Z2, false, + NULL, 0, + true, EXPANSIONTYPE_SCSI }, { - _T("supradrive"), _T("SupraDrive"), _T("Supra"), - supra_init, NULL, supra_add_scsi_unit, ROMTYPE_SUPRA | ROMTYPE_NONE, 0, 0, 2, false, - supra_sub, 0, + _T("a2091"), _T("A590/A2091"), _T("Commodore"), + a2091_init, NULL, a2091_add_scsi_unit, ROMTYPE_A2091 | ROMTYPE_NONE, 0, 0, BOARD_AUTOCONFIG_Z2, false, + a2091_sub, 1, + true, EXPANSIONTYPE_SCSI, + 0, 0, 0, true, NULL + }, + { + _T("a4091"), _T("A4091"), _T("Commodore"), + ncr710_a4091_autoconfig_init, NULL, a4091_add_scsi_unit, ROMTYPE_A4091, 0, 0, BOARD_AUTOCONFIG_Z3, false, + NULL, 0, + false, EXPANSIONTYPE_SCSI, + 0, 0, 0, false, NULL, + true + }, + { + _T("dataflyerscsiplus"), _T("DataFlyer SCSI+"), _T("Expansion Systems"), + dataflyer_init, NULL, dataflyer_add_scsi_unit, ROMTYPE_DATAFLYER | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG, true, + NULL, 0, + false, EXPANSIONTYPE_SCSI + }, + { + _T("gvp1"), _T("Series I"), _T("GVP"), + gvp_init_s1, NULL, gvp_s1_add_scsi_unit, ROMTYPE_GVPS1 | ROMTYPE_NONE, ROMTYPE_GVPS12, 0, BOARD_AUTOCONFIG_Z2, false, + gvp1_sub, 1, true, EXPANSIONTYPE_SCSI }, { - _T("golem"), _T("Golem"), _T("Kupke"), - golem_init, NULL, golem_add_scsi_unit, ROMTYPE_GOLEM, 0, 0, 2, false, + _T("gvp"), _T("Series II"), _T("GVP"), + gvp_init_s2, NULL, gvp_s2_add_scsi_unit, ROMTYPE_GVPS2 | ROMTYPE_NONE, ROMTYPE_GVPS12, 0, BOARD_AUTOCONFIG_Z2, false, NULL, 0, true, EXPANSIONTYPE_SCSI, - 2079, 3, 0 + 2017, 10, 0 + }, + { + _T("vector"), _T("Vector Falcon 8000"), _T("HK-Computer"), + vector_init, NULL, vector_add_scsi_unit, ROMTYPE_VECTOR, 0, 0, BOARD_AUTOCONFIG_Z2, false, + NULL, 0, + false, EXPANSIONTYPE_SCSI }, { _T("adide"), _T("AdIDE"), _T("ICD"), - adide_init, NULL, adide_add_ide_unit, ROMTYPE_ADIDE | ROMTYPE_NONE, 0, 0, 2, false, + adide_init, NULL, adide_add_ide_unit, ROMTYPE_ADIDE | ROMTYPE_NONE, 0, 0, BOARD_AUTOCONFIG_Z2, false, NULL, 0, true, EXPANSIONTYPE_IDE }, { _T("adscsi2000"), _T("AdSCSI Advantage 2000"), _T("ICD"), - adscsi_init, NULL, adscsi_add_scsi_unit, ROMTYPE_ADSCSI, 0, 0, 2, false, + adscsi_init, NULL, adscsi_add_scsi_unit, ROMTYPE_ADSCSI, 0, 0, BOARD_AUTOCONFIG_Z2, false, NULL, 0, false, EXPANSIONTYPE_SCSI, 0, 0, 0, false, NULL, @@ -2536,21 +2574,33 @@ const struct expansionromtype expansionroms[] = { adscsi2000_settings }, { - _T("mtecat"), _T("AT 500"), _T("M-Tec"), - mtec_init, NULL, mtec_add_ide_unit, ROMTYPE_MTEC, 0, 0, 2, false, + _T("kommos"), _T("A500/A2000 SCSI"), _T("Jürgen Kommos"), + kommos_init, NULL, kommos_add_scsi_unit, ROMTYPE_KOMMOS, 0, 0, BOARD_NONAUTOCONFIG, true, NULL, 0, - true, EXPANSIONTYPE_IDE + false, EXPANSIONTYPE_SCSI }, { - _T("protar"), _T("A500 HD"), _T("Protar"), - protar_init, NULL, protar_add_ide_unit, ROMTYPE_PROTAR, 0, 0, 2, false, + _T("golem"), _T("Golem"), _T("Kupke"), + golem_init, NULL, golem_add_scsi_unit, ROMTYPE_GOLEM, 0, 0, BOARD_AUTOCONFIG_Z2, false, NULL, 0, true, EXPANSIONTYPE_SCSI, - 4149, 51, 0 + 2079, 3, 0 + }, + { + _T("mtecat"), _T("AT 500"), _T("M-Tec"), + mtec_init, NULL, mtec_add_ide_unit, ROMTYPE_MTEC, 0, 0, BOARD_AUTOCONFIG_Z2, false, + NULL, 0, + true, EXPANSIONTYPE_IDE + }, + { + _T("masoboshi"), _T("MasterCard"), _T("Masoboshi"), + masoboshi_init, NULL, masoboshi_add_idescsi_unit, ROMTYPE_MASOBOSHI | ROMTYPE_NONE, 0, 0, BOARD_AUTOCONFIG_Z2, false, + masoboshi_sub, 0, + true, EXPANSIONTYPE_SCSI | EXPANSIONTYPE_IDE }, { _T("stardrive"), _T("StarDrive"), _T("Microbotics"), - stardrive_init, NULL, stardrive_add_scsi_unit, ROMTYPE_STARDRIVE | ROMTYPE_NOT, 0, 0, 2, true, + stardrive_init, NULL, stardrive_add_scsi_unit, ROMTYPE_STARDRIVE | ROMTYPE_NOT, 0, 0, BOARD_AUTOCONFIG_Z2, true, NULL, 0, false, EXPANSIONTYPE_SCSI, 1010, 0, 0, false, NULL, @@ -2559,54 +2609,60 @@ const struct expansionromtype expansionroms[] = { }, { - _T("kommos"), _T("A500/A2000 SCSI"), _T("Jürgen Kommos"), - kommos_init, NULL, kommos_add_scsi_unit, ROMTYPE_KOMMOS, 0, 0, 1, true, + _T("fastlane"), _T("Fastlane"), _T("Phase 5"), + ncr_fastlane_autoconfig_init, NULL, fastlane_add_scsi_unit, ROMTYPE_FASTLANE, 0, 0, BOARD_AUTOCONFIG_Z3, false, NULL, 0, - false, EXPANSIONTYPE_SCSI + false, EXPANSIONTYPE_SCSI, + 8512, 10, 0, false, fastlane_memory_callback }, { - _T("vector"), _T("Vector Falcon 8000"), _T("HK-Computer"), - vector_init, NULL, vector_add_scsi_unit, ROMTYPE_VECTOR, 0, 0, 2, false, + _T("ptnexus"), _T("Nexus"), _T("Preferred Technologies"), + ptnexus_init, NULL, ptnexus_add_scsi_unit, ROMTYPE_PTNEXUS | ROMTYPE_NONE, 0, 0, BOARD_AUTOCONFIG_Z2, false, NULL, 0, - false, EXPANSIONTYPE_SCSI + false, EXPANSIONTYPE_SCSI, + 2102, 4, 0, false, nexus_memory_callback, + false, nexus_settings, + { 0xd1, 0x01, 0x00, 0x00, 0x08, 0x36, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00 }, }, { - _T("add500"), _T("ADD-500"), _T("Archos"), - add500_init, NULL, add500_add_scsi_unit, ROMTYPE_ADD500, 0, 0, 2, false, + _T("protar"), _T("A500 HD"), _T("Protar"), + protar_init, NULL, protar_add_ide_unit, ROMTYPE_PROTAR, 0, 0, BOARD_AUTOCONFIG_Z2, false, NULL, 0, - false, EXPANSIONTYPE_SCSI, - 8498, 27, 0, true, NULL + true, EXPANSIONTYPE_SCSI, + 4149, 51, 0 }, { _T("rochard"), _T("RocHard RH800C"), _T("Roctec"), - rochard_init, NULL, rochard_add_idescsi_unit, ROMTYPE_ROCHARD | ROMTYPE_NONE, 0, 0, 2, false, + rochard_init, NULL, rochard_add_idescsi_unit, ROMTYPE_ROCHARD | ROMTYPE_NONE, 0, 0, BOARD_AUTOCONFIG_Z2, false, rochard_sub, 0, true, EXPANSIONTYPE_IDE | EXPANSIONTYPE_SCSI | EXPANSIONTYPE_IDE_PORT_DOUBLED, 2144, 2, 0 }, { - _T("cltda1000scsi"), _T("A1000/A2000 SCSI"), _T("C-Ltd"), - cltda1000scsi_init, NULL, cltda1000scsi_add_scsi_unit, ROMTYPE_CLTDSCSI | ROMTYPE_NOT, 0, 0, 2, false, + _T("supradrive"), _T("SupraDrive"), _T("Supra Corporation"), + supra_init, NULL, supra_add_scsi_unit, ROMTYPE_SUPRA | ROMTYPE_NONE, 0, 0, BOARD_AUTOCONFIG_Z2, false, + supra_sub, 0, + true, EXPANSIONTYPE_SCSI + }, +#if 0 /* driver is MIA, 3rd party ScottDevice driver is not enough for full implementation. */ + { + _T("microforge"), _T("Hard Disk"), _T("Micro Forge"), + microforge_init, NULL, microforge_add_scsi_unit, ROMTYPE_MICROFORGE | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG, true, NULL, 0, - false, EXPANSIONTYPE_SCSI, - 0, 0, 0, false, NULL, - false, NULL, - { 0xc1, 0x0c, 0x00, 0x00, 0x03, 0xec, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + false, EXPANSIONTYPE_SASI | EXPANSIONTYPE_SCSI }, +#endif { - _T("ptnexus"), _T("Nexus"), _T("Preferred Technologies"), - ptnexus_init, NULL, ptnexus_add_scsi_unit, ROMTYPE_PTNEXUS | ROMTYPE_NONE, 0, 0, 2, false, + _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, NULL, 0, - false, EXPANSIONTYPE_SCSI, - 2102, 4, 0, false, nexus_memory_callback, - false, nexus_settings, - { 0xd1, 0x01, 0x00, 0x00, 0x08, 0x36, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00 }, + false, EXPANSIONTYPE_SASI | EXPANSIONTYPE_SCSI }, { - _T("dataflyerscsiplus"), _T("DataFlyer SCSI+"), _T("Expansion Systems"), - dataflyer_init, NULL, dataflyer_add_scsi_unit, ROMTYPE_DATAFLYER | ROMTYPE_NOT, 0, 0, 1, true, + _T("xebec"), _T("9720H"), _T("Xebec"), + xebec_init, NULL, xebec_add_scsi_unit, ROMTYPE_XEBEC | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG, true, NULL, 0, - false, EXPANSIONTYPE_SCSI, + false, EXPANSIONTYPE_SASI | EXPANSIONTYPE_SCSI }, #if 0 { @@ -2646,7 +2702,7 @@ static const struct cpuboardsubtype gvpboard_sub[] = { BOARD_MEMORY_Z2, 8 * 1024 * 1024, 0, - gvp_ide_rom_autoconfig_init, NULL, 2, 0 + gvp_ide_rom_autoconfig_init, NULL, BOARD_AUTOCONFIG_Z2, 0 }, { _T("A3001 Series II"), @@ -2656,7 +2712,7 @@ static const struct cpuboardsubtype gvpboard_sub[] = { BOARD_MEMORY_Z2, 8 * 1024 * 1024, 0, - gvp_ide_rom_autoconfig_init, gvp_ide_controller_autoconfig_init, 2, 0 + gvp_ide_rom_autoconfig_init, gvp_ide_controller_autoconfig_init, BOARD_AUTOCONFIG_Z2, 0 }, { _T("A530"), @@ -2666,7 +2722,7 @@ static const struct cpuboardsubtype gvpboard_sub[] = { BOARD_MEMORY_Z2, 8 * 1024 * 1024, 0, - gvp_init_accelerator, NULL, 2, 1, + gvp_init_accelerator, NULL, BOARD_AUTOCONFIG_Z2, 1, NULL, NULL, 2017, 9, 0, false }, @@ -2678,7 +2734,7 @@ static const struct cpuboardsubtype gvpboard_sub[] = { BOARD_MEMORY_25BITMEM, 128 * 1024 * 1024, 0, - gvp_init_accelerator, NULL, 2, 1 + gvp_init_accelerator, NULL, BOARD_AUTOCONFIG_Z2, 1 }, { _T("Tek Magic 2040/2060"), @@ -2697,7 +2753,7 @@ static const struct cpuboardsubtype blizzardboard_sub[] = { _T("Blizzard 1230 IV"), _T("Blizzard1230IV"), ROMTYPE_CB_BLIZ1230, 0, - cpuboard_ncr9x_add_scsi_unit, EXPANSIONTYPE_SCSI, + NULL, 0, BOARD_MEMORY_BLIZZARD_12xx, 256 * 1024 * 1024, 0, @@ -2708,7 +2764,7 @@ static const struct cpuboardsubtype blizzardboard_sub[] = { _T("Blizzard 1260"), _T("Blizzard1260"), ROMTYPE_CB_BLIZ1260, 0, - cpuboard_ncr9x_add_scsi_unit, EXPANSIONTYPE_SCSI, + NULL, 0, BOARD_MEMORY_BLIZZARD_12xx, 256 * 1024 * 1024, 0, @@ -2784,7 +2840,7 @@ static const struct cpuboardsubtype warpengine_sub[] = { BOARD_MEMORY_HIGHMEM, 128 * 1024 * 1024, 0x01000000, - ncr710_warpengine_autoconfig_init, NULL, 3, 1 + ncr710_warpengine_autoconfig_init, NULL, BOARD_AUTOCONFIG_Z3, 1 }, { NULL @@ -2825,7 +2881,7 @@ static const struct cpuboardsubtype dbk_sub[] = { 0, 128 * 1024 * 1024, 0, - ncr_dkb_autoconfig_init, NULL, 2, 0 + ncr_dkb_autoconfig_init, NULL, BOARD_AUTOCONFIG_Z2, 0 }, { _T("Wildfire"), @@ -2835,7 +2891,7 @@ static const struct cpuboardsubtype dbk_sub[] = { BOARD_MEMORY_HIGHMEM, 128 * 1024 * 1024, 0, - dkb_wildfire_pci_init, NULL, 1, 0 // fake board + dkb_wildfire_pci_init, NULL, BOARD_NONAUTOCONFIG, 0 }, { NULL @@ -2905,19 +2961,9 @@ const struct cpuboardtype cpuboards[] = { dummy_sub, 0 }, { - BOARD_BLIZZARD, - _T("Phase 5 - Blizzard"), - blizzardboard_sub, 0 - }, - { - BOARD_CYBERSTORM, - _T("Phase 5 - CyberStorm"), - cyberstormboard_sub, 0 - }, - { - BOARD_MACROSYSTEM, - _T("MacroSystem"), - warpengine_sub, 0 + BOARD_ACT, + _T("ACT"), + apollo_sub, 0 }, { BOARD_COMMODORE, @@ -2929,16 +2975,6 @@ const struct cpuboardtype cpuboards[] = { _T("DKB"), dbk_sub, 0 }, - { - BOARD_RCS, - _T("RCS Management"), - fusionforty_sub, 0 - }, - { - BOARD_ACT, - _T("ACT"), - apollo_sub, 0 - }, { BOARD_GVP, _T("GVP"), @@ -2949,6 +2985,26 @@ const struct cpuboardtype cpuboards[] = { _T("Kupke"), kupkeboard_sub, 0 }, + { + BOARD_MACROSYSTEM, + _T("MacroSystem"), + warpengine_sub, 0 + }, + { + BOARD_BLIZZARD, + _T("Phase 5 - Blizzard"), + blizzardboard_sub, 0 + }, + { + BOARD_CYBERSTORM, + _T("Phase 5 - CyberStorm"), + cyberstormboard_sub, 0 + }, + { + BOARD_RCS, + _T("RCS Management"), + fusionforty_sub, 0 + }, #if 0 { BOARD_IC, diff --git a/hardfile.cpp b/hardfile.cpp index cc361313..afc8d739 100644 --- a/hardfile.cpp +++ b/hardfile.cpp @@ -28,6 +28,7 @@ #include "execio.h" #include "zfile.h" #include "ide.h" +#include "debug.h" #ifdef WITH_CHD #include "archivers/chd/chdtypes.h" @@ -1138,6 +1139,18 @@ static void setdrivestring(const TCHAR *s, uae_u8 *d, int start, int length) xfree (ss); } +static const uae_u8 sasi_commands[] = +{ + 0x00, 0x01, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x12, + 0xe0, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, + 0xff +}; +static const uae_u8 sasi_commands2[] = +{ + 0x12, + 0xff +}; + int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, uae_u8 *cmdbuf, int scsi_cmd_len, uae_u8 *scsi_data, int *data_len, uae_u8 *r, int *reply_len, uae_u8 *s, int *sense_len) { @@ -1147,6 +1160,8 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua int status = 0; int lun; uae_u8 cmd = cmdbuf[0]; + bool sasi = hfd->ci.unit_feature_level >= HD_LEVEL_SASI; + bool sasie = hfd->ci.unit_feature_level == HD_LEVEL_SASI_ENHANCED; if (log_scsiemu) { write_log (_T("SCSIEMU HD %d: %02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X CMDLEN=%d DATA=%p\n"), hfd->unitnum, @@ -1168,6 +1183,8 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua *reply_len = *sense_len = 0; lun = cmdbuf[1] >> 5; + if (sasi) + lun = 0; if (cmd != 0x03 && cmd != 0x12 && lun) { status = 2; /* CHECK CONDITION */ s[0] = 0x70; @@ -1178,6 +1195,55 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua goto scsi_done; } + if (sasi) { + int i; + for (i = 0; sasi_commands[i] != 0xff; i++) { + if (sasi_commands[i] == cmdbuf[0]) + break; + } + if (sasi_commands[i] == 0xff) { + if (sasie) { + for (i = 0; sasi_commands2[i] != 0xff; i++) { + if (sasi_commands2[i] == cmdbuf[0]) + break; + } + if (sasi_commands2[i] == 0xff) + goto errreq; + } else { + goto errreq; + } + } + switch (cmdbuf[0]) + { + case 0x0c: /* INITIALIZE DRIVE CHARACTERICS */ + scsi_len = 8; + goto scsi_done; + case 0x12: /* INQUIRY */ + { + int cyl, cylsec, head, tracksec; + int alen = cmdbuf[4]; + if (nodisk(hfd)) + goto nodisk; + if (hdhfd) { + cyl = hdhfd->cyls; + head = hdhfd->heads; + tracksec = hdhfd->secspertrack; + cylsec = 0; + } else { + getchsx(hfd, &cyl, &cylsec, &head, &tracksec); + } + r[0] = 0; + r[1] = 11; + r[9] = cyl >> 8; + r[10] = cyl; + r[11] = head; + scsi_len = lr = alen > 12 ? 12 : alen; + goto scsi_done; + } + break; + } + } + switch (cmdbuf[0]) { case 0x12: /* INQUIRY */ @@ -1245,6 +1311,15 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua goto readprot; scsi_len = 0; break; + case 0x09: /* READ VERIFY */ + if (nodisk(hfd)) + goto nodisk; + offset = ((cmdbuf[1] & 31) << 16) | (cmdbuf[2] << 8) | cmdbuf[3]; + offset *= hfd->ci.blocksize; + if (!checkbounds(hfd, offset, hfd->ci.blocksize)) + goto outofbounds; + scsi_len = 0; + break; case 0x0b: /* SEEK (6) */ if (nodisk (hfd)) goto nodisk; @@ -1267,6 +1342,9 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua goto outofbounds; scsi_len = (uae_u32)cmd_readx (hfd, scsi_data, offset, len); break; + case 0x0f: /* WRITE SECTOR BUFFER */ + scsi_len = hfd->ci.blocksize; + break; case 0x0a: /* WRITE (6) */ if (nodisk (hfd)) goto nodisk; @@ -1493,6 +1571,11 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua ls = 0x12; #endif break; + case 0xe0: /* RAM DIAGNOSTICS */ + case 0xe3: /* DRIVE DIAGNOSTIC */ + case 0xe4: /* CONTROLLER INTERNAL DIAGNOSTICS */ + scsi_len = 0; + break; readprot: status = 2; /* CHECK CONDITION */ s[0] = 0x70; diff --git a/include/autoconf.h b/include/autoconf.h index 65e1ab4f..98c048da 100644 --- a/include/autoconf.h +++ b/include/autoconf.h @@ -111,6 +111,8 @@ typedef void(*DEVICE_MEMORY_CALLBACK)(struct romconfig*, uae_u8*, int); #define EXPANSIONTYPE_IDE 2 #define EXPANSIONTYPE_24BIT 4 #define EXPANSIONTYPE_IDE_PORT_DOUBLED 8 +#define EXPANSIONTYPE_SASI 16 +#define EXPANSIONTYPE_PCI_BRIDGE 32 struct expansionboardsettings { const TCHAR *name; diff --git a/include/scsi.h b/include/scsi.h index 358c900e..1c648db3 100644 --- a/include/scsi.h +++ b/include/scsi.h @@ -200,3 +200,12 @@ void ptnexus_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconf addrbank *dataflyer_init(struct romconfig *rc); void dataflyer_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc); + +addrbank *tecmar_init(struct romconfig *rc); +void tecmar_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc); + +addrbank *xebec_init(struct romconfig *rc); +void xebec_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc); + +addrbank *microforge_init(struct romconfig *rc); +void microforge_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc); diff --git a/scsi.cpp b/scsi.cpp index 9e19df30..03b1af91 100644 --- a/scsi.cpp +++ b/scsi.cpp @@ -42,13 +42,16 @@ #define NCR5380_CLTD 12 #define NCR5380_PTNEXUS 13 #define NCR5380_DATAFLYER 14 -#define NCR_LAST 15 +#define NONCR_TECMAR 15 +#define NCR5380_XEBEC 16 +#define NONCR_MICROFORGE 17 +#define NCR_LAST 18 extern int log_scsiemu; -static const int outcmd[] = { 0x04, 0x0a, 0x2a, 0xaa, 0x15, 0x55, -1 }; +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, 0x0b, 0x11, 0x16, 0x17, 0x19, 0x1b, 0x1e, 0x2b, 0x35, -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 void scsi_illegal_command(struct scsi_data *sd) @@ -127,6 +130,9 @@ bool scsi_emulate_analyze (struct scsi_data *sd) return true; } break; + case 0x0c: // INITIALIZE DRIVE CHARACTERICS (SASI) + data_len = 8; + break; case 0x08: // READ(6) data_len2 = sd->cmd[4] * sd->blocksize; scsi_grow_buffer(sd, data_len2); @@ -139,6 +145,10 @@ bool scsi_emulate_analyze (struct scsi_data *sd) data_len2 = ((sd->cmd[6] << 24) | (sd->cmd[7] << 16) | (sd->cmd[8] << 8) | (sd->cmd[9] << 0)) * (uae_s64)sd->blocksize; scsi_grow_buffer(sd, data_len2); break; + case 0x0f: // WRITE SECTOR BUFFER + data_len = sd->blocksize; + scsi_grow_buffer(sd, data_len); + break; case 0x0a: // WRITE(6) if (sd->device_type == UAEDEV_CD) goto nocmd; @@ -614,6 +624,7 @@ struct soft_scsi struct raw_scsi rscsi; bool irq; bool intena; + bool level6; bool enabled; bool delayed_irq; bool configured; @@ -648,6 +659,10 @@ struct soft_scsi int databuffer_size; int db_read_index; int db_write_index; + + // sasi + bool active_select; + bool wait_select; }; @@ -729,6 +744,8 @@ static struct soft_scsi *getscsiboard(uaecptr addr) return s; if (s->baseaddress2 && (addr & ~s->board_mask) == s->baseaddress2) return s; + if (s->baseaddress == 0xe80000 && addr < 65536) + return s; } return NULL; } @@ -1198,10 +1215,24 @@ static void supra_do_dma(struct soft_scsi *ncr) } } +static void xebec_do_dma(struct soft_scsi *ncr) +{ + struct raw_scsi *rs = &ncr->rscsi; + while (rs->bus_phase == SCSI_SIGNAL_PHASE_DATA_OUT || rs->bus_phase == SCSI_SIGNAL_PHASE_DATA_IN) { + if (rs->bus_phase == SCSI_SIGNAL_PHASE_DATA_IN) { + x_put_byte(ncr->dmac_address, ncr5380_bget(ncr, 8)); + } else if (rs->bus_phase == SCSI_SIGNAL_PHASE_DATA_OUT) { + ncr5380_bput(ncr, 8, x_get_byte(ncr->dmac_address)); + } + } +} + + static void dma_check(struct soft_scsi *ncr) { if (ncr->dmac_active && ncr->dma_direction) { - if (ncr->type ==NCR5380_SUPRA && ncr->subtype == 4) { + + if (ncr->type == NCR5380_SUPRA && ncr->subtype == 4) { if (ncr->dmac_direction != ncr->dma_direction) { write_log(_T("SUPRADMA: mismatched direction\n")); ncr->dmac_active = 0; @@ -1209,6 +1240,12 @@ static void dma_check(struct soft_scsi *ncr) } supra_do_dma(ncr); } + + if (ncr->type == NCR5380_XEBEC) { + + xebec_do_dma(ncr); + + } ncr->dmac_active = 0; } } @@ -1219,7 +1256,10 @@ void ncr80_rethink(void) { for (int i = 0; soft_scsi_devices[i]; i++) { if (soft_scsi_devices[i]->irq && soft_scsi_devices[i]->intena) { - INTREQ_0(0x8000 | 0x0008); + if (soft_scsi_devices[i]->level6) + INTREQ_0(0x8000 | 0x2000); + else + INTREQ_0(0x8000 | 0x0008); return; } } @@ -1319,6 +1359,15 @@ uae_u8 ncr5380_bget(struct soft_scsi *scsi, int reg) if (scsi->dma_active && !scsi->dma_controller) { v |= 1 << 6; } + if (scsi->regs[2] & 4) { + // monitor busy + if (r->bus_phase == SCSI_SIGNAL_PHASE_FREE) { + // any loss of busy = Busy error + // not just "unexpected" loss of busy + v |= 1 << 2; + scsi->dmac_active = false; + } + } } break; case 0: @@ -1344,6 +1393,7 @@ void ncr5380_bput(struct soft_scsi *scsi, int reg, uae_u8 v) { if (reg > 8) return; + bool dataoutput = (scsi->regs[1] & 1) != 0; struct raw_scsi *r = &scsi->rscsi; uae_u8 old = scsi->regs[reg]; scsi->regs[reg] = v; @@ -1363,20 +1413,25 @@ void ncr5380_bput(struct soft_scsi *scsi, int reg, uae_u8 v) } break; case 1: - scsi->regs[reg] &= ~((1 << 5) | (1 << 6)); - scsi->regs[reg] |= old & ((1 << 5) | (1 << 6)); // AIP, LA - if (!(v & 0x80)) { - bool init = r->bus_phase < 0; - ncr5380_databusoutput(scsi); - raw_scsi_set_signal_phase(r, - (v & (1 << 3)) != 0, - (v & (1 << 2)) != 0, - (v & (1 << 1)) != 0); - if (!(scsi->regs[2] & 2)) - raw_scsi_set_ack(r, (v & (1 << 4)) != 0); - } - if (v & 0x80) { // RST - ncr5380_reset(scsi); + { + scsi->regs[reg] &= ~((1 << 5) | (1 << 6)); + scsi->regs[reg] |= old & ((1 << 5) | (1 << 6)); // AIP, LA + if (!(v & 0x80)) { + bool init = r->bus_phase < 0; + ncr5380_databusoutput(scsi); + if (init && !dataoutput && (v & 1) && (scsi->regs[2] & 1)) { + r->bus_phase = SCSI_SIGNAL_PHASE_SELECT_1; + } + raw_scsi_set_signal_phase(r, + (v & (1 << 3)) != 0, + (v & (1 << 2)) != 0, + (v & (1 << 1)) != 0); + if (!(scsi->regs[2] & 2)) + raw_scsi_set_ack(r, (v & (1 << 4)) != 0); + } + if (v & 0x80) { // RST + ncr5380_reset(scsi); + } } break; case 2: @@ -1403,7 +1458,7 @@ void ncr5380_bput(struct soft_scsi *scsi, int reg, uae_u8 v) dma_check(scsi); } #if NCR5380_DEBUG - write_log(_T("DMA send\n")); + write_log(_T("DMA send PC=%08x\n"), M68K_GETPC); #endif break; case 6: @@ -1412,7 +1467,7 @@ void ncr5380_bput(struct soft_scsi *scsi, int reg, uae_u8 v) scsi->dma_active = true; } #if NCR5380_DEBUG - write_log(_T("DMA target recv\n")); + write_log(_T("DMA target recv PC=%08x\n"), M68K_GETPC); #endif break; case 7: @@ -1422,7 +1477,7 @@ void ncr5380_bput(struct soft_scsi *scsi, int reg, uae_u8 v) dma_check(scsi); } #if NCR5380_DEBUG - write_log(_T("DMA initiator recv\n")); + write_log(_T("DMA initiator recv PC=%08x\n"), M68K_GETPC); #endif break; case 8: // fake dma port @@ -1523,6 +1578,143 @@ static void ncr53400_bput(struct soft_scsi *scsi, int reg, uae_u8 v) ncr5380_check_phase(scsi); } +/* SASI */ + +static uae_u8 sasi_tecmar_bget(struct soft_scsi *scsi, int reg) +{ + struct raw_scsi *rs = &scsi->rscsi; + uae_u8 v = 0; + + if (reg == 1) { + + uae_u8 t = raw_scsi_get_signal_phase(rs); + v = 0; + switch (rs->bus_phase) + { + case SCSI_SIGNAL_PHASE_DATA_OUT: + v = 0; + break; + case SCSI_SIGNAL_PHASE_DATA_IN: + v = 1 << 2; + break; + case SCSI_SIGNAL_PHASE_COMMAND: + v = 1 << 3; + break; + case SCSI_SIGNAL_PHASE_STATUS: + v = (1 << 2) | (1 << 3); + break; + case SCSI_SIGNAL_PHASE_MESSAGE_IN: + v = (1 << 2) | (1 << 3) | (1 << 4); + break; + } + if (t & SCSI_IO_BUSY) + v |= 1 << 1; + if (t & SCSI_IO_REQ) + v |= 1 << 0; + v = v ^ 0xff; + + } else { + + v = raw_scsi_get_data_2(rs, true, false); + + } + + //write_log(_T("SASI READ port %d: %02x\n"), reg, v); + + return v; +} + +static void sasi_tecmar_bput(struct soft_scsi *scsi, int reg, uae_u8 v) +{ + struct raw_scsi *rs = &scsi->rscsi; + + //write_log(_T("SASI WRITE port %d: %02x\n"), reg, v); + + if (reg == 1) { + if ((v & 1)) { + raw_scsi_busfree(rs); + } + if ((v & 2) && !scsi->active_select) { + // select? + scsi->active_select = true; + if (!rs->data_write) + scsi->wait_select = true; + else + raw_scsi_set_signal_phase(rs, false, true, false); + } else if (!(v & 2) && scsi->active_select) { + scsi->active_select = false; + raw_scsi_set_signal_phase(rs, false, false, false); + } + } else { + raw_scsi_put_data(rs, v, true); + if (scsi->wait_select && scsi->active_select) + raw_scsi_set_signal_phase(rs, false, true, false); + scsi->wait_select = false; + } +} + +static uae_u8 sasi_microforge_bget(struct soft_scsi *scsi, int reg) +{ + struct raw_scsi *rs = &scsi->rscsi; + uae_u8 v = 0; + + if (reg == 1) { + + uae_u8 t = raw_scsi_get_signal_phase(rs); + v = 0; + if (rs->bus_phase >= 0) { + if (rs->bus_phase & SCSI_IO_MESSAGE) + v |= 1 << 1; + if (rs->bus_phase & SCSI_IO_COMMAND) + v |= 1 << 2; + if (rs->bus_phase & SCSI_IO_DIRECTION) + v |= 1 << 3; + } + if (t & SCSI_IO_BUSY) + v |= 1 << 0; + if (t & SCSI_IO_REQ) + v |= 1 << 4; + v = v ^ 0xff; + + } + else { + + v = raw_scsi_get_data_2(rs, true, false); + + } + + //write_log(_T("SASI READ port %d: %02x\n"), reg, v); + + return v; +} + +static void sasi_microforge_bput(struct soft_scsi *scsi, int reg, uae_u8 v) +{ + struct raw_scsi *rs = &scsi->rscsi; + + //write_log(_T("SASI WRITE port %d: %02x\n"), reg, v); + + if (reg == 1) { + if ((v & 4) && !scsi->active_select) { + // select? + scsi->active_select = true; + if (!rs->data_write) + scsi->wait_select = true; + else + raw_scsi_set_signal_phase(rs, false, true, false); + } else if (!(v & 4) && scsi->active_select) { + scsi->active_select = false; + raw_scsi_set_signal_phase(rs, false, false, false); + } + } + else { + raw_scsi_put_data(rs, v, true); + if (scsi->wait_select && scsi->active_select) + raw_scsi_set_signal_phase(rs, false, true, false); + scsi->wait_select = false; + } +} + static int suprareg(struct soft_scsi *ncr, uaecptr addr, bool write) { int reg = (addr & 0x0f) >> 1; @@ -1601,6 +1793,52 @@ static int ptnexusreg(struct soft_scsi *ncr, uaecptr addr) return reg; } +static int xebec_reg(struct soft_scsi *ncr, uaecptr addr) +{ + if (addr < 0x10000) { + if (addr & 1) + return (addr & 0xff) >> 1; + return -1; + } + if ((addr & 0x180000) == 0x100000) { + + ncr->dmac_active = 1; + + } else if ((addr & 0x180000) == 0x180000) { + + ncr->dmac_active = 0; + ncr->dmac_address = ncr->baseaddress | 0x80000; + + } else if ((addr & 0x180000) == 0x080000) { + ncr->dmac_address = addr | ncr->baseaddress | 1; + ncr->dmac_address += 2; + if (addr & 1) + return 0x80000 + (addr & 32767); + return -1; + } + +// if (addr >= 0x10000) +// write_log(_T("XEBEC %08x PC=%08x\n"), addr, M68K_GETPC); + return -1; +} + + +static int microforge_reg(struct soft_scsi *ncr, uaecptr addr, bool write) +{ + int reg = -1; + if ((addr & 0x7000) != 0x7000) + return -1; + addr &= 0xfff; + if (addr == 38 && !write) + return 0; + if (addr == 40 && write) + return 0; + if (addr == 42 && !write) + return 1; + if (addr == 44 && write) + return 1; + return reg; +} static uae_u8 read_supra_dma(struct soft_scsi *ncr, uaecptr addr) { @@ -1667,13 +1905,81 @@ static void vector_scsi_status(struct raw_scsi *rs) } } +static int tecmar_clock_reg_select; +static uae_u8 tecmar_clock_regs[64]; +static uae_u8 tecmar_clock_bcd(uae_u8 v) +{ + uae_u8 out = v; + if (!(tecmar_clock_regs[11] & 4)) { + out = ((v / 10) << 4) + (v % 10); + } + return out; +} +static void tecmar_clock_bput(int addr, uae_u8 v) +{ + if (addr == 0) { + tecmar_clock_reg_select = v & 63; + } + else if (addr == 1) { + tecmar_clock_regs[tecmar_clock_reg_select] = v; + tecmar_clock_regs[12] = 0x00; + tecmar_clock_regs[13] = 0x80; + } +} +static uae_u8 tecmar_clock_bget(int addr) +{ + uae_u8 v = 0; + if (addr == 0) { + v = tecmar_clock_reg_select; + } + else if (addr == 1) { + time_t t = time(0); + t += currprefs.cs_rtc_adjust; + struct tm *ct = localtime(&t); + switch (tecmar_clock_reg_select) + { + case 0: + v = tecmar_clock_bcd(ct->tm_sec); + break; + case 2: + v = tecmar_clock_bcd(ct->tm_min); + break; + case 4: + v = tecmar_clock_bcd(ct->tm_hour); + if (!(tecmar_clock_regs[11] & 2)) { + if (v >= 12) { + v -= 12; + v |= 0x80; + } + v++; + } + break; + case 6: + v = tecmar_clock_bcd(ct->tm_wday + 1); + break; + case 7: + v = tecmar_clock_bcd(ct->tm_mday); + break; + case 8: + v = tecmar_clock_bcd(ct->tm_mon + 1); + break; + case 9: + v = tecmar_clock_bcd(ct->tm_year % 100); + break; + default: + v = tecmar_clock_regs[tecmar_clock_reg_select]; + break; + } + } + return v; +} static uae_u32 ncr80_bget2(struct soft_scsi *ncr, uaecptr addr, int size) { int reg = -1; uae_u32 v = 0; int addresstype = -1; - uaecptr origddr = addr; + uaecptr origaddr = addr; addr &= ncr->board_mask; @@ -1801,7 +2107,7 @@ static uae_u32 ncr80_bget2(struct soft_scsi *ncr, uaecptr addr, int size) struct raw_scsi *rs = &ncr->rscsi; if (addr & 0x8000) { v = ncr->rom[addr & 0x7fff]; - } else if ((origddr & 0xf00000) != 0xf00000) { + } else if ((origaddr & 0xf00000) != 0xf00000) { if (!(addr & 8)) { v = raw_scsi_get_data(rs, true); } else { @@ -1961,11 +2267,41 @@ static uae_u32 ncr80_bget2(struct soft_scsi *ncr, uaecptr addr, int size) reg = addr & 0xff; v = ncr5380_bget(ncr, reg); + } else if (ncr->type == NONCR_TECMAR) { + + v = ncr->rom[addr]; + if (addr >= 0x2000 && addr < 0x3000) { + if (addr == 0x2040) + v = tecmar_clock_bget(0); + else if (addr == 0x2042) + v = tecmar_clock_bget(1); + } else if (addr >= 0x4000 && addr < 0x5000) { + if (addr == 0x4040) + v = sasi_tecmar_bget(ncr, 1); + else if (addr == 0x4042) + v = sasi_tecmar_bget(ncr, 0); + } + + } else if (ncr->type == NCR5380_XEBEC) { + + reg = xebec_reg(ncr, addr); + if (reg >= 0 && reg < 8) { + v = ncr5380_bget(ncr, reg); + } else if (reg >= 0x80000) { + v = ncr->databufferptr[reg & (ncr->databuffer_size - 1)]; + } + + } else if (ncr->type == NONCR_MICROFORGE) { + + reg = microforge_reg(ncr, addr, false); + if (reg >= 0) + v = sasi_microforge_bget(ncr, reg); + } #if NCR5380_DEBUG > 1 //if (addr >= 0x8000) - write_log(_T("GET %08x %02x %d %08x %d\n"), addr, v, reg, M68K_GETPC, regs.intmask); + write_log(_T("GET %08x %02x %d %08x %d\n"), origaddr, v, reg, M68K_GETPC, regs.intmask); #endif return v; @@ -2131,10 +2467,54 @@ static void ncr80_bput2(struct soft_scsi *ncr, uaecptr addr, uae_u32 val, int si reg = addr & 0xff; ncr5380_bput(ncr, reg, val); + } else if (ncr->type == NONCR_TECMAR) { + + if (addr == 0x22) { + // box + ncr->baseaddress = 0xe80000 + ((val & 0x7f) * 4096); + map_banks_z2(ncr->bank, ncr->baseaddress >> 16, 1); + expamem_next(ncr->bank, NULL); + } else if (addr == 0x1020) { + // memory board control/status + ncr->rom[addr] = val & (0x80 | 0x40 | 0x02); + } else if (addr == 0x1024) { + // memory board memory address reg + if (currprefs.fastmem2_size) + map_banks_z2(&fastmem2_bank, val, currprefs.fastmem2_size >> 16); + } + else if (addr >= 0x2000 && addr < 0x3000) { + // clock + if (addr == 0x2040) + tecmar_clock_bput(0, val); + else if (addr == 0x2042) + tecmar_clock_bput(1, val); + } else if (addr >= 0x4000 && addr < 0x5000) { + // sasi + if (addr == 0x4040) + sasi_tecmar_bput(ncr, 1, val); + else if (addr == 0x4042) + sasi_tecmar_bput(ncr, 0, val); + } + + } else if (ncr->type == NCR5380_XEBEC) { + + reg = xebec_reg(ncr, addr); + if (reg >= 0 && reg < 8) { + ncr5380_bput(ncr, reg, val); + } else if (reg >= 0x80000) { + ncr->databufferptr[reg & (ncr->databuffer_size - 1)] = val; + } + + } else if (ncr->type == NONCR_MICROFORGE) { + + reg = microforge_reg(ncr, addr, true); + if (reg >= 0) + sasi_microforge_bput(ncr, reg, val); + } #if NCR5380_DEBUG > 1 - write_log(_T("PUT %08x %02x %d %08x %d\n"), addr, val, reg, M68K_GETPC, regs.intmask); + write_log(_T("PUT %08x %02x %d %08x %d\n"), origddr, val, reg, M68K_GETPC, regs.intmask); #endif } @@ -2639,6 +3019,133 @@ void dataflyer_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romco generic_soft_scsi_add(ch, ci, rc, NCR5380_DATAFLYER, 4096, 0, ROMTYPE_DATAFLYER); } +static void expansion_add_protoautoconfig_data(uae_u8 *p, uae_u16 manufacturer_id, uae_u8 product_id) +{ + memset(p, 0, 4096); + p[0x02] = product_id; + p[0x08] = manufacturer_id >> 8; + p[0x0a] = manufacturer_id; +} + +static void expansion_add_protoautoconfig_box(uae_u8 *p, int box_size, uae_u16 manufacturer_id, uae_u8 product_id) +{ + expansion_add_protoautoconfig_data(p, manufacturer_id, product_id); + // "box without init/diagnostics code" + p[0] = 0x40 | (box_size << 3); +} +static void expansion_add_protoautoconfig_board(uae_u8 *p, int board, uae_u16 manufacturer_id, uae_u8 product_id, int memorysize) +{ + p += (board + 1) * 4096; + expansion_add_protoautoconfig_data(p, manufacturer_id, product_id); + // "board without init/diagnostic code" + p[0] = 0x08; + if (memorysize) { + int v = 0; + switch (memorysize) + { + case 64 * 1024: + v = 1; + break; + case 128 * 1024: + v = 2; + break; + case 256 * 1024: + v = 3; + break; + case 512 * 1024: + v = 4; + break; + case 1024 * 1024: + v = 5; + break; + case 2048 * 1024: + v = 6; + break; + case 4096 * 1024: + default: + v = 7; + break; + } + p[0] |= v; + } +} + +addrbank *tecmar_init(struct romconfig *rc) +{ + struct soft_scsi *scsi = getscsi(rc); + int index = 0; + + if (!scsi) + return &expamem_null; + + const struct expansionromtype *ert = get_device_expansion_rom(ROMTYPE_PTNEXUS); + scsi->rom = xcalloc(uae_u8, 65536); + expansion_add_protoautoconfig_box(scsi->rom, 3, 1001, 0); + // memory + expansion_add_protoautoconfig_board(scsi->rom, index++, 1001, 1, currprefs.fastmem2_size); + // clock + expansion_add_protoautoconfig_board(scsi->rom, index++, 1001, 2, 0); + // serial + expansion_add_protoautoconfig_board(scsi->rom, index++, 1001, 3, 0); + // parallel + expansion_add_protoautoconfig_board(scsi->rom, index++, 1001, 4, 0); + // sasi + expansion_add_protoautoconfig_board(scsi->rom, index++, 1001, 4, 0); + memset(tecmar_clock_regs, 0, sizeof tecmar_clock_regs); + tecmar_clock_regs[11] = 0x04 | 0x02 | 0x01; + scsi->configured = true; + scsi->baseaddress = 0xe80000; + return scsi->bank; +} + +void tecmar_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc) +{ + generic_soft_scsi_add(ch, ci, rc, NONCR_TECMAR, 65536, 65536, ROMTYPE_TECMAR); +} + +addrbank *microforge_init(struct romconfig *rc) +{ + struct soft_scsi *scsi = getscsi(rc); + + if (!scsi) + return NULL; + + scsi->configured = 1; + + map_banks(scsi->bank, 0xef0000 >> 16, 0x10000 >> 16, 0); + scsi->baseaddress = 0xef0000; + return NULL; +} + +void microforge_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc) +{ + generic_soft_scsi_add(ch, ci, rc, NONCR_MICROFORGE, 65536, 0, ROMTYPE_MICROFORGE); +} + +addrbank *xebec_init(struct romconfig *rc) +{ + struct soft_scsi *scsi = getscsi(rc); + + if (!scsi) + return NULL; + + scsi->configured = 1; + + map_banks(scsi->bank, 0x600000 >> 16, (0x800000 - 0x600000) >> 16, 0); + scsi->board_mask = 0x1fffff; + scsi->baseaddress = 0x600000; + scsi->level6 = true; + scsi->intena = true; + scsi->dma_controller = true; + scsi->databuffer_size = 32768; + scsi->databufferptr = xcalloc(uae_u8, scsi->databuffer_size); + return NULL; +} + +void xebec_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc) +{ + generic_soft_scsi_add(ch, ci, rc, NCR5380_XEBEC, 65536, 0, ROMTYPE_XEBEC); +} void soft_scsi_free(void) {