From 78eaecb29e67f203b55e66c2a89675ab3aa1d56a Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Fri, 9 Mar 2018 15:36:11 -0500 Subject: [PATCH 1/3] Provides the proper framework for encapsulation of analyser target specifics. ... while making them a safe container for objects too. Uses the ZX80/81 as the pilot platform. --- .../MultiConfigurationTarget.cpp | 2 +- .../MultiConfigurationTarget.hpp | 2 +- Analyser/Static/StaticAnalyser.hpp | 13 ++------ Analyser/Static/ZX8081/StaticAnalyser.cpp | 19 ++++++----- Analyser/Static/ZX8081/Target.hpp | 33 +++++++++++++++++++ Machines/AmstradCPC/AmstradCPC.cpp | 10 +++--- Machines/Atari2600/Atari2600.cpp | 12 +++---- Machines/ColecoVision/ColecoVision.cpp | 4 +-- Machines/Commodore/Vic-20/Vic20.cpp | 12 +++---- Machines/ConfigurationTarget.hpp | 2 +- Machines/Electron/Electron.cpp | 16 ++++----- Machines/MSX/MSX.cpp | 10 +++--- Machines/Oric/Oric.cpp | 12 +++---- Machines/Utility/MachineForTarget.cpp | 8 ++--- Machines/ZX8081/ZX8081.cpp | 28 +++++++++------- Machines/ZX8081/ZX8081.hpp | 2 +- .../Clock Signal.xcodeproj/project.pbxproj | 2 ++ 17 files changed, 110 insertions(+), 77 deletions(-) create mode 100644 Analyser/Static/ZX8081/Target.hpp diff --git a/Analyser/Dynamic/MultiMachine/Implementation/MultiConfigurationTarget.cpp b/Analyser/Dynamic/MultiMachine/Implementation/MultiConfigurationTarget.cpp index b4d8a7192..e8d3e09bf 100644 --- a/Analyser/Dynamic/MultiMachine/Implementation/MultiConfigurationTarget.cpp +++ b/Analyser/Dynamic/MultiMachine/Implementation/MultiConfigurationTarget.cpp @@ -17,7 +17,7 @@ MultiConfigurationTarget::MultiConfigurationTarget(const std::vector> &machines); // Below is the standard ConfigurationTarget::Machine interface; see there for documentation. - void configure_as_target(const Analyser::Static::Target &target) override; + void configure_as_target(const Analyser::Static::Target *target) override; bool insert_media(const Analyser::Static::Media &media) override; private: diff --git a/Analyser/Static/StaticAnalyser.hpp b/Analyser/Static/StaticAnalyser.hpp index 3a679c0a8..cc9107881 100644 --- a/Analyser/Static/StaticAnalyser.hpp +++ b/Analyser/Static/StaticAnalyser.hpp @@ -42,12 +42,6 @@ enum class Atari2600PagingModel { Pitfall2 }; -enum class ZX8081MemoryModel { - Unexpanded, - SixteenKB, - SixtyFourKB -}; - enum class AmstradCPCModel { CPC464, CPC664, @@ -72,6 +66,8 @@ struct Media { and instructions on how to launch the software attached, plus a measure of confidence in this target's correctness. */ struct Target { + virtual ~Target() {} + Machine machine; Media media; @@ -102,11 +98,6 @@ struct Target { bool has_c1540; } vic20; - struct { - ZX8081MemoryModel memory_model; - bool isZX81; - } zx8081; - struct { AmstradCPCModel model; } amstradcpc; diff --git a/Analyser/Static/ZX8081/StaticAnalyser.cpp b/Analyser/Static/ZX8081/StaticAnalyser.cpp index 266b4c9df..4ee957325 100644 --- a/Analyser/Static/ZX8081/StaticAnalyser.cpp +++ b/Analyser/Static/ZX8081/StaticAnalyser.cpp @@ -11,6 +11,7 @@ #include #include +#include "Target.hpp" #include "../../../Storage/Tape/Parsers/ZX8081.hpp" static std::vector GetFiles(const std::shared_ptr &tape) { @@ -27,41 +28,41 @@ static std::vector GetFiles(const std::shared_ptr> &destination, TargetPlatform::IntType potential_platforms) { +void Analyser::Static::ZX8081::AddTargets(const Media &media, std::vector> &destination, TargetPlatform::IntType potential_platforms) { if(!media.tapes.empty()) { std::vector files = GetFiles(media.tapes.front()); media.tapes.front()->reset(); if(!files.empty()) { - std::unique_ptr target(new Target); + Target *target = new Target; + destination.push_back(std::unique_ptr<::Analyser::Static::Target>(target)); target->machine = Machine::ZX8081; // Guess the machine type from the file only if it isn't already known. switch(potential_platforms & (TargetPlatform::ZX80 | TargetPlatform::ZX81)) { default: - target->zx8081.isZX81 = files.front().isZX81; + target->isZX81 = files.front().isZX81; break; - case TargetPlatform::ZX80: target->zx8081.isZX81 = false; break; - case TargetPlatform::ZX81: target->zx8081.isZX81 = true; break; + case TargetPlatform::ZX80: target->isZX81 = false; break; + case TargetPlatform::ZX81: target->isZX81 = true; break; } /*if(files.front().data.size() > 16384) { target->zx8081.memory_model = ZX8081MemoryModel::SixtyFourKB; } else*/ if(files.front().data.size() > 1024) { - target->zx8081.memory_model = ZX8081MemoryModel::SixteenKB; + target->memory_model = Target::MemoryModel::SixteenKB; } else { - target->zx8081.memory_model = ZX8081MemoryModel::Unexpanded; + target->memory_model = Target::MemoryModel::Unexpanded; } target->media.tapes = media.tapes; // TODO: how to run software once loaded? Might require a BASIC detokeniser. - if(target->zx8081.isZX81) { + if(target->isZX81) { target->loading_command = "J\"\"\n"; } else { target->loading_command = "W\n"; } - destination.push_back(std::move(target)); } } } diff --git a/Analyser/Static/ZX8081/Target.hpp b/Analyser/Static/ZX8081/Target.hpp new file mode 100644 index 000000000..180282576 --- /dev/null +++ b/Analyser/Static/ZX8081/Target.hpp @@ -0,0 +1,33 @@ +// +// Target.hpp +// Clock Signal +// +// Created by Thomas Harte on 09/03/2018. +// Copyright © 2018 Thomas Harte. All rights reserved. +// + +#ifndef Target_h +#define Target_h + +#include "../StaticAnalyser.hpp" + +namespace Analyser { +namespace Static { +namespace ZX8081 { + +struct Target: public ::Analyser::Static::Target { + enum class MemoryModel { + Unexpanded, + SixteenKB, + SixtyFourKB + }; + + MemoryModel memory_model; + bool isZX81; +}; + +} +} +} + +#endif /* Target_h */ diff --git a/Machines/AmstradCPC/AmstradCPC.cpp b/Machines/AmstradCPC/AmstradCPC.cpp index d93aeef79..b81b852ba 100644 --- a/Machines/AmstradCPC/AmstradCPC.cpp +++ b/Machines/AmstradCPC/AmstradCPC.cpp @@ -874,8 +874,8 @@ class ConcreteMachine: } /// The ConfigurationTarget entry point; should configure this meachine as described by @c target. - void configure_as_target(const Analyser::Static::Target &target) override final { - switch(target.amstradcpc.model) { + void configure_as_target(const Analyser::Static::Target *target) override final { + switch(target->amstradcpc.model) { case Analyser::Static::AmstradCPCModel::CPC464: rom_model_ = ROMType::OS464; has_128k_ = false; @@ -908,11 +908,11 @@ class ConcreteMachine: read_pointers_[3] = roms_[upper_rom_].data(); // Type whatever is required. - if(target.loading_command.length()) { - type_string(target.loading_command); + if(target->loading_command.length()) { + type_string(target->loading_command); } - insert_media(target.media); + insert_media(target->media); } bool insert_media(const Analyser::Static::Media &media) override final { diff --git a/Machines/Atari2600/Atari2600.cpp b/Machines/Atari2600/Atari2600.cpp index ed969863c..181a57bdd 100644 --- a/Machines/Atari2600/Atari2600.cpp +++ b/Machines/Atari2600/Atari2600.cpp @@ -89,9 +89,9 @@ class ConcreteMachine: close_output(); } - void configure_as_target(const Analyser::Static::Target &target) override { - const std::vector &rom = target.media.cartridges.front()->get_segments().front().data; - switch(target.atari.paging_model) { + void configure_as_target(const Analyser::Static::Target *target) override { + const std::vector &rom = target->media.cartridges.front()->get_segments().front().data; + switch(target->atari.paging_model) { case Analyser::Static::Atari2600PagingModel::ActivisionStack: bus_.reset(new Cartridge::Cartridge(rom)); break; case Analyser::Static::Atari2600PagingModel::CBSRamPlus: bus_.reset(new Cartridge::Cartridge(rom)); break; case Analyser::Static::Atari2600PagingModel::CommaVid: bus_.reset(new Cartridge::Cartridge(rom)); break; @@ -103,21 +103,21 @@ class ConcreteMachine: case Analyser::Static::Atari2600PagingModel::Tigervision: bus_.reset(new Cartridge::Cartridge(rom)); break; case Analyser::Static::Atari2600PagingModel::Atari8k: - if(target.atari.uses_superchip) { + if(target->atari.uses_superchip) { bus_.reset(new Cartridge::Cartridge(rom)); } else { bus_.reset(new Cartridge::Cartridge(rom)); } break; case Analyser::Static::Atari2600PagingModel::Atari16k: - if(target.atari.uses_superchip) { + if(target->atari.uses_superchip) { bus_.reset(new Cartridge::Cartridge(rom)); } else { bus_.reset(new Cartridge::Cartridge(rom)); } break; case Analyser::Static::Atari2600PagingModel::Atari32k: - if(target.atari.uses_superchip) { + if(target->atari.uses_superchip) { bus_.reset(new Cartridge::Cartridge(rom)); } else { bus_.reset(new Cartridge::Cartridge(rom)); diff --git a/Machines/ColecoVision/ColecoVision.cpp b/Machines/ColecoVision/ColecoVision.cpp index da62dda4f..f238637a3 100644 --- a/Machines/ColecoVision/ColecoVision.cpp +++ b/Machines/ColecoVision/ColecoVision.cpp @@ -150,9 +150,9 @@ class ConcreteMachine: z80_.run_for(cycles); } - void configure_as_target(const Analyser::Static::Target &target) override { + void configure_as_target(const Analyser::Static::Target *target) override { // Insert the media. - insert_media(target.media); + insert_media(target->media); } bool insert_media(const Analyser::Static::Media &media) override { diff --git a/Machines/Commodore/Vic-20/Vic20.cpp b/Machines/Commodore/Vic-20/Vic20.cpp index 1aeb6d1df..11e99f5e7 100644 --- a/Machines/Commodore/Vic-20/Vic20.cpp +++ b/Machines/Commodore/Vic-20/Vic20.cpp @@ -363,12 +363,12 @@ class ConcreteMachine: return true; } - void configure_as_target(const Analyser::Static::Target &target) override final { - if(target.loading_command.length()) { - type_string(target.loading_command); + void configure_as_target(const Analyser::Static::Target *target) override final { + if(target->loading_command.length()) { + type_string(target->loading_command); } - switch(target.vic20.memory_model) { + switch(target->vic20.memory_model) { case Analyser::Static::Vic20MemoryModel::Unexpanded: set_memory_size(Default); break; @@ -380,7 +380,7 @@ class ConcreteMachine: break; } - if(target.media.disks.size()) { + if(target->media.disks.size()) { // construct the 1540 c1540_.reset(new ::Commodore::C1540::Machine(Commodore::C1540::Machine::C1540)); @@ -391,7 +391,7 @@ class ConcreteMachine: c1540_->set_rom_fetcher(rom_fetcher_); } - insert_media(target.media); + insert_media(target->media); } bool insert_media(const Analyser::Static::Media &media) override final { diff --git a/Machines/ConfigurationTarget.hpp b/Machines/ConfigurationTarget.hpp index 600f76730..05cbaa3f2 100644 --- a/Machines/ConfigurationTarget.hpp +++ b/Machines/ConfigurationTarget.hpp @@ -23,7 +23,7 @@ namespace ConfigurationTarget { class Machine { public: /// Instructs the machine to configure itself as described by @c target and insert the included media. - virtual void configure_as_target(const Analyser::Static::Target &target) = 0; + virtual void configure_as_target(const Analyser::Static::Target *target) = 0; /*! Requests that the machine insert @c media as a modification to current state diff --git a/Machines/Electron/Electron.cpp b/Machines/Electron/Electron.cpp index 3e98f5131..aeb7e927b 100644 --- a/Machines/Electron/Electron.cpp +++ b/Machines/Electron/Electron.cpp @@ -123,28 +123,28 @@ class ConcreteMachine: if(is_holding_shift_) set_key_state(KeyShift, true); } - void configure_as_target(const Analyser::Static::Target &target) override final { - if(target.loading_command.length()) { - type_string(target.loading_command); + void configure_as_target(const Analyser::Static::Target *target) override final { + if(target->loading_command.length()) { + type_string(target->loading_command); } - if(target.acorn.should_shift_restart) { + if(target->acorn.should_shift_restart) { shift_restart_counter_ = 1000000; } - if(target.acorn.has_dfs || target.acorn.has_adfs) { + if(target->acorn.has_dfs || target->acorn.has_adfs) { plus3_.reset(new Plus3); - if(target.acorn.has_dfs) { + if(target->acorn.has_dfs) { set_rom(ROMSlot0, dfs_, true); } - if(target.acorn.has_adfs) { + if(target->acorn.has_adfs) { set_rom(ROMSlot4, adfs1_, true); set_rom(ROMSlot5, adfs2_, true); } } - insert_media(target.media); + insert_media(target->media); } bool insert_media(const Analyser::Static::Media &media) override final { diff --git a/Machines/MSX/MSX.cpp b/Machines/MSX/MSX.cpp index a927c4cb5..cec831d93 100644 --- a/Machines/MSX/MSX.cpp +++ b/Machines/MSX/MSX.cpp @@ -178,20 +178,20 @@ class ConcreteMachine: } } - void configure_as_target(const Analyser::Static::Target &target) override { + void configure_as_target(const Analyser::Static::Target *target) override { // Add a disk cartridge if any disks were supplied. - if(!target.media.disks.empty()) { + if(!target->media.disks.empty()) { map(2, 0, 0x4000, 0x2000); unmap(2, 0x6000, 0x2000); memory_slots_[2].set_handler(new DiskROM(memory_slots_[2].source)); } // Insert the media. - insert_media(target.media); + insert_media(target->media); // Type whatever has been requested. - if(target.loading_command.length()) { - type_string(target.loading_command); + if(target->loading_command.length()) { + type_string(target->loading_command); } } diff --git a/Machines/Oric/Oric.cpp b/Machines/Oric/Oric.cpp index abe91ff74..172fe6f28 100644 --- a/Machines/Oric/Oric.cpp +++ b/Machines/Oric/Oric.cpp @@ -262,18 +262,18 @@ class ConcreteMachine: } // to satisfy ConfigurationTarget::Machine - void configure_as_target(const Analyser::Static::Target &target) override final { - if(target.oric.has_microdisc) { + void configure_as_target(const Analyser::Static::Target *target) override final { + if(target->oric.has_microdisc) { microdisc_is_enabled_ = true; microdisc_did_change_paging_flags(µdisc_); microdisc_.set_delegate(this); } - if(target.loading_command.length()) { - type_string(target.loading_command); + if(target->loading_command.length()) { + type_string(target->loading_command); } - if(target.oric.use_atmos_rom) { + if(target->oric.use_atmos_rom) { std::memcpy(rom_, basic11_rom_.data(), std::min(basic11_rom_.size(), sizeof(rom_))); is_using_basic11_ = true; @@ -289,7 +289,7 @@ class ConcreteMachine: tape_speed_address_ = 0x67; } - insert_media(target.media); + insert_media(target->media); } bool insert_media(const Analyser::Static::Media &media) override final { diff --git a/Machines/Utility/MachineForTarget.cpp b/Machines/Utility/MachineForTarget.cpp index 7ec719686..294b8663e 100644 --- a/Machines/Utility/MachineForTarget.cpp +++ b/Machines/Utility/MachineForTarget.cpp @@ -22,10 +22,10 @@ namespace { -::Machine::DynamicMachine *MachineForTarget(const Analyser::Static::Target &target, const ROMMachine::ROMFetcher &rom_fetcher, Machine::Error &error) { +::Machine::DynamicMachine *MachineForTarget(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher, Machine::Error &error) { error = Machine::Error::None; ::Machine::DynamicMachine *machine = nullptr; - switch(target.machine) { + switch(target->machine) { case Analyser::Machine::AmstradCPC: machine = new Machine::TypedDynamicMachine(AmstradCPC::Machine::AmstradCPC()); break; case Analyser::Machine::Atari2600: machine = new Machine::TypedDynamicMachine(Atari2600::Machine::Atari2600()); break; case Analyser::Machine::ColecoVision: machine = new Machine::TypedDynamicMachine(Coleco::Vision::Machine::ColecoVision()); break; @@ -71,7 +71,7 @@ namespace { if(targets.size() > 1) { std::vector> machines; for(const auto &target: targets) { - machines.emplace_back(MachineForTarget(*target, rom_fetcher, error)); + machines.emplace_back(MachineForTarget(target.get(), rom_fetcher, error)); // Exit early if any errors have occurred. if(error != Error::None) { @@ -89,7 +89,7 @@ namespace { } // There's definitely exactly one target. - return MachineForTarget(*targets.front(), rom_fetcher, error); + return MachineForTarget(targets.front().get(), rom_fetcher, error); } std::string Machine::ShortNameForTargetMachine(const Analyser::Machine machine) { diff --git a/Machines/ZX8081/ZX8081.cpp b/Machines/ZX8081/ZX8081.cpp index c10d3b27c..7d80d2fc1 100644 --- a/Machines/ZX8081/ZX8081.cpp +++ b/Machines/ZX8081/ZX8081.cpp @@ -25,6 +25,8 @@ #include "../../Outputs/Speaker/Implementation/LowpassSpeaker.hpp" +#include "../../Analyser/Static/ZX8081/Target.hpp" + #include "Keyboard.hpp" #include "Video.hpp" @@ -277,8 +279,10 @@ template class ConcreteMachine: z80_.run_for(cycles); } - void configure_as_target(const Analyser::Static::Target &target) override final { - is_zx81_ = target.zx8081.isZX81; + void configure_as_target(const Analyser::Static::Target *target) override final { + const Analyser::Static::ZX8081::Target *const zx8081_target = + dynamic_cast(target); + is_zx81_ = zx8081_target->isZX81; if(is_zx81_) { rom_ = zx81_rom_; tape_trap_address_ = 0x37c; @@ -298,18 +302,18 @@ template class ConcreteMachine: } rom_mask_ = static_cast(rom_.size() - 1); - switch(target.zx8081.memory_model) { - case Analyser::Static::ZX8081MemoryModel::Unexpanded: + switch(zx8081_target->memory_model) { + case Analyser::Static::ZX8081::Target::MemoryModel::Unexpanded: ram_.resize(1024); ram_base_ = 16384; ram_mask_ = 1023; break; - case Analyser::Static::ZX8081MemoryModel::SixteenKB: + case Analyser::Static::ZX8081::Target::MemoryModel::SixteenKB: ram_.resize(16384); ram_base_ = 16384; ram_mask_ = 16383; break; - case Analyser::Static::ZX8081MemoryModel::SixtyFourKB: + case Analyser::Static::ZX8081::Target::MemoryModel::SixtyFourKB: ram_.resize(65536); ram_base_ = 8192; ram_mask_ = 65535; @@ -317,11 +321,11 @@ template class ConcreteMachine: } Memory::Fuzz(ram_); - if(target.loading_command.length()) { - type_string(target.loading_command); + if(target->loading_command.length()) { + type_string(target->loading_command); } - insert_media(target.media); + insert_media(target->media); } bool insert_media(const Analyser::Static::Media &media) override final { @@ -517,9 +521,11 @@ template class ConcreteMachine: using namespace ZX8081; // See header; constructs and returns an instance of the ZX80 or 81. -Machine *Machine::ZX8081(const Analyser::Static::Target &target_hint) { +Machine *Machine::ZX8081(const Analyser::Static::Target *target_hint) { + const Analyser::Static::ZX8081::Target *const hint = dynamic_cast(target_hint); + // Instantiate the correct type of machine. - if(target_hint.zx8081.isZX81) + if(hint->isZX81) return new ZX8081::ConcreteMachine(); else return new ZX8081::ConcreteMachine(); diff --git a/Machines/ZX8081/ZX8081.hpp b/Machines/ZX8081/ZX8081.hpp index b04a317a8..cbe1615eb 100644 --- a/Machines/ZX8081/ZX8081.hpp +++ b/Machines/ZX8081/ZX8081.hpp @@ -21,7 +21,7 @@ class Machine { public: virtual ~Machine(); - static Machine *ZX8081(const Analyser::Static::Target &target_hint); + static Machine *ZX8081(const Analyser::Static::Target *target_hint); virtual void set_tape_is_playing(bool is_playing) = 0; virtual bool get_tape_is_playing() = 0; diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index 0bc7b7618..f912171d9 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -1330,6 +1330,7 @@ 4BD9137D1F311BC5009BCF85 /* i8255.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = i8255.hpp; path = 8255/i8255.hpp; sourceTree = ""; }; 4BDCC5F81FB27A5E001220C5 /* ROMMachine.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ROMMachine.hpp; sourceTree = ""; }; 4BDDBA981EF3451200347E61 /* Z80MachineCycleTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Z80MachineCycleTests.swift; sourceTree = ""; }; + 4BE3231220532443006EF799 /* Target.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Target.hpp; sourceTree = ""; }; 4BE7C9161E3D397100A5496D /* TIA.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TIA.cpp; sourceTree = ""; }; 4BE7C9171E3D397100A5496D /* TIA.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = TIA.hpp; sourceTree = ""; }; 4BE845201F2FF7F100A5EA22 /* CRTC6845.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = CRTC6845.hpp; path = 6845/CRTC6845.hpp; sourceTree = ""; }; @@ -2208,6 +2209,7 @@ children = ( 4B894506201967B4007DE474 /* StaticAnalyser.cpp */, 4B894505201967B4007DE474 /* StaticAnalyser.hpp */, + 4BE3231220532443006EF799 /* Target.hpp */, ); path = ZX8081; sourceTree = ""; From 89bec2919fcdd28863a9f2cbb6a6014a6fa75f89 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Fri, 9 Mar 2018 16:07:29 -0500 Subject: [PATCH 2/3] Encapsulates machine configuration properties for all remaining platforms. --- Analyser/Static/Acorn/StaticAnalyser.cpp | 18 +++--- Analyser/Static/Acorn/Target.hpp | 28 ++++++++++ Analyser/Static/AmstradCPC/StaticAnalyser.cpp | 10 ++-- Analyser/Static/Atari/StaticAnalyser.cpp | 54 +++++++++--------- Analyser/Static/Atari/Target.hpp | 43 ++++++++++++++ Analyser/Static/Commodore/StaticAnalyser.cpp | 15 ++--- Analyser/Static/Oric/StaticAnalyser.cpp | 11 ++-- Analyser/Static/Oric/Target.hpp | 25 +++++++++ Analyser/Static/StaticAnalyser.hpp | 56 ------------------- Machines/AmstradCPC/AmstradCPC.cpp | 12 ++-- Machines/Atari2600/Atari2600.cpp | 37 ++++++------ Machines/Commodore/Vic-20/Vic20.cpp | 12 ++-- Machines/Electron/Electron.cpp | 11 ++-- Machines/Oric/Oric.cpp | 8 ++- Machines/ZX8081/ZX8081.cpp | 3 +- .../Clock Signal.xcodeproj/project.pbxproj | 10 ++++ 16 files changed, 215 insertions(+), 138 deletions(-) create mode 100644 Analyser/Static/Acorn/Target.hpp create mode 100644 Analyser/Static/Atari/Target.hpp create mode 100644 Analyser/Static/Oric/Target.hpp diff --git a/Analyser/Static/Acorn/StaticAnalyser.cpp b/Analyser/Static/Acorn/StaticAnalyser.cpp index 3b2eed51e..5942d7fc9 100644 --- a/Analyser/Static/Acorn/StaticAnalyser.cpp +++ b/Analyser/Static/Acorn/StaticAnalyser.cpp @@ -10,6 +10,7 @@ #include "Disk.hpp" #include "Tape.hpp" +#include "Target.hpp" using namespace Analyser::Static::Acorn; @@ -56,13 +57,13 @@ static std::vector> return acorn_cartridges; } -void Analyser::Static::Acorn::AddTargets(const Media &media, std::vector> &destination) { +void Analyser::Static::Acorn::AddTargets(const Media &media, std::vector> &destination) { std::unique_ptr target(new Target); target->machine = Machine::Electron; target->confidence = 0.5; // TODO: a proper estimation - target->acorn.has_dfs = false; - target->acorn.has_adfs = false; - target->acorn.should_shift_restart = false; + target->has_dfs = false; + target->has_adfs = false; + target->should_shift_restart = false; // strip out inappropriate cartridges target->media.cartridges = AcornCartridgesFrom(media.cartridges); @@ -109,17 +110,18 @@ void Analyser::Static::Acorn::AddTargets(const Media &media, std::vectormedia.disks = media.disks; - target->acorn.has_dfs = !!dfs_catalogue; - target->acorn.has_adfs = !!adfs_catalogue; + target->has_dfs = !!dfs_catalogue; + target->has_adfs = !!adfs_catalogue; Catalogue::BootOption bootOption = (dfs_catalogue ?: adfs_catalogue)->bootOption; if(bootOption != Catalogue::BootOption::None) - target->acorn.should_shift_restart = true; + target->should_shift_restart = true; else target->loading_command = "*CAT\n"; } } - if(target->media.tapes.size() || target->media.disks.size() || target->media.cartridges.size()) + if(target->media.tapes.size() || target->media.disks.size() || target->media.cartridges.size()) { destination.push_back(std::move(target)); + } } diff --git a/Analyser/Static/Acorn/Target.hpp b/Analyser/Static/Acorn/Target.hpp new file mode 100644 index 000000000..e247f7bfc --- /dev/null +++ b/Analyser/Static/Acorn/Target.hpp @@ -0,0 +1,28 @@ +// +// Target.hpp +// Clock Signal +// +// Created by Thomas Harte on 09/03/2018. +// Copyright © 2018 Thomas Harte. All rights reserved. +// + +#ifndef Target_h +#define Target_h + +#include "../StaticAnalyser.hpp" + +namespace Analyser { +namespace Static { +namespace Acorn { + +struct Target: public ::Analyser::Static::Target { + bool has_adfs; + bool has_dfs; + bool should_shift_restart; +}; + +} +} +} + +#endif /* Target_h */ diff --git a/Analyser/Static/AmstradCPC/StaticAnalyser.cpp b/Analyser/Static/AmstradCPC/StaticAnalyser.cpp index 19438df8d..6eaaecd8f 100644 --- a/Analyser/Static/AmstradCPC/StaticAnalyser.cpp +++ b/Analyser/Static/AmstradCPC/StaticAnalyser.cpp @@ -11,6 +11,8 @@ #include #include +#include "Target.hpp" + #include "../../../Storage/Disk/Parsers/CPM.hpp" #include "../../../Storage/Disk/Encodings/MFM/Parser.hpp" @@ -58,7 +60,7 @@ static std::string RunCommandFor(const Storage::Disk::CPM::File &file) { static void InspectCatalogue( const Storage::Disk::CPM::Catalogue &catalogue, - const std::unique_ptr &target) { + const std::unique_ptr &target) { std::vector candidate_files; candidate_files.reserve(catalogue.files.size()); @@ -153,7 +155,7 @@ static void InspectCatalogue( target->loading_command = "cat\n"; } -static bool CheckBootSector(const std::shared_ptr &disk, const std::unique_ptr &target) { +static bool CheckBootSector(const std::shared_ptr &disk, const std::unique_ptr &target) { Storage::Encodings::MFM::Parser parser(true, disk); Storage::Encodings::MFM::Sector *boot_sector = parser.get_sector(0, 0, 0x41); if(boot_sector != nullptr && !boot_sector->samples.empty()) { @@ -177,7 +179,7 @@ static bool CheckBootSector(const std::shared_ptr &disk, co return false; } -void Analyser::Static::AmstradCPC::AddTargets(const Media &media, std::vector> &destination) { +void Analyser::Static::AmstradCPC::AddTargets(const Media &media, std::vector> &destination) { std::unique_ptr target(new Target); target->machine = Machine::AmstradCPC; target->confidence = 0.5; @@ -185,7 +187,7 @@ void Analyser::Static::AmstradCPC::AddTargets(const Media &media, std::vectormedia.tapes = media.tapes; target->media.cartridges = media.cartridges; - target->amstradcpc.model = AmstradCPCModel::CPC6128; + target->model = Target::Model::CPC6128; if(!target->media.tapes.empty()) { // Ugliness flows here: assume the CPC isn't smart enough to pause between pressing diff --git a/Analyser/Static/Atari/StaticAnalyser.cpp b/Analyser/Static/Atari/StaticAnalyser.cpp index 59b92614f..206fe1f77 100644 --- a/Analyser/Static/Atari/StaticAnalyser.cpp +++ b/Analyser/Static/Atari/StaticAnalyser.cpp @@ -8,11 +8,13 @@ #include "StaticAnalyser.hpp" +#include "Target.hpp" + #include "../Disassembler/6502.hpp" using namespace Analyser::Static::Atari; -static void DeterminePagingFor2kCartridge(Analyser::Static::Target &target, const Storage::Cartridge::Cartridge::Segment &segment) { +static void DeterminePagingFor2kCartridge(Analyser::Static::Atari::Target &target, const Storage::Cartridge::Cartridge::Segment &segment) { // if this is a 2kb cartridge then it's definitely either unpaged or a CommaVid uint16_t entry_address, break_address; @@ -46,10 +48,10 @@ static void DeterminePagingFor2kCartridge(Analyser::Static::Target &target, cons // caveat: false positives aren't likely to be problematic; a false positive is a 2KB ROM that always addresses // itself so as to land in ROM even if mapped as a CommaVid and this code is on the fence as to whether it // attempts to modify itself but it probably doesn't - if(has_wide_area_store) target.atari.paging_model = Analyser::Static::Atari2600PagingModel::CommaVid; + if(has_wide_area_store) target.paging_model = Analyser::Static::Atari::Target::PagingModel::CommaVid; } -static void DeterminePagingFor8kCartridge(Analyser::Static::Target &target, const Storage::Cartridge::Cartridge::Segment &segment, const Analyser::Static::MOS6502::Disassembly &disassembly) { +static void DeterminePagingFor8kCartridge(Analyser::Static::Atari::Target &target, const Storage::Cartridge::Cartridge::Segment &segment, const Analyser::Static::MOS6502::Disassembly &disassembly) { // Activision stack titles have their vectors at the top of the low 4k, not the top, and // always list 0xf000 as both vectors; they do not repeat them, and, inexplicably, they all // issue an SEI as their first instruction (maybe some sort of relic of the development environment?) @@ -58,12 +60,12 @@ static void DeterminePagingFor8kCartridge(Analyser::Static::Target &target, cons (segment.data[8191] != 0xf0 || segment.data[8189] != 0xf0 || segment.data[8190] != 0x00 || segment.data[8188] != 0x00) && segment.data[0] == 0x78 ) { - target.atari.paging_model = Analyser::Static::Atari2600PagingModel::ActivisionStack; + target.paging_model = Analyser::Static::Atari::Target::PagingModel::ActivisionStack; return; } // make an assumption that this is the Atari paging model - target.atari.paging_model = Analyser::Static::Atari2600PagingModel::Atari8k; + target.paging_model = Analyser::Static::Atari::Target::PagingModel::Atari8k; std::set internal_accesses; internal_accesses.insert(disassembly.internal_stores.begin(), disassembly.internal_stores.end()); @@ -83,13 +85,13 @@ static void DeterminePagingFor8kCartridge(Analyser::Static::Target &target, cons tigervision_access_count += masked_address == 0x3f; } - if(parker_access_count > atari_access_count) target.atari.paging_model = Analyser::Static::Atari2600PagingModel::ParkerBros; - else if(tigervision_access_count > atari_access_count) target.atari.paging_model = Analyser::Static::Atari2600PagingModel::Tigervision; + if(parker_access_count > atari_access_count) target.paging_model = Analyser::Static::Atari::Target::PagingModel::ParkerBros; + else if(tigervision_access_count > atari_access_count) target.paging_model = Analyser::Static::Atari::Target::PagingModel::Tigervision; } -static void DeterminePagingFor16kCartridge(Analyser::Static::Target &target, const Storage::Cartridge::Cartridge::Segment &segment, const Analyser::Static::MOS6502::Disassembly &disassembly) { +static void DeterminePagingFor16kCartridge(Analyser::Static::Atari::Target &target, const Storage::Cartridge::Cartridge::Segment &segment, const Analyser::Static::MOS6502::Disassembly &disassembly) { // make an assumption that this is the Atari paging model - target.atari.paging_model = Analyser::Static::Atari2600PagingModel::Atari16k; + target.paging_model = Analyser::Static::Atari::Target::PagingModel::Atari16k; std::set internal_accesses; internal_accesses.insert(disassembly.internal_stores.begin(), disassembly.internal_stores.end()); @@ -104,17 +106,17 @@ static void DeterminePagingFor16kCartridge(Analyser::Static::Target &target, con mnetwork_access_count += masked_address >= 0x1fe0 && masked_address < 0x1ffb; } - if(mnetwork_access_count > atari_access_count) target.atari.paging_model = Analyser::Static::Atari2600PagingModel::MNetwork; + if(mnetwork_access_count > atari_access_count) target.paging_model = Analyser::Static::Atari::Target::PagingModel::MNetwork; } -static void DeterminePagingFor64kCartridge(Analyser::Static::Target &target, const Storage::Cartridge::Cartridge::Segment &segment, const Analyser::Static::MOS6502::Disassembly &disassembly) { +static void DeterminePagingFor64kCartridge(Analyser::Static::Atari::Target &target, const Storage::Cartridge::Cartridge::Segment &segment, const Analyser::Static::MOS6502::Disassembly &disassembly) { // make an assumption that this is a Tigervision if there is a write to 3F - target.atari.paging_model = + target.paging_model = (disassembly.external_stores.find(0x3f) != disassembly.external_stores.end()) ? - Analyser::Static::Atari2600PagingModel::Tigervision : Analyser::Static::Atari2600PagingModel::MegaBoy; + Analyser::Static::Atari::Target::PagingModel::Tigervision : Analyser::Static::Atari::Target::PagingModel::MegaBoy; } -static void DeterminePagingForCartridge(Analyser::Static::Target &target, const Storage::Cartridge::Cartridge::Segment &segment) { +static void DeterminePagingForCartridge(Analyser::Static::Atari::Target &target, const Storage::Cartridge::Cartridge::Segment &segment) { if(segment.data.size() == 2048) { DeterminePagingFor2kCartridge(target, segment); return; @@ -138,16 +140,16 @@ static void DeterminePagingForCartridge(Analyser::Static::Target &target, const DeterminePagingFor8kCartridge(target, segment, disassembly); break; case 10495: - target.atari.paging_model = Analyser::Static::Atari2600PagingModel::Pitfall2; + target.paging_model = Analyser::Static::Atari::Target::PagingModel::Pitfall2; break; case 12288: - target.atari.paging_model = Analyser::Static::Atari2600PagingModel::CBSRamPlus; + target.paging_model = Analyser::Static::Atari::Target::PagingModel::CBSRamPlus; break; case 16384: DeterminePagingFor16kCartridge(target, segment, disassembly); break; case 32768: - target.atari.paging_model = Analyser::Static::Atari2600PagingModel::Atari32k; + target.paging_model = Analyser::Static::Atari::Target::PagingModel::Atari32k; break; case 65536: DeterminePagingFor64kCartridge(target, segment, disassembly); @@ -159,8 +161,8 @@ static void DeterminePagingForCartridge(Analyser::Static::Target &target, const // check for a Super Chip. Atari ROM images [almost] always have the same value stored over RAM // regions; when they don't they at least seem to have the first 128 bytes be the same as the // next 128 bytes. So check for that. - if( target.atari.paging_model != Analyser::Static::Atari2600PagingModel::CBSRamPlus && - target.atari.paging_model != Analyser::Static::Atari2600PagingModel::MNetwork) { + if( target.paging_model != Analyser::Static::Atari::Target::PagingModel::CBSRamPlus && + target.paging_model != Analyser::Static::Atari::Target::PagingModel::MNetwork) { bool has_superchip = true; for(std::size_t address = 0; address < 128; address++) { if(segment.data[address] != segment.data[address+128]) { @@ -168,24 +170,24 @@ static void DeterminePagingForCartridge(Analyser::Static::Target &target, const break; } } - target.atari.uses_superchip = has_superchip; + target.uses_superchip = has_superchip; } // check for a Tigervision or Tigervision-esque scheme - if(target.atari.paging_model == Analyser::Static::Atari2600PagingModel::None && segment.data.size() > 4096) { + if(target.paging_model == Analyser::Static::Atari::Target::PagingModel::None && segment.data.size() > 4096) { bool looks_like_tigervision = disassembly.external_stores.find(0x3f) != disassembly.external_stores.end(); - if(looks_like_tigervision) target.atari.paging_model = Analyser::Static::Atari2600PagingModel::Tigervision; + if(looks_like_tigervision) target.paging_model = Analyser::Static::Atari::Target::PagingModel::Tigervision; } } -void Analyser::Static::Atari::AddTargets(const Media &media, std::vector> &destination) { +void Analyser::Static::Atari::AddTargets(const Media &media, std::vector> &destination) { // TODO: sanity checking; is this image really for an Atari 2600? - std::unique_ptr target(new Target); + std::unique_ptr target(new Analyser::Static::Atari::Target); target->machine = Machine::Atari2600; target->confidence = 0.5; target->media.cartridges = media.cartridges; - target->atari.paging_model = Atari2600PagingModel::None; - target->atari.uses_superchip = false; + target->paging_model = Analyser::Static::Atari::Target::PagingModel::None; + target->uses_superchip = false; // try to figure out the paging scheme if(!media.cartridges.empty()) { diff --git a/Analyser/Static/Atari/Target.hpp b/Analyser/Static/Atari/Target.hpp new file mode 100644 index 000000000..dc6cd7955 --- /dev/null +++ b/Analyser/Static/Atari/Target.hpp @@ -0,0 +1,43 @@ +// +// Target.hpp +// Clock Signal +// +// Created by Thomas Harte on 09/03/2018. +// Copyright © 2018 Thomas Harte. All rights reserved. +// + +#ifndef Target_h +#define Target_h + +#include "../StaticAnalyser.hpp" + +namespace Analyser { +namespace Static { +namespace Atari { + +struct Target: public ::Analyser::Static::Target { + enum class PagingModel { + None, + CommaVid, + Atari8k, + Atari16k, + Atari32k, + ActivisionStack, + ParkerBros, + Tigervision, + CBSRamPlus, + MNetwork, + MegaBoy, + Pitfall2 + }; + + // TODO: shouldn't these be properties of the cartridge? + PagingModel paging_model; + bool uses_superchip; +}; + +} +} +} + +#endif /* Target_h */ diff --git a/Analyser/Static/Commodore/StaticAnalyser.cpp b/Analyser/Static/Commodore/StaticAnalyser.cpp index 872e0e3b9..c6daba8f6 100644 --- a/Analyser/Static/Commodore/StaticAnalyser.cpp +++ b/Analyser/Static/Commodore/StaticAnalyser.cpp @@ -11,6 +11,7 @@ #include "Disk.hpp" #include "File.hpp" #include "Tape.hpp" +#include "Target.hpp" #include "../../../Storage/Cartridge/Encodings/CommodoreROM.hpp" #include @@ -38,7 +39,7 @@ static std::vector> return vic20_cartridges; } -void Analyser::Static::Commodore::AddTargets(const Media &media, std::vector> &destination) { +void Analyser::Static::Commodore::AddTargets(const Media &media, std::vector> &destination) { std::unique_ptr target(new Target); target->machine = Machine::Vic20; // TODO: machine estimation target->confidence = 0.5; // TODO: a proper estimation @@ -73,7 +74,7 @@ void Analyser::Static::Commodore::AddTargets(const Media &media, std::vectorvic20.memory_model = Vic20MemoryModel::Unexpanded; + target->memory_model = Target::MemoryModel::Unexpanded; std::ostringstream string_stream; string_stream << "LOAD\"" << (is_disk ? "*" : "") << "\"," << device << ","; if(files.front().is_basic()) { @@ -89,10 +90,10 @@ void Analyser::Static::Commodore::AddTargets(const Media &media, std::vectorvic20.memory_model = Vic20MemoryModel::ThirtyTwoKB; + target->memory_model = Target::MemoryModel::ThirtyTwoKB; break; case 0x0401: - target->vic20.memory_model = Vic20MemoryModel::EightKB; + target->memory_model = Target::MemoryModel::EightKB; break; } @@ -129,9 +130,9 @@ void Analyser::Static::Commodore::AddTargets(const Media &media, std::vector 0x2000) - target->vic20.memory_model = Vic20MemoryModel::ThirtyTwoKB; - else if(target->vic20.memory_model == Vic20MemoryModel::Unexpanded && !(starting_address >= 0x1000 || starting_address+file_size < 0x0400)) - target->vic20.memory_model = Vic20MemoryModel::ThirtyTwoKB; + target->memory_model = Target::MemoryModel::ThirtyTwoKB; + else if(target->memory_model == Target::MemoryModel::Unexpanded && !(starting_address >= 0x1000 || starting_address+file_size < 0x0400)) + target->memory_model = Target::MemoryModel::ThirtyTwoKB; // } } } diff --git a/Analyser/Static/Oric/StaticAnalyser.cpp b/Analyser/Static/Oric/StaticAnalyser.cpp index 364ba8bbf..d32680120 100644 --- a/Analyser/Static/Oric/StaticAnalyser.cpp +++ b/Analyser/Static/Oric/StaticAnalyser.cpp @@ -9,6 +9,7 @@ #include "StaticAnalyser.hpp" #include "Tape.hpp" +#include "Target.hpp" #include "../Disassembler/6502.hpp" #include "../Disassembler/AddressMapper.hpp" @@ -73,7 +74,7 @@ static int Basic11Score(const Analyser::Static::MOS6502::Disassembly &disassembl return Score(disassembly, rom_functions, variable_locations); } -void Analyser::Static::Oric::AddTargets(const Media &media, std::vector> &destination) { +void Analyser::Static::Oric::AddTargets(const Media &media, std::vector> &destination) { std::unique_ptr target(new Target); target->machine = Machine::Oric; target->confidence = 0.5; @@ -104,15 +105,15 @@ void Analyser::Static::Oric::AddTargets(const Media &media, std::vectororic.has_microdisc = true; + target->has_microdisc = true; target->media.disks = media.disks; } else { - target->oric.has_microdisc = false; + target->has_microdisc = false; } // TODO: really this should add two targets if not all votes agree - target->oric.use_atmos_rom = basic11_votes >= basic10_votes; - if(target->oric.has_microdisc) target->oric.use_atmos_rom = true; + target->use_atmos_rom = basic11_votes >= basic10_votes; + if(target->has_microdisc) target->use_atmos_rom = true; if(target->media.tapes.size() || target->media.disks.size() || target->media.cartridges.size()) destination.push_back(std::move(target)); diff --git a/Analyser/Static/Oric/Target.hpp b/Analyser/Static/Oric/Target.hpp new file mode 100644 index 000000000..b3a507de2 --- /dev/null +++ b/Analyser/Static/Oric/Target.hpp @@ -0,0 +1,25 @@ +// +// Target.hpp +// Clock Signal +// +// Created by Thomas Harte on 09/03/2018. +// Copyright © 2018 Thomas Harte. All rights reserved. +// + +#ifndef Target_h +#define Target_h + +namespace Analyser { +namespace Static { +namespace Oric { + +struct Target: public ::Analyser::Static::Target { + bool use_atmos_rom; + bool has_microdisc; +}; + +} +} +} + +#endif /* Target_h */ diff --git a/Analyser/Static/StaticAnalyser.hpp b/Analyser/Static/StaticAnalyser.hpp index cc9107881..acfccc507 100644 --- a/Analyser/Static/StaticAnalyser.hpp +++ b/Analyser/Static/StaticAnalyser.hpp @@ -21,33 +21,6 @@ namespace Analyser { namespace Static { -enum class Vic20MemoryModel { - Unexpanded, - EightKB, - ThirtyTwoKB -}; - -enum class Atari2600PagingModel { - None, - CommaVid, - Atari8k, - Atari16k, - Atari32k, - ActivisionStack, - ParkerBros, - Tigervision, - CBSRamPlus, - MNetwork, - MegaBoy, - Pitfall2 -}; - -enum class AmstradCPCModel { - CPC464, - CPC664, - CPC6128 -}; - /*! A list of disks, tapes and cartridges. */ @@ -73,35 +46,6 @@ struct Target { float confidence; std::string loading_command; - - // TODO: this is too C-like a solution; make Target a base class and - // turn the following into information held by more specific subclasses. - union { - struct { - bool has_adfs; - bool has_dfs; - bool should_shift_restart; - } acorn; - - struct { - Atari2600PagingModel paging_model; - bool uses_superchip; - } atari; - - struct { - bool use_atmos_rom; - bool has_microdisc; - } oric; - - struct { - Vic20MemoryModel memory_model; - bool has_c1540; - } vic20; - - struct { - AmstradCPCModel model; - } amstradcpc; - }; }; /*! diff --git a/Machines/AmstradCPC/AmstradCPC.cpp b/Machines/AmstradCPC/AmstradCPC.cpp index b81b852ba..cd4ca2bff 100644 --- a/Machines/AmstradCPC/AmstradCPC.cpp +++ b/Machines/AmstradCPC/AmstradCPC.cpp @@ -29,6 +29,8 @@ #include "../../ClockReceiver/ForceInline.hpp" #include "../../Outputs/Speaker/Implementation/LowpassSpeaker.hpp" +#include "../../Analyser/Static/AmstradCPC/Target.hpp" + #include #include @@ -875,18 +877,20 @@ class ConcreteMachine: /// The ConfigurationTarget entry point; should configure this meachine as described by @c target. void configure_as_target(const Analyser::Static::Target *target) override final { - switch(target->amstradcpc.model) { - case Analyser::Static::AmstradCPCModel::CPC464: + auto *const cpc_target = dynamic_cast(target); + + switch(cpc_target->model) { + case Analyser::Static::AmstradCPC::Target::Model::CPC464: rom_model_ = ROMType::OS464; has_128k_ = false; has_fdc_ = false; break; - case Analyser::Static::AmstradCPCModel::CPC664: + case Analyser::Static::AmstradCPC::Target::Model::CPC664: rom_model_ = ROMType::OS664; has_128k_ = false; has_fdc_ = true; break; - case Analyser::Static::AmstradCPCModel::CPC6128: + case Analyser::Static::AmstradCPC::Target::Model::CPC6128: rom_model_ = ROMType::OS6128; has_128k_ = true; has_fdc_ = true; diff --git a/Machines/Atari2600/Atari2600.cpp b/Machines/Atari2600/Atari2600.cpp index 181a57bdd..ed75abcc5 100644 --- a/Machines/Atari2600/Atari2600.cpp +++ b/Machines/Atari2600/Atari2600.cpp @@ -15,6 +15,8 @@ #include "../CRTMachine.hpp" #include "../JoystickMachine.hpp" +#include "../../Analyser/Static/Atari/Target.hpp" + #include "Cartridges/Atari8k.hpp" #include "Cartridges/Atari16k.hpp" #include "Cartridges/Atari32k.hpp" @@ -90,34 +92,37 @@ class ConcreteMachine: } void configure_as_target(const Analyser::Static::Target *target) override { + auto *const atari_target = dynamic_cast(target); const std::vector &rom = target->media.cartridges.front()->get_segments().front().data; - switch(target->atari.paging_model) { - case Analyser::Static::Atari2600PagingModel::ActivisionStack: bus_.reset(new Cartridge::Cartridge(rom)); break; - case Analyser::Static::Atari2600PagingModel::CBSRamPlus: bus_.reset(new Cartridge::Cartridge(rom)); break; - case Analyser::Static::Atari2600PagingModel::CommaVid: bus_.reset(new Cartridge::Cartridge(rom)); break; - case Analyser::Static::Atari2600PagingModel::MegaBoy: bus_.reset(new Cartridge::Cartridge(rom)); break; - case Analyser::Static::Atari2600PagingModel::MNetwork: bus_.reset(new Cartridge::Cartridge(rom)); break; - case Analyser::Static::Atari2600PagingModel::None: bus_.reset(new Cartridge::Cartridge(rom)); break; - case Analyser::Static::Atari2600PagingModel::ParkerBros: bus_.reset(new Cartridge::Cartridge(rom)); break; - case Analyser::Static::Atari2600PagingModel::Pitfall2: bus_.reset(new Cartridge::Cartridge(rom)); break; - case Analyser::Static::Atari2600PagingModel::Tigervision: bus_.reset(new Cartridge::Cartridge(rom)); break; - case Analyser::Static::Atari2600PagingModel::Atari8k: - if(target->atari.uses_superchip) { + using PagingModel = Analyser::Static::Atari::Target::PagingModel; + switch(atari_target->paging_model) { + case PagingModel::ActivisionStack: bus_.reset(new Cartridge::Cartridge(rom)); break; + case PagingModel::CBSRamPlus: bus_.reset(new Cartridge::Cartridge(rom)); break; + case PagingModel::CommaVid: bus_.reset(new Cartridge::Cartridge(rom)); break; + case PagingModel::MegaBoy: bus_.reset(new Cartridge::Cartridge(rom)); break; + case PagingModel::MNetwork: bus_.reset(new Cartridge::Cartridge(rom)); break; + case PagingModel::None: bus_.reset(new Cartridge::Cartridge(rom)); break; + case PagingModel::ParkerBros: bus_.reset(new Cartridge::Cartridge(rom)); break; + case PagingModel::Pitfall2: bus_.reset(new Cartridge::Cartridge(rom)); break; + case PagingModel::Tigervision: bus_.reset(new Cartridge::Cartridge(rom)); break; + + case PagingModel::Atari8k: + if(atari_target->uses_superchip) { bus_.reset(new Cartridge::Cartridge(rom)); } else { bus_.reset(new Cartridge::Cartridge(rom)); } break; - case Analyser::Static::Atari2600PagingModel::Atari16k: - if(target->atari.uses_superchip) { + case PagingModel::Atari16k: + if(atari_target->uses_superchip) { bus_.reset(new Cartridge::Cartridge(rom)); } else { bus_.reset(new Cartridge::Cartridge(rom)); } break; - case Analyser::Static::Atari2600PagingModel::Atari32k: - if(target->atari.uses_superchip) { + case PagingModel::Atari32k: + if(atari_target->uses_superchip) { bus_.reset(new Cartridge::Cartridge(rom)); } else { bus_.reset(new Cartridge::Cartridge(rom)); diff --git a/Machines/Commodore/Vic-20/Vic20.cpp b/Machines/Commodore/Vic-20/Vic20.cpp index 11e99f5e7..32d01439b 100644 --- a/Machines/Commodore/Vic-20/Vic20.cpp +++ b/Machines/Commodore/Vic-20/Vic20.cpp @@ -31,6 +31,8 @@ #include "../../../Configurable/StandardOptions.hpp" +#include "../../../Analyser/Static/Commodore/Target.hpp" + #include #include @@ -364,18 +366,20 @@ class ConcreteMachine: } void configure_as_target(const Analyser::Static::Target *target) override final { + auto *const commodore_target = dynamic_cast(target); + if(target->loading_command.length()) { type_string(target->loading_command); } - switch(target->vic20.memory_model) { - case Analyser::Static::Vic20MemoryModel::Unexpanded: + switch(commodore_target->memory_model) { + case Analyser::Static::Commodore::Target::MemoryModel::Unexpanded: set_memory_size(Default); break; - case Analyser::Static::Vic20MemoryModel::EightKB: + case Analyser::Static::Commodore::Target::MemoryModel::EightKB: set_memory_size(ThreeKB); break; - case Analyser::Static::Vic20MemoryModel::ThirtyTwoKB: + case Analyser::Static::Commodore::Target::MemoryModel::ThirtyTwoKB: set_memory_size(ThirtyTwoKB); break; } diff --git a/Machines/Electron/Electron.cpp b/Machines/Electron/Electron.cpp index aeb7e927b..f54dfe637 100644 --- a/Machines/Electron/Electron.cpp +++ b/Machines/Electron/Electron.cpp @@ -20,6 +20,7 @@ #include "../../Storage/Tape/Tape.hpp" #include "../Utility/Typer.hpp" +#include "../../Analyser/Static/Acorn/Target.hpp" #include "Interrupts.hpp" #include "Keyboard.hpp" @@ -124,21 +125,23 @@ class ConcreteMachine: } void configure_as_target(const Analyser::Static::Target *target) override final { + auto *const acorn_target = dynamic_cast(target); + if(target->loading_command.length()) { type_string(target->loading_command); } - if(target->acorn.should_shift_restart) { + if(acorn_target->should_shift_restart) { shift_restart_counter_ = 1000000; } - if(target->acorn.has_dfs || target->acorn.has_adfs) { + if(acorn_target->has_dfs || acorn_target->has_adfs) { plus3_.reset(new Plus3); - if(target->acorn.has_dfs) { + if(acorn_target->has_dfs) { set_rom(ROMSlot0, dfs_, true); } - if(target->acorn.has_adfs) { + if(acorn_target->has_adfs) { set_rom(ROMSlot4, adfs1_, true); set_rom(ROMSlot5, adfs2_, true); } diff --git a/Machines/Oric/Oric.cpp b/Machines/Oric/Oric.cpp index 172fe6f28..30da85595 100644 --- a/Machines/Oric/Oric.cpp +++ b/Machines/Oric/Oric.cpp @@ -30,6 +30,8 @@ #include "../../Configurable/StandardOptions.hpp" #include "../../Outputs/Speaker/Implementation/LowpassSpeaker.hpp" +#include "../../Analyser/Static/Oric/Target.hpp" + #include #include #include @@ -263,7 +265,9 @@ class ConcreteMachine: // to satisfy ConfigurationTarget::Machine void configure_as_target(const Analyser::Static::Target *target) override final { - if(target->oric.has_microdisc) { + auto *const oric_target = dynamic_cast(target); + + if(oric_target->has_microdisc) { microdisc_is_enabled_ = true; microdisc_did_change_paging_flags(µdisc_); microdisc_.set_delegate(this); @@ -273,7 +277,7 @@ class ConcreteMachine: type_string(target->loading_command); } - if(target->oric.use_atmos_rom) { + if(oric_target->use_atmos_rom) { std::memcpy(rom_, basic11_rom_.data(), std::min(basic11_rom_.size(), sizeof(rom_))); is_using_basic11_ = true; diff --git a/Machines/ZX8081/ZX8081.cpp b/Machines/ZX8081/ZX8081.cpp index 7d80d2fc1..af566af18 100644 --- a/Machines/ZX8081/ZX8081.cpp +++ b/Machines/ZX8081/ZX8081.cpp @@ -280,8 +280,7 @@ template class ConcreteMachine: } void configure_as_target(const Analyser::Static::Target *target) override final { - const Analyser::Static::ZX8081::Target *const zx8081_target = - dynamic_cast(target); + auto *const zx8081_target = dynamic_cast(target); is_zx81_ = zx8081_target->isZX81; if(is_zx81_) { rom_ = zx81_rom_; diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index f912171d9..95ecf7270 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -1331,6 +1331,11 @@ 4BDCC5F81FB27A5E001220C5 /* ROMMachine.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ROMMachine.hpp; sourceTree = ""; }; 4BDDBA981EF3451200347E61 /* Z80MachineCycleTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Z80MachineCycleTests.swift; sourceTree = ""; }; 4BE3231220532443006EF799 /* Target.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Target.hpp; sourceTree = ""; }; + 4BE32313205327D7006EF799 /* Target.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Target.hpp; sourceTree = ""; }; + 4BE32314205328FF006EF799 /* Target.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Target.hpp; sourceTree = ""; }; + 4BE3231520532AA7006EF799 /* Target.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Target.hpp; sourceTree = ""; }; + 4BE3231620532BED006EF799 /* Target.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Target.hpp; sourceTree = ""; }; + 4BE3231720532CC0006EF799 /* Target.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Target.hpp; sourceTree = ""; }; 4BE7C9161E3D397100A5496D /* TIA.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TIA.cpp; sourceTree = ""; }; 4BE7C9171E3D397100A5496D /* TIA.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = TIA.hpp; sourceTree = ""; }; 4BE845201F2FF7F100A5EA22 /* CRTC6845.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = CRTC6845.hpp; path = 6845/CRTC6845.hpp; sourceTree = ""; }; @@ -2165,6 +2170,7 @@ 4B8944EE201967B4007DE474 /* File.hpp */, 4B8944ED201967B4007DE474 /* StaticAnalyser.hpp */, 4B8944EF201967B4007DE474 /* Tape.hpp */, + 4BE32313205327D7006EF799 /* Target.hpp */, ); path = Acorn; sourceTree = ""; @@ -2174,6 +2180,7 @@ children = ( 4B8944F5201967B4007DE474 /* StaticAnalyser.cpp */, 4B8944F4201967B4007DE474 /* StaticAnalyser.hpp */, + 4BE3231720532CC0006EF799 /* Target.hpp */, ); path = Atari; sourceTree = ""; @@ -2185,6 +2192,7 @@ 4B8944F9201967B4007DE474 /* Tape.cpp */, 4B8944F7201967B4007DE474 /* StaticAnalyser.hpp */, 4B8944F8201967B4007DE474 /* Tape.hpp */, + 4BE3231620532BED006EF799 /* Target.hpp */, ); path = Oric; sourceTree = ""; @@ -2200,6 +2208,7 @@ 4B8944FE201967B4007DE474 /* File.hpp */, 4B8944FD201967B4007DE474 /* StaticAnalyser.hpp */, 4B8944FF201967B4007DE474 /* Tape.hpp */, + 4BE3231520532AA7006EF799 /* Target.hpp */, ); path = Commodore; sourceTree = ""; @@ -2245,6 +2254,7 @@ children = ( 4B894516201967B4007DE474 /* StaticAnalyser.cpp */, 4B894515201967B4007DE474 /* StaticAnalyser.hpp */, + 4BE32314205328FF006EF799 /* Target.hpp */, ); path = AmstradCPC; sourceTree = ""; From a7f229bc4b0f9100c9d4bf132fc35666e214b793 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Fri, 9 Mar 2018 16:10:17 -0500 Subject: [PATCH 3/3] Adds missing files. --- Analyser/Static/AmstradCPC/Target.hpp | 33 +++++++++++++++++++++++++++ Analyser/Static/Commodore/Target.hpp | 33 +++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 Analyser/Static/AmstradCPC/Target.hpp create mode 100644 Analyser/Static/Commodore/Target.hpp diff --git a/Analyser/Static/AmstradCPC/Target.hpp b/Analyser/Static/AmstradCPC/Target.hpp new file mode 100644 index 000000000..056c45402 --- /dev/null +++ b/Analyser/Static/AmstradCPC/Target.hpp @@ -0,0 +1,33 @@ +// +// Target.hpp +// Clock Signal +// +// Created by Thomas Harte on 09/03/2018. +// Copyright © 2018 Thomas Harte. All rights reserved. +// + +#ifndef Target_h +#define Target_h + +#include "../StaticAnalyser.hpp" + +namespace Analyser { +namespace Static { +namespace AmstradCPC { + +struct Target: public ::Analyser::Static::Target { + enum class Model { + CPC464, + CPC664, + CPC6128 + }; + + Model model; +}; + +} +} +} + + +#endif /* Target_h */ diff --git a/Analyser/Static/Commodore/Target.hpp b/Analyser/Static/Commodore/Target.hpp new file mode 100644 index 000000000..381e35207 --- /dev/null +++ b/Analyser/Static/Commodore/Target.hpp @@ -0,0 +1,33 @@ +// +// Target.hpp +// Clock Signal +// +// Created by Thomas Harte on 09/03/2018. +// Copyright © 2018 Thomas Harte. All rights reserved. +// + +#ifndef Target_h +#define Target_h + +#include "../StaticAnalyser.hpp" + +namespace Analyser { +namespace Static { +namespace Commodore { + +struct Target: public ::Analyser::Static::Target { + enum class MemoryModel { + Unexpanded, + EightKB, + ThirtyTwoKB + }; + + MemoryModel memory_model; + bool has_c1540; +}; + +} +} +} + +#endif /* Target_h */