From 6a65c7a52a79bad49c129730efd0545b7249f70f Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Thu, 10 Aug 2017 17:10:21 -0400 Subject: [PATCH] Started working on a CPC-oriented analyser; for now I just want to be able to make a good guess at the appropriate file to load from a disk. As it turns out, the CPC simply adopts the CP/M format, so a generic parser is appropriate. This is its beginning. --- .../Clock Signal.xcodeproj/project.pbxproj | 22 ++++++++-- StaticAnalyser/AmstradCPC/StaticAnalyser.cpp | 13 ++++++ Storage/Disk/Parsers/CPM.cpp | 43 +++++++++++++++++++ Storage/Disk/Parsers/CPM.hpp | 39 +++++++++++++++++ 4 files changed, 113 insertions(+), 4 deletions(-) create mode 100644 Storage/Disk/Parsers/CPM.cpp create mode 100644 Storage/Disk/Parsers/CPM.hpp diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index 1522bb3df..263dd9bb3 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -58,6 +58,7 @@ 4B3BA0D11D318B44005DD7A7 /* TestMachine6502.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B3BA0CD1D318B44005DD7A7 /* TestMachine6502.mm */; }; 4B3BF5B01F146265005B6C36 /* CSW.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B3BF5AE1F146264005B6C36 /* CSW.cpp */; }; 4B3F1B461E0388D200DB26EE /* PCMPatchedTrack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B3F1B441E0388D200DB26EE /* PCMPatchedTrack.cpp */; }; + 4B3FE75E1F3CF68B00448EE4 /* CPM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B3FE75C1F3CF68B00448EE4 /* CPM.cpp */; }; 4B448E811F1C45A00009ABD6 /* TZX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B448E7F1F1C45A00009ABD6 /* TZX.cpp */; }; 4B448E841F1C4C480009ABD6 /* PulseQueuedTape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B448E821F1C4C480009ABD6 /* PulseQueuedTape.cpp */; }; 4B44EBF51DC987AF00A7820C /* AllSuiteA.bin in Resources */ = {isa = PBXBuildFile; fileRef = 4B44EBF41DC987AE00A7820C /* AllSuiteA.bin */; }; @@ -562,6 +563,8 @@ 4B3BF5AF1F146264005B6C36 /* CSW.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CSW.hpp; sourceTree = ""; }; 4B3F1B441E0388D200DB26EE /* PCMPatchedTrack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PCMPatchedTrack.cpp; sourceTree = ""; }; 4B3F1B451E0388D200DB26EE /* PCMPatchedTrack.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = PCMPatchedTrack.hpp; sourceTree = ""; }; + 4B3FE75C1F3CF68B00448EE4 /* CPM.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CPM.cpp; path = Parsers/CPM.cpp; sourceTree = ""; }; + 4B3FE75D1F3CF68B00448EE4 /* CPM.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = CPM.hpp; path = Parsers/CPM.hpp; sourceTree = ""; }; 4B448E7F1F1C45A00009ABD6 /* TZX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TZX.cpp; sourceTree = ""; }; 4B448E801F1C45A00009ABD6 /* TZX.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = TZX.hpp; sourceTree = ""; }; 4B448E821F1C4C480009ABD6 /* PulseQueuedTape.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PulseQueuedTape.cpp; sourceTree = ""; }; @@ -1330,6 +1333,15 @@ path = Bridges; sourceTree = ""; }; + 4B3FE75F1F3CF6BA00448EE4 /* Parsers */ = { + isa = PBXGroup; + children = ( + 4B3FE75C1F3CF68B00448EE4 /* CPM.cpp */, + 4B3FE75D1F3CF68B00448EE4 /* CPM.hpp */, + ); + name = Parsers; + sourceTree = ""; + }; 4B4A762D1DB1A35C007AAE2E /* AY38910 */ = { isa = PBXGroup; children = ( @@ -1446,12 +1458,12 @@ 4B69FB3A1C4D908A00B5F0AA /* Tape */ = { isa = PBXGroup; children = ( + 4B448E821F1C4C480009ABD6 /* PulseQueuedTape.cpp */, + 4B69FB3B1C4D908A00B5F0AA /* Tape.cpp */, + 4B448E831F1C4C480009ABD6 /* PulseQueuedTape.hpp */, + 4B69FB3C1C4D908A00B5F0AA /* Tape.hpp */, 4B69FB411C4D941400B5F0AA /* Formats */, 4B8805F11DCFC9A2003085B1 /* Parsers */, - 4B448E821F1C4C480009ABD6 /* PulseQueuedTape.cpp */, - 4B448E831F1C4C480009ABD6 /* PulseQueuedTape.hpp */, - 4B69FB3B1C4D908A00B5F0AA /* Tape.cpp */, - 4B69FB3C1C4D908A00B5F0AA /* Tape.hpp */, ); path = Tape; sourceTree = ""; @@ -1545,6 +1557,7 @@ 4BAB62B71D3302CA00DF5BA0 /* PCMTrack.hpp */, 4BB697CF1D4BA44900248BDF /* Encodings */, 4BAB62B21D327F7E00DF5BA0 /* Formats */, + 4B3FE75F1F3CF6BA00448EE4 /* Parsers */, ); path = Disk; sourceTree = ""; @@ -2700,6 +2713,7 @@ 4B1497921EE4B5A800CE2596 /* ZX8081.cpp in Sources */, 4B643F3F1D77B88000D431D6 /* DocumentController.swift in Sources */, 4BA799951D8B656E0045123D /* StaticAnalyser.cpp in Sources */, + 4B3FE75E1F3CF68B00448EE4 /* CPM.cpp in Sources */, 4B2BFDB21DAEF5FF001A68B8 /* Video.cpp in Sources */, 4B4DC82B1D2C27A4003C5BF8 /* SerialBus.cpp in Sources */, 4BC3B74F1CD194CC00F86E85 /* Shader.cpp in Sources */, diff --git a/StaticAnalyser/AmstradCPC/StaticAnalyser.cpp b/StaticAnalyser/AmstradCPC/StaticAnalyser.cpp index 8e15fdd2b..9f0b2273f 100644 --- a/StaticAnalyser/AmstradCPC/StaticAnalyser.cpp +++ b/StaticAnalyser/AmstradCPC/StaticAnalyser.cpp @@ -7,6 +7,7 @@ // #include "StaticAnalyser.hpp" +#include "../../Storage/Disk/Parsers/CPM.hpp" void StaticAnalyser::AmstradCPC::AddTargets( const std::list> &disks, @@ -22,5 +23,17 @@ void StaticAnalyser::AmstradCPC::AddTargets( target.amstradcpc.model = target.disks.empty() ? AmstradCPCModel::CPC464 : AmstradCPCModel::CPC6128; + if(!target.disks.empty()) { + // This is CPC data format. + Storage::Disk::CPM::ParameterBlock parameters; + parameters.sectors_per_track = 9; + parameters.sector_size = 512; + parameters.first_sector = 0xc1; + parameters.catalogue_allocation_bitmap = 0xc000; + parameters.reserved_tracks = 0; + + Storage::Disk::CPM::GetCatalogue(target.disks.front(), parameters); + } + destination.push_back(target); } diff --git a/Storage/Disk/Parsers/CPM.cpp b/Storage/Disk/Parsers/CPM.cpp new file mode 100644 index 000000000..96302b788 --- /dev/null +++ b/Storage/Disk/Parsers/CPM.cpp @@ -0,0 +1,43 @@ +// +// CPM.cpp +// Clock Signal +// +// Created by Thomas Harte on 10/08/2017. +// Copyright © 2017 Thomas Harte. All rights reserved. +// + +#include "CPM.hpp" + +#include "../Encodings/MFM.hpp" + +using namespace Storage::Disk::CPM; + +std::unique_ptr Storage::Disk::CPM::GetCatalogue(const std::shared_ptr &disk, const ParameterBlock ¶meters) { + Storage::Encodings::MFM::Parser parser(true, disk); + + // Assemble the actual bytes of the catalogue. + std::vector catalogue; + uint16_t catalogue_allocation_bitmap = parameters.catalogue_allocation_bitmap; + int sector = 0; + int track = parameters.reserved_tracks; + while(catalogue_allocation_bitmap) { + if(catalogue_allocation_bitmap & 0x8000) { + std::shared_ptr sector_contents = parser.get_sector((uint8_t)track, (uint8_t)(parameters.first_sector + sector)); + if(!sector_contents) { + return nullptr; + } + + catalogue.insert(catalogue.end(), sector_contents->data.begin(), sector_contents->data.end()); + } + + catalogue_allocation_bitmap <<= 1; + + sector++; + if(sector == parameters.sectors_per_track) { + sector = 0; + track++; + } + } + + return nullptr; +} diff --git a/Storage/Disk/Parsers/CPM.hpp b/Storage/Disk/Parsers/CPM.hpp new file mode 100644 index 000000000..4ee333e98 --- /dev/null +++ b/Storage/Disk/Parsers/CPM.hpp @@ -0,0 +1,39 @@ +// +// CPM.hpp +// Clock Signal +// +// Created by Thomas Harte on 10/08/2017. +// Copyright © 2017 Thomas Harte. All rights reserved. +// + +#ifndef Storage_Disk_Parsers_CPM_hpp +#define Storage_Disk_Parsers_CPM_hpp + +#include "../Disk.hpp" +#include + +namespace Storage { +namespace Disk { +namespace CPM { + +struct ParameterBlock { + int sectors_per_track; + int sector_size; + int first_sector; + uint16_t catalogue_allocation_bitmap; + int reserved_tracks; +}; + +struct File { +}; + +struct Catalogue { +}; + +std::unique_ptr GetCatalogue(const std::shared_ptr &disk, const ParameterBlock ¶meters); + +} +} +} + +#endif /* Storage_Disk_Parsers_CPM_hpp */