1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-06-25 18:30:07 +00:00

Basic sketch for state snapshots: an extra field on Target.

I think it doesn't make sense for states to own a target as that complicates the concept of Media. Plus they're distinct because it makes sense to have only one per Target. Let's see how this pans out.
This commit is contained in:
Thomas Harte 2021-04-24 23:17:47 -04:00
parent 9cc747b3e2
commit d61f478a39
8 changed files with 170 additions and 10 deletions

View File

@ -57,6 +57,9 @@
#include "../../Storage/MassStorage/Formats/DAT.hpp"
#include "../../Storage/MassStorage/Formats/HFV.hpp"
// State Snapshots
#include "../../Storage/State/SNA.hpp"
// Tapes
#include "../../Storage/Tape/Formats/CAS.hpp"
#include "../../Storage/Tape/Formats/CommodoreTAP.hpp"
@ -73,15 +76,23 @@
using namespace Analyser::Static;
static Media GetMediaAndPlatforms(const std::string &file_name, TargetPlatform::IntType &potential_platforms) {
Media result;
namespace {
std::string get_extension(const std::string &name) {
// Get the extension, if any; it will be assumed that extensions are reliable, so an extension is a broad-phase
// test as to file format.
std::string::size_type final_dot = file_name.find_last_of(".");
if(final_dot == std::string::npos) return result;
std::string extension = file_name.substr(final_dot + 1);
std::string::size_type final_dot = name.find_last_of(".");
if(final_dot == std::string::npos) return name;
std::string extension = name.substr(final_dot + 1);
std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
return extension;
}
}
static Media GetMediaAndPlatforms(const std::string &file_name, TargetPlatform::IntType &potential_platforms) {
Media result;
const std::string extension = get_extension(file_name);
#define InsertInstance(list, instance, platforms) \
list.emplace_back(instance);\
@ -189,6 +200,7 @@ static Media GetMediaAndPlatforms(const std::string &file_name, TargetPlatform::
#undef TryInsert
#undef InsertInstance
return result;
}
@ -199,14 +211,31 @@ Media Analyser::Static::GetMedia(const std::string &file_name) {
TargetList Analyser::Static::GetTargets(const std::string &file_name) {
TargetList targets;
const std::string extension = get_extension(file_name);
// Check whether the file directly identifies a target; if so then just return that.
#define Format(ext, class) \
if(extension == ext) { \
auto target = Storage::State::class::load(file_name); \
if(target) { \
targets.push_back(std::move(target)); \
return targets; \
} \
}
Format("sna", SNA);
#undef TryInsert
// Otherwise:
//
// Collect all disks, tapes ROMs, etc as can be extrapolated from this file, forming the
// union of all platforms this file might be a target for.
TargetPlatform::IntType potential_platforms = 0;
Media media = GetMediaAndPlatforms(file_name, potential_platforms);
// Hand off to platform-specific determination of whether these things are actually compatible and,
// if so, how to load them.
// Hand off to platform-specific determination of whether these
// things are actually compatible and, if so, how to load them.
#define Append(x) if(potential_platforms & TargetPlatform::x) {\
auto new_targets = x::GetTargets(media, file_name, potential_platforms);\
std::move(new_targets.begin(), new_targets.end(), std::back_inserter(targets));\

View File

@ -15,6 +15,7 @@
#include "../../Storage/Disk/Disk.hpp"
#include "../../Storage/MassStorage/MassStorageDevice.hpp"
#include "../../Storage/Tape/Tape.hpp"
#include "../../Reflection/Struct.hpp"
#include <memory>
#include <string>
@ -23,8 +24,10 @@
namespace Analyser {
namespace Static {
struct State;
/*!
A list of disks, tapes and cartridges.
A list of disks, tapes and cartridges, and possibly a state snapshot.
*/
struct Media {
std::vector<std::shared_ptr<Storage::Disk::Disk>> disks;
@ -48,13 +51,16 @@ struct Media {
};
/*!
A list of disks, tapes and cartridges plus information about the machine to which to attach them and its configuration,
and instructions on how to launch the software attached, plus a measure of confidence in this target's correctness.
Describes a machine and possibly its state; conventionally subclassed to add other machine-specific configuration fields and any
necessary instructions on how to launch any software provided, plus a measure of confidence in this target's correctness.
*/
struct Target {
Target(Machine machine) : machine(machine) {}
virtual ~Target() {}
// This field is entirely optional.
std::shared_ptr<Reflection::Struct> state;
Machine machine;
Media media;
float confidence = 0.0f;

View File

@ -20,6 +20,7 @@
#include "MediaTarget.hpp"
#include "MouseMachine.hpp"
#include "ScanProducer.hpp"
#include "StateProducer.hpp"
#include "TimedMachine.hpp"
#endif /* MachineTypes_h */

View File

@ -0,0 +1,26 @@
//
// StateProducer.hpp
// Clock Signal
//
// Created by Thomas Harte on 24/04/2021.
// Copyright © 2021 Thomas Harte. All rights reserved.
//
#ifndef State_h
#define State_h
#include <memory>
#include "../Analyser/Static/StaticAnalyser.hpp"
namespace MachineTypes {
struct StateProducer {
// TODO.
// virtual bool get_state(Analyser::Static::State *, [[maybe_unused]] bool advance_to_simple = false) {
// return false;
// }
};
};
#endif /* State_h */

View File

@ -479,6 +479,8 @@
4B89453E201967B4007DE474 /* StaticAnalyser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B894517201967B4007DE474 /* StaticAnalyser.cpp */; };
4B89453F201967B4007DE474 /* StaticAnalyser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B894517201967B4007DE474 /* StaticAnalyser.cpp */; };
4B8DD3682633B2D400B3C866 /* SpectrumVideoContentionTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B8DD3672633B2D400B3C866 /* SpectrumVideoContentionTests.mm */; };
4B8DD3862634D37E00B3C866 /* SNA.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8DD3842634D37E00B3C866 /* SNA.cpp */; };
4B8DD3872634D37E00B3C866 /* SNA.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8DD3842634D37E00B3C866 /* SNA.cpp */; };
4B8DF4D825465B7500F3433C /* IIgsMemoryMapTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B8DF4D725465B7500F3433C /* IIgsMemoryMapTests.mm */; };
4B8DF4F9254E36AE00F3433C /* Video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8DF4F7254E36AD00F3433C /* Video.cpp */; };
4B8DF4FA254E36AE00F3433C /* Video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8DF4F7254E36AD00F3433C /* Video.cpp */; };
@ -1429,6 +1431,9 @@
4B8A7E85212F988200F2BBC6 /* DeferredQueue.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = DeferredQueue.hpp; sourceTree = "<group>"; };
4B8D287E1F77207100645199 /* TrackSerialiser.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = TrackSerialiser.hpp; sourceTree = "<group>"; };
4B8DD3672633B2D400B3C866 /* SpectrumVideoContentionTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SpectrumVideoContentionTests.mm; sourceTree = "<group>"; };
4B8DD375263481BB00B3C866 /* StateProducer.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = StateProducer.hpp; sourceTree = "<group>"; };
4B8DD3842634D37E00B3C866 /* SNA.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SNA.cpp; sourceTree = "<group>"; };
4B8DD3852634D37E00B3C866 /* SNA.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = SNA.hpp; sourceTree = "<group>"; };
4B8DF4D62546561300F3433C /* MemoryMap.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = MemoryMap.hpp; sourceTree = "<group>"; };
4B8DF4D725465B7500F3433C /* IIgsMemoryMapTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = IIgsMemoryMapTests.mm; sourceTree = "<group>"; };
4B8DF4ED254B840B00F3433C /* AppleClock.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = AppleClock.hpp; sourceTree = "<group>"; };
@ -2842,6 +2847,7 @@
4B8805F81DCFF6CD003085B1 /* Data */,
4BAB62AA1D3272D200DF5BA0 /* Disk */,
4B6AAEA1230E3E1D0078E864 /* MassStorage */,
4B8DD3832634D37E00B3C866 /* State */,
4B69FB3A1C4D908A00B5F0AA /* Tape */,
);
name = Storage;
@ -3248,6 +3254,15 @@
path = AmstradCPC;
sourceTree = "<group>";
};
4B8DD3832634D37E00B3C866 /* State */ = {
isa = PBXGroup;
children = (
4B8DD3842634D37E00B3C866 /* SNA.cpp */,
4B8DD3852634D37E00B3C866 /* SNA.hpp */,
);
path = State;
sourceTree = "<group>";
};
4B8DF4EC254B840B00F3433C /* AppleClock */ = {
isa = PBXGroup;
children = (
@ -4018,6 +4033,7 @@
4B92294222B04A3D00A1458F /* MouseMachine.hpp */,
4BDCC5F81FB27A5E001220C5 /* ROMMachine.hpp */,
4B046DC31CFE651500E9E45E /* ScanProducer.hpp */,
4B8DD375263481BB00B3C866 /* StateProducer.hpp */,
4BC57CD32434282000FBC404 /* TimedMachine.hpp */,
4B38F3491F2EC12000D9235D /* AmstradCPC */,
4BCE0048227CE8CA000CA200 /* Apple */,
@ -5216,6 +5232,7 @@
4BEDA43225B3C700000C2DBD /* Executor.cpp in Sources */,
4BC1317B2346DF2B00E4FF3D /* MSA.cpp in Sources */,
4B894533201967B4007DE474 /* 6502.cpp in Sources */,
4B8DD3872634D37E00B3C866 /* SNA.cpp in Sources */,
4B055AA91FAE85EF0060FFFF /* CommodoreGCR.cpp in Sources */,
4B055ADB1FAE9B460060FFFF /* 6560.cpp in Sources */,
4B17B58C20A8A9D9007CCA8F /* StringSerialiser.cpp in Sources */,
@ -5486,6 +5503,7 @@
4BEBFB4D2002C4BF000708CC /* MSXDSK.cpp in Sources */,
4BBFBB6C1EE8401E00C01E7A /* ZX8081.cpp in Sources */,
4B83348A1F5DB94B0097E338 /* IRQDelegatePortHandler.cpp in Sources */,
4B8DD3862634D37E00B3C866 /* SNA.cpp in Sources */,
4B4DEC06252BFA56004583AC /* 65816Base.cpp in Sources */,
4B894524201967B4007DE474 /* Tape.cpp in Sources */,
4B7136891F78725F008B8ED9 /* Shifter.cpp in Sources */,

View File

@ -592,6 +592,26 @@
<key>NSDocumentClass</key>
<string>$(PRODUCT_MODULE_NAME).MachineDocument</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>sna</string>
</array>
<key>CFBundleTypeName</key>
<string>ZX Spectrum SNA image</string>
<key>CFBundleTypeOSTypes</key>
<array>
<string>????</string>
</array>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSHandlerRank</key>
<string>Owner</string>
<key>LSTypeIsPackage</key>
<false/>
<key>NSDocumentClass</key>
<string>$(PRODUCT_MODULE_NAME).MachineDocument</string>
</dict>
</array>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>

36
Storage/State/SNA.cpp Normal file
View File

@ -0,0 +1,36 @@
//
// SNA.cpp
// Clock Signal
//
// Created by Thomas Harte on 24/04/2021.
// Copyright © 2021 Thomas Harte. All rights reserved.
//
#include "SNA.hpp"
using namespace Storage::State;
std::unique_ptr<Analyser::Static::Target> SNA::load(const std::string &file_name) {
// 0x1a byte header:
//
// 00 I
// 01 HL'
// 03 DE'
// 05 BC'
// 07 AF'
// 09 HL
// 0B DE
// 0D BC
// 0F IY
// 11 IX
// 13 IFF2 (in bit 2)
// 14 R
// 15 AF
// 17 SP
// 19 interrupt mode
// 1A border colour
// 1B 48kb RAM contents
(void)file_name;
return nullptr;
}

24
Storage/State/SNA.hpp Normal file
View File

@ -0,0 +1,24 @@
//
// SNA.hpp
// Clock Signal
//
// Created by Thomas Harte on 24/04/2021.
// Copyright © 2021 Thomas Harte. All rights reserved.
//
#ifndef SNA_hpp
#define SNA_hpp
#include "../../Analyser/Static/StaticAnalyser.hpp"
namespace Storage {
namespace State {
struct SNA {
static std::unique_ptr<Analyser::Static::Target> load(const std::string &file_name);
};
}
}
#endif /* SNA_hpp */