diff --git a/Storage/Disk/Encodings/MFM/Parser.cpp b/Storage/Disk/Encodings/MFM/Parser.cpp index 28a653a14..efc851042 100644 --- a/Storage/Disk/Encodings/MFM/Parser.cpp +++ b/Storage/Disk/Encodings/MFM/Parser.cpp @@ -14,6 +14,9 @@ using namespace Storage::Encodings::MFM; +Parser::Parser(const std::shared_ptr &disk) : + disk_(disk) {} + Parser::Parser(Density density, const std::shared_ptr &disk) : disk_(disk), density_(density) {} @@ -27,15 +30,30 @@ void Parser::install_track(const Storage::Disk::Track::Address &address) { return; } - std::map sectors = sectors_from_segment( - Storage::Disk::track_serialisation(*track, bit_length(density_)), - density_); - std::map sectors_by_id; - for(const auto §or : sectors) { - sectors_by_id.insert(std::make_pair(sector.second.address.sector, std::move(sector.second))); + if(density_) { + append(parse_track(*track, *density_), sectors_by_id); + return; + } else { + // Just try all three in succession. + append(parse_track(*track, Density::Single), sectors_by_id); + append(parse_track(*track, Density::Double), sectors_by_id); + append(parse_track(*track, Density::High), sectors_by_id);; + } + + sectors_by_address_by_track_.emplace(address, std::move(sectors_by_id)); +} + +SectorMap Parser::parse_track(const Storage::Disk::Track &track, Density density) { + return sectors_from_segment( + Storage::Disk::track_serialisation(track, bit_length(density)), + density); +} + +void Parser::append(const SectorMap &source, std::map &destination) { + for(const auto §or : source) { + destination.emplace(sector.second.address.sector, std::move(sector.second)); } - sectors_by_address_by_track_.insert(std::make_pair(address, std::move(sectors_by_id))); } const Sector *Parser::sector(int head, int track, uint8_t sector) { diff --git a/Storage/Disk/Encodings/MFM/Parser.hpp b/Storage/Disk/Encodings/MFM/Parser.hpp index 50cd35910..8bbd91291 100644 --- a/Storage/Disk/Encodings/MFM/Parser.hpp +++ b/Storage/Disk/Encodings/MFM/Parser.hpp @@ -11,9 +11,12 @@ #include "Constants.hpp" #include "Sector.hpp" +#include "SegmentParser.hpp" #include "../../Track/Track.hpp" #include "../../Drive.hpp" +#include + namespace Storage::Encodings::MFM { /*! @@ -21,8 +24,12 @@ namespace Storage::Encodings::MFM { */ class Parser { public: + /// Creates a parser that will only attempt to interpret the underlying disk as being of @c density. Parser(Density density, const std::shared_ptr &disk); + /// Creates a parser that will automatically try all available FM and MFM densities to try to extract sectors. + Parser(const std::shared_ptr &disk); + /*! Seeks to the physical track at @c head and @c track. Searches on it for a sector with logical address @c sector. @@ -31,11 +38,15 @@ class Parser { */ const Storage::Encodings::MFM::Sector *sector(int head, int track, uint8_t sector); + // TODO: set_sector. + private: std::shared_ptr disk_; - Density density_ = Density::Double; + std::optional density_; void install_track(const Storage::Disk::Track::Address &address); + static SectorMap parse_track(const Storage::Disk::Track &track, Density density); + static void append(const SectorMap &source, std::map &destination); // Maps from a track address, i.e. head and position, to a map from // sector IDs to sectors.