From 97249b0edd830b3a1f4296685fa2fb9999a2a5bc Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Thu, 18 Mar 2021 10:18:17 -0400 Subject: [PATCH] Slow walks further towards a functioning Spectrum. --- Analyser/Static/ZXSpectrum/StaticAnalyser.cpp | 3 +- Analyser/Static/ZXSpectrum/Target.hpp | 40 +++++++++++ Machines/Sinclair/ZXSpectrum/ZXSpectrum.cpp | 69 +++++++++++++++++-- .../Clock Signal.xcodeproj/project.pbxproj | 2 + 4 files changed, 109 insertions(+), 5 deletions(-) create mode 100644 Analyser/Static/ZXSpectrum/Target.hpp diff --git a/Analyser/Static/ZXSpectrum/StaticAnalyser.cpp b/Analyser/Static/ZXSpectrum/StaticAnalyser.cpp index 82456be58..637a106a2 100644 --- a/Analyser/Static/ZXSpectrum/StaticAnalyser.cpp +++ b/Analyser/Static/ZXSpectrum/StaticAnalyser.cpp @@ -9,6 +9,7 @@ #include "StaticAnalyser.hpp" #include "../../../Storage/Tape/Parsers/Spectrum.hpp" +#include "Target.hpp" namespace { @@ -33,7 +34,7 @@ bool IsSpectrumTape(const std::shared_ptr &tape) { Analyser::Static::TargetList Analyser::Static::ZXSpectrum::GetTargets(const Media &media, const std::string &, TargetPlatform::IntType) { TargetList destination; - auto target = std::make_unique(Machine::ZXSpectrum); + auto target = std::make_unique(); target->confidence = 0.5; if(!media.tapes.empty()) { diff --git a/Analyser/Static/ZXSpectrum/Target.hpp b/Analyser/Static/ZXSpectrum/Target.hpp new file mode 100644 index 000000000..159cec9ef --- /dev/null +++ b/Analyser/Static/ZXSpectrum/Target.hpp @@ -0,0 +1,40 @@ +// +// Target.hpp +// Clock Signal +// +// Created by Thomas Harte on 18/03/2021. +// Copyright © 2021 Thomas Harte. All rights reserved. +// + +#ifndef Analyser_Static_ZXSpectrum_Target_h +#define Analyser_Static_ZXSpectrum_Target_h + +#include "../../../Reflection/Enum.hpp" +#include "../../../Reflection/Struct.hpp" +#include "../StaticAnalyser.hpp" + +namespace Analyser { +namespace Static { +namespace ZXSpectrum { + +struct Target: public ::Analyser::Static::Target, public Reflection::StructImpl { + ReflectableEnum(Model, + Plus2a, + Plus3, + ); + + Model model = Model::Plus2a; + + Target(): Analyser::Static::Target(Machine::ZXSpectrum) { + if(needs_declare()) { + DeclareField(model); + AnnounceEnum(Model); + } + } +}; + +} +} +} + +#endif /* Target_h */ diff --git a/Machines/Sinclair/ZXSpectrum/ZXSpectrum.cpp b/Machines/Sinclair/ZXSpectrum/ZXSpectrum.cpp index 0fb126aa8..a253fbed7 100644 --- a/Machines/Sinclair/ZXSpectrum/ZXSpectrum.cpp +++ b/Machines/Sinclair/ZXSpectrum/ZXSpectrum.cpp @@ -10,15 +10,76 @@ #include "../../MachineTypes.hpp" -#include "../../../Analyser/Static/StaticAnalyser.hpp" +#include "../../../Analyser/Static/ZXSpectrum/Target.hpp" +#include + +namespace { + const unsigned int ClockRate = 3'500'000; +} + + +namespace Sinclair { +namespace ZXSpectrum { + +using Model = Analyser::Static::ZXSpectrum::Target::Model; +template class ConcreteMachine: + public MachineTypes::ScanProducer, + public MachineTypes::TimedMachine, + public Machine { + public: + ConcreteMachine(const Analyser::Static::ZXSpectrum::Target &target, const ROMMachine::ROMFetcher &rom_fetcher) + { + set_clock_rate(ClockRate); + + // With only the +2a and +3 currently supported, the +3 ROM is always + // the one required. + const auto roms = + rom_fetcher({ {"ZXSpectrum", "the +2a/+3 ROM", "plus3.rom", 64 * 1024, 0x96e3c17a} }); + if(!roms[0]) throw ROMMachine::Error::MissingROMs; + memcpy(rom_.data(), roms[0]->data(), std::min(rom_.size(), roms[0]->size())); + + // TODO: insert media, set up memory map. + (void)target; + } + + // MARK: - TimedMachine + + void run_for(const Cycles cycles) override { + // TODO. + (void)cycles; + } + + // MARK: - ScanProducer + + void set_scan_target(Outputs::Display::ScanTarget *scan_target) final { + (void)scan_target; + } + + Outputs::Display::ScanStatus get_scaled_scan_status() const final { + // TODO. + return Outputs::Display::ScanStatus(); + } + + private: + std::array rom_; + std::array ram_; +}; + + +} +} using namespace Sinclair::ZXSpectrum; Machine *Machine::ZXSpectrum(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher) { - /* TODO */ - (void)target; - (void)rom_fetcher; + const auto zx_target = dynamic_cast(target); + + switch(zx_target->model) { + case Model::Plus2a: return new ConcreteMachine(*zx_target, rom_fetcher); + case Model::Plus3: return new ConcreteMachine(*zx_target, rom_fetcher); + } + return nullptr; } diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index c3b07e5b4..cfe9b411e 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -1069,6 +1069,7 @@ 4B0F1BD02602F17B00B85C66 /* ZX8081.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ZX8081.hpp; sourceTree = ""; }; 4B0F1BFA260300D900B85C66 /* ZXSpectrum.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ZXSpectrum.cpp; sourceTree = ""; }; 4B0F1BFB260300D900B85C66 /* ZXSpectrum.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ZXSpectrum.hpp; sourceTree = ""; }; + 4B0F1C04260391F100B85C66 /* Target.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Target.hpp; sourceTree = ""; }; 4B0F94FC208C1A1600FE41D9 /* NIB.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = NIB.cpp; sourceTree = ""; }; 4B0F94FD208C1A1600FE41D9 /* NIB.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = NIB.hpp; sourceTree = ""; }; 4B0F9500208C42A300FE41D9 /* Target.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; name = Target.hpp; path = AppleII/Target.hpp; sourceTree = ""; }; @@ -2167,6 +2168,7 @@ children = ( 4B0F1BB02602645900B85C66 /* StaticAnalyser.cpp */, 4B0F1BB12602645900B85C66 /* StaticAnalyser.hpp */, + 4B0F1C04260391F100B85C66 /* Target.hpp */, ); path = ZXSpectrum; sourceTree = "";