From 8db289e229d07461972360a1c6e5e65b57c66329 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sun, 31 Jan 2021 13:12:59 -0500 Subject: [PATCH] Adds some notes-to-self on SCSI and a route to using Acorn's ADFS. --- Analyser/Static/Acorn/StaticAnalyser.cpp | 14 ++++-- Analyser/Static/Acorn/Target.hpp | 6 ++- Machines/Electron/Electron.cpp | 49 ++++++++++++++++--- .../StaticAnalyser/CSStaticAnalyser.mm | 2 +- ROMImages/Electron/readme.txt | 3 +- 5 files changed, 58 insertions(+), 16 deletions(-) diff --git a/Analyser/Static/Acorn/StaticAnalyser.cpp b/Analyser/Static/Acorn/StaticAnalyser.cpp index 76d655cfc..e37ffc7c8 100644 --- a/Analyser/Static/Acorn/StaticAnalyser.cpp +++ b/Analyser/Static/Acorn/StaticAnalyser.cpp @@ -61,10 +61,6 @@ static std::vector> Analyser::Static::TargetList Analyser::Static::Acorn::GetTargets(const Media &media, const std::string &, TargetPlatform::IntType) { auto target = std::make_unique(); - target->confidence = 0.5; // TODO: a proper estimation - target->has_dfs = false; - target->has_adfs = false; - target->should_shift_restart = false; // strip out inappropriate cartridges target->media.cartridges = AcornCartridgesFrom(media.cartridges); @@ -111,9 +107,10 @@ Analyser::Static::TargetList Analyser::Static::Acorn::GetTargets(const Media &me if(dfs_catalogue == nullptr) adfs_catalogue = GetADFSCatalogue(disk); if(dfs_catalogue || adfs_catalogue) { // Accept the disk and determine whether DFS or ADFS ROMs are implied. + // Use the Pres ADFS if using an ADFS, as it leaves Page at &EOO. target->media.disks = media.disks; target->has_dfs = bool(dfs_catalogue); - target->has_adfs = bool(adfs_catalogue); + target->has_pres_adfs = bool(adfs_catalogue); // Check whether a simple shift+break will do for loading this disk. Catalogue::BootOption bootOption = (dfs_catalogue ?: adfs_catalogue)->bootOption; @@ -144,6 +141,13 @@ Analyser::Static::TargetList Analyser::Static::Acorn::GetTargets(const Media &me } } + // Enable the Acorn ADFS if a mass-storage device is attached; + // unlike the Pres ADFS it retains SCSI logic. + if(!media.mass_storage_devices.empty()) { + target->has_pres_adfs = false; + target->has_acorn_adfs = true; + } + TargetList targets; if(!target->media.empty()) { targets.push_back(std::move(target)); diff --git a/Analyser/Static/Acorn/Target.hpp b/Analyser/Static/Acorn/Target.hpp index f415f4b30..17dad7393 100644 --- a/Analyser/Static/Acorn/Target.hpp +++ b/Analyser/Static/Acorn/Target.hpp @@ -18,7 +18,8 @@ namespace Static { namespace Acorn { struct Target: public ::Analyser::Static::Target, public Reflection::StructImpl { - bool has_adfs = false; + bool has_acorn_adfs = false; + bool has_pres_adfs = false; bool has_dfs = false; bool has_ap6_rom = false; bool has_sideways_ram = false; @@ -27,7 +28,8 @@ struct Target: public ::Analyser::Static::Target, public Reflection::StructImpl< Target() : Analyser::Static::Target(Machine::Electron) { if(needs_declare()) { - DeclareField(has_adfs); + DeclareField(has_pres_adfs); + DeclareField(has_acorn_adfs); DeclareField(has_dfs); DeclareField(has_ap6_rom); DeclareField(has_sideways_ram); diff --git a/Machines/Electron/Electron.cpp b/Machines/Electron/Electron.cpp index 4344e44a4..ad148b88f 100644 --- a/Machines/Electron/Electron.cpp +++ b/Machines/Electron/Electron.cpp @@ -64,10 +64,15 @@ class ConcreteMachine: {machine_name, "the Acorn BASIC II ROM", "basic.rom", 16*1024, 0x79434781}, {machine_name, "the Electron MOS ROM", "os.rom", 16*1024, 0xbf63fb1f} }; - if(target.has_adfs) { + const size_t pres_adfs_rom_position = required_roms.size(); + if(target.has_pres_adfs) { required_roms.emplace_back(machine_name, "the E00 ADFS ROM, first slot", "ADFS-E00_1.rom", 16*1024, 0x51523993); required_roms.emplace_back(machine_name, "the E00 ADFS ROM, second slot", "ADFS-E00_2.rom", 16*1024, 0x8d17de0e); } + const size_t acorn_adfs_rom_position = required_roms.size(); + if(target.has_acorn_adfs) { + required_roms.emplace_back(machine_name, "the Acorn ADFS ROM", "adfs.rom", 16*1024, 0x3289bdc6); + } const size_t dfs_rom_position = required_roms.size(); if(target.has_dfs) { required_roms.emplace_back(machine_name, "the 1770 DFS ROM", "DFS-1770-2.20.rom", 16*1024, 0xf3dc9bc5); @@ -91,19 +96,23 @@ class ConcreteMachine: * the keyboard and BASIC ROMs occupy slots 8, 9, 10 and 11; * the DFS, if in use, occupies slot 1; - * the ADFS, if in use, occupies slots 4 and 5; + * the Pres ADFS, if in use, occupies slots 4 and 5; + * the Acorn ADFS, if in use, occupies slot 6; * the AP6, if in use, occupies slot 15; and * if sideways RAM was asked for, all otherwise unused slots are populated with sideways RAM. */ - if(target.has_dfs || target.has_adfs) { + if(target.has_dfs || target.has_acorn_adfs || target.has_pres_adfs) { plus3_ = std::make_unique(); if(target.has_dfs) { set_rom(ROM::Slot0, *roms[dfs_rom_position], true); } - if(target.has_adfs) { - set_rom(ROM::Slot4, *roms[2], true); - set_rom(ROM::Slot5, *roms[3], true); + if(target.has_pres_adfs) { + set_rom(ROM::Slot4, *roms[pres_adfs_rom_position], true); + set_rom(ROM::Slot5, *roms[pres_adfs_rom_position+1], true); + } + if(target.has_acorn_adfs) { + set_rom(ROM::Slot6, *roms[acorn_adfs_rom_position], true); } } @@ -298,6 +307,7 @@ class ConcreteMachine: break; case 0xfc04: case 0xfc05: case 0xfc06: case 0xfc07: + printf("%04x %s %02x\n", address, isReadOperation(operation) ? "->" : "<-", *value); if(plus3_ && (address&0x00f0) == 0x00c0) { if(is_holding_shift_ && address == 0xfcc4) { is_holding_shift_ = false; @@ -310,12 +320,39 @@ class ConcreteMachine: } break; case 0xfc00: + printf("%04x %s %02x\n", address, isReadOperation(operation) ? "->" : "<-", *value); if(plus3_ && (address&0x00f0) == 0x00c0) { if(!isReadOperation(operation)) { plus3_->set_control_register(*value); } else *value = 1; } break; + case 0xfc03: + printf("%04x %s %02x\n", address, isReadOperation(operation) ? "->" : "<-", *value); + break; + + // SCSI locations: + // + // fc40: data, read and write + // fc41: status read + // fc42: select write + // fc43: interrupt latch + // + // Status byte is: + // + // b7: SCSI C/D + // b6: SCSI I/O + // b5: SCSI REQ + // b4: interrupt flag + // b3: 0 + // b2: 0 + // b1: SCSI BSY + // b0: SCSI MSG + // + // Interrupt latch is: + // + // b0: enable or disable IRQ on REQ + // (and, possibly, writing to the latch acknowledges?) default: if(address >= 0xc000) { diff --git a/OSBindings/Mac/Clock Signal/Machine/StaticAnalyser/CSStaticAnalyser.mm b/OSBindings/Mac/Clock Signal/Machine/StaticAnalyser/CSStaticAnalyser.mm index 71eb87247..a302b5f3c 100644 --- a/OSBindings/Mac/Clock Signal/Machine/StaticAnalyser/CSStaticAnalyser.mm +++ b/OSBindings/Mac/Clock Signal/Machine/StaticAnalyser/CSStaticAnalyser.mm @@ -99,7 +99,7 @@ using Target = Analyser::Static::Acorn::Target; auto target = std::make_unique(); target->has_dfs = dfs; - target->has_adfs = adfs; + target->has_pres_adfs = adfs; target->has_ap6_rom = ap6; target->has_sideways_ram = sidewaysRAM; _targets.push_back(std::move(target)); diff --git a/ROMImages/Electron/readme.txt b/ROMImages/Electron/readme.txt index 995145ee9..349144e2a 100644 --- a/ROMImages/Electron/readme.txt +++ b/ROMImages/Electron/readme.txt @@ -8,10 +8,9 @@ DFS-1770-2.20.rom — used only if the user opens a DFS disk image ADFS-E00_1.rom — used only if the user opens an ADFS disk image ADFS-E00_2.rom AP6v133.rom — used only if the user opens a disk image that makes use of any of the commands given below. +adfs.rom - used only if the user opens a hard disk image Possibly to be desired in the future: -* adfs.rom -* ElectronExpansionRomPresAP2-v1.23.rom * os300.rom Commands that trigger a request for the AP6v133 ROM: