From 548e07ce17f34a48c7d58060863ee50428a4bad8 Mon Sep 17 00:00:00 2001 From: David Given Date: Tue, 22 Feb 2022 22:51:14 +0100 Subject: [PATCH 1/3] Fix off-by-one error in the MX decoder. --- arch/mx/decoder.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mx/decoder.cc b/arch/mx/decoder.cc index 94de4082..25b5ca59 100644 --- a/arch/mx/decoder.cc +++ b/arch/mx/decoder.cc @@ -38,7 +38,7 @@ public: nanoseconds_t advanceToNextRecord() override { - if (_currentSector == 10) + if (_currentSector == 11) { /* That was the last sector on the disk. */ return 0; From b5c3e75f10852127cf5394ce9928ad332a82c846 Mon Sep 17 00:00:00 2001 From: David Given Date: Tue, 22 Feb 2022 23:39:08 +0100 Subject: [PATCH 2/3] Fix the new logger output. --- lib/globals.h | 3 + lib/logger.cc | 165 ++++++++++++++++++++++++++++---------------------- lib/logger.h | 10 ++- 3 files changed, 102 insertions(+), 76 deletions(-) diff --git a/lib/globals.h b/lib/globals.h index 9ec85182..702d84a2 100644 --- a/lib/globals.h +++ b/lib/globals.h @@ -50,4 +50,7 @@ private: std::stringstream _stream; }; +template struct overloaded : Ts... { using Ts::operator()...; }; +template overloaded(Ts...) -> overloaded; + #endif diff --git a/lib/logger.cc b/lib/logger.cc index 562f5e96..823d800e 100644 --- a/lib/logger.cc +++ b/lib/logger.cc @@ -6,124 +6,141 @@ #include "fmt/format.h" #include "logger.h" -template -struct overloaded : Ts... -{ - using Ts::operator()...; -}; -template -overloaded(Ts...) -> overloaded; - static bool indented = false; +static std::function)> loggerImpl = + Logger::textLogger; -static void indent() +Logger& Logger::operator<<(std::shared_ptr message) { - if (!indented) - std::cout << " "; - indented = false; + loggerImpl(message); + return *this; } -Logger& Logger::operator<<(std::shared_ptr message) +void Logger::setLogger( + std::function)> cb) { + loggerImpl = cb; +} + +void Logger::textLogger(std::shared_ptr message) +{ + std::cout << toString(*message) << std::flush; +} + +std::string Logger::toString(const AnyLogMessage& message) +{ + std::stringstream stream; + + auto indent = [&]() { + if (!indented) + stream << " "; + indented = false; + }; + std::visit( overloaded{ /* Fallback --- do nothing */ - [](const auto& m) + [&](const auto& m) { }, - /* Start measuring the rotational speed */ - [](const BeginSpeedOperationLogMessage& m) - { - std::cout << "Measuring rotational speed... " << std::flush; - }, - - /* Finish measuring the rotational speed */ - [](const EndSpeedOperationLogMessage& m) - { - std::cout << fmt::format("{:.1f}ms ({:.1f}rpm)\n", - m.rotationalPeriod / 1e6, - 60e9 / m.rotationalPeriod); - }, - - /* Indicates that we're working on a given cylinder and head */ - [](const DiskContextLogMessage& m) + /* Start measuring the rotational speed */ + [&](const BeginSpeedOperationLogMessage& m) { - std::cout << fmt::format("{:2}.{}: ", m.cylinder, m.head) - << std::flush; + stream << "Measuring rotational speed... "; + }, + + /* Finish measuring the rotational speed */ + [&](const EndSpeedOperationLogMessage& m) + { + stream << fmt::format("{:.1f}ms ({:.1f}rpm)\n", + m.rotationalPeriod / 1e6, + 60e9 / m.rotationalPeriod); + }, + + /* Indicates that we're working on a given cylinder and head */ + [&](const DiskContextLogMessage& m) + { + stream << fmt::format("{:2}.{}: ", m.cylinder, m.head); indented = true; }, /* A single read has happened */ - [](const SingleReadLogMessage& m) + [&](const SingleReadLogMessage& m) { - const auto& trackdataflux = m.trackDataFlux; + const auto& trackdataflux = m.trackDataFlux; indent(); - std::cout << fmt::format("{} records, {} sectors", + stream << fmt::format("{} records, {} sectors", trackdataflux->records.size(), trackdataflux->sectors.size()); if (trackdataflux->sectors.size() > 0) { nanoseconds_t clock = (*trackdataflux->sectors.begin())->clock; - std::cout << fmt::format("; {:.2f}us clock ({:.0f}kHz)", + stream << fmt::format("; {:.2f}us clock ({:.0f}kHz)", clock / 1000.0, 1000000.0 / clock); } - std::cout << '\n'; + stream << '\n'; - indent(); - std::cout << "sectors:"; + indent(); + stream << "sectors:"; - std::vector> sectors(m.sectors.begin(), m.sectors.end()); - std::sort(sectors.begin(), sectors.end(), - [](const std::shared_ptr& s1, const std::shared_ptr&s2) - { - return s1->logicalSector < s2->logicalSector; - } - ); + std::vector> sectors( + m.sectors.begin(), m.sectors.end()); + std::sort(sectors.begin(), + sectors.end(), + [](const std::shared_ptr& s1, + const std::shared_ptr& s2) + { + return s1->logicalSector < s2->logicalSector; + }); - for (const auto& sector : sectors) - std::cout << fmt::format(" {}{}", sector->logicalSector, Sector::statusToChar(sector->status)); + for (const auto& sector : sectors) + stream << fmt::format(" {}{}", + sector->logicalSector, + Sector::statusToChar(sector->status)); - std::cout << '\n'; + stream << '\n'; }, - /* We've finished reading a track */ - [](const TrackReadLogMessage& m) - { - int size = 0; - std::set> track_ids; - for (const auto& sector : m.track->sectors) - { - track_ids.insert(std::make_pair(sector->logicalTrack, sector->logicalSide)); - size += sector->data.size(); - } + /* We've finished reading a track */ + [&](const TrackReadLogMessage& m) + { + int size = 0; + std::set> track_ids; + for (const auto& sector : m.track->sectors) + { + track_ids.insert(std::make_pair( + sector->logicalTrack, sector->logicalSide)); + size += sector->data.size(); + } - if (!track_ids.empty()) - { - std::vector ids; + if (!track_ids.empty()) + { + std::vector ids; - for (const auto& i : track_ids) - ids.push_back(fmt::format("{}.{}", i.first, i.second)); + for (const auto& i : track_ids) + ids.push_back(fmt::format("{}.{}", i.first, i.second)); - indent(); - std::cout << fmt::format("logical track {}\n", fmt::join(ids, "; ")); - } + indent(); + stream << fmt::format( + "logical track {}\n", fmt::join(ids, "; ")); + } - indent(); - std::cout << fmt::format("{} bytes decoded\n", size); - }, + indent(); + stream << fmt::format("{} bytes decoded\n", size); + }, /* Generic text message */ - [](const std::string& s) + [&](const std::string& s) { indent(); - std::cout << s << '\n'; + stream << s << '\n'; }, }, - *message); - return *this; + message); + return stream.str(); } diff --git a/lib/logger.h b/lib/logger.h index f6039f9b..391c6a08 100644 --- a/lib/logger.h +++ b/lib/logger.h @@ -52,13 +52,19 @@ typedef std::variant message); + Logger& operator<<(std::shared_ptr message); template Logger& operator<<(const T& message) { - return *this << std::make_shared(message); + return *this << std::make_shared(message); } + + static void setLogger( + std::function)> cb); + + static std::string toString(const AnyLogMessage&); + static void textLogger(std::shared_ptr); }; #endif From 8d04d17e398f17195702247e96ba19e7c3224aac Mon Sep 17 00:00:00 2001 From: "Howard M. Harte" Date: Tue, 22 Feb 2022 22:45:39 -0800 Subject: [PATCH 3/3] Fix override warnings in decoders. --- arch/aeslanier/decoder.cc | 2 +- arch/apple2/decoder.cc | 4 ++-- arch/brother/decoder.cc | 4 ++-- arch/c64/decoder.cc | 4 ++-- arch/f85/decoder.cc | 4 ++-- arch/fb100/decoder.cc | 2 +- arch/macintosh/decoder.cc | 6 +++--- arch/micropolis/decoder.cc | 2 +- arch/mx/decoder.cc | 4 ++-- arch/tids990/decoder.cc | 4 ++-- arch/victor9k/decoder.cc | 4 ++-- arch/zilogmcz/decoder.cc | 2 +- 12 files changed, 21 insertions(+), 21 deletions(-) diff --git a/arch/aeslanier/decoder.cc b/arch/aeslanier/decoder.cc index f5d73a31..f2fcc41e 100644 --- a/arch/aeslanier/decoder.cc +++ b/arch/aeslanier/decoder.cc @@ -35,7 +35,7 @@ public: return seekToPattern(SECTOR_PATTERN); } - void decodeSectorRecord() + void decodeSectorRecord() override { /* Skip ID mark (we know it's a AESLANIER_RECORD_SEPARATOR). */ diff --git a/arch/apple2/decoder.cc b/arch/apple2/decoder.cc index a076be63..f046e6c8 100644 --- a/arch/apple2/decoder.cc +++ b/arch/apple2/decoder.cc @@ -76,7 +76,7 @@ public: return seekToPattern(ANY_RECORD_PATTERN); } - void decodeSectorRecord() + void decodeSectorRecord() override { if (readRaw24() != APPLE2_SECTOR_RECORD) return; @@ -94,7 +94,7 @@ public: _sector->status = Sector::DATA_MISSING; /* unintuitive but correct */ } - void decodeDataRecord() + void decodeDataRecord() override { /* Check ID. */ diff --git a/arch/brother/decoder.cc b/arch/brother/decoder.cc index e068aa25..9fbc4072 100644 --- a/arch/brother/decoder.cc +++ b/arch/brother/decoder.cc @@ -64,7 +64,7 @@ public: return seekToPattern(ANY_RECORD_PATTERN); } - void decodeSectorRecord() + void decodeSectorRecord() override { if (readRaw32() != BROTHER_SECTOR_RECORD) return; @@ -86,7 +86,7 @@ public: _sector->status = Sector::DATA_MISSING; } - void decodeDataRecord() + void decodeDataRecord() override { if (readRaw32() != BROTHER_DATA_RECORD) return; diff --git a/arch/c64/decoder.cc b/arch/c64/decoder.cc index 4c0c9419..5dd3ed30 100644 --- a/arch/c64/decoder.cc +++ b/arch/c64/decoder.cc @@ -63,7 +63,7 @@ public: return seekToPattern(ANY_RECORD_PATTERN); } - void decodeSectorRecord() + void decodeSectorRecord() override { if (readRaw20() != C64_SECTOR_RECORD) return; @@ -79,7 +79,7 @@ public: _sector->status = Sector::DATA_MISSING; /* unintuitive but correct */ } - void decodeDataRecord() + void decodeDataRecord() override { if (readRaw20() != C64_DATA_RECORD) return; diff --git a/arch/f85/decoder.cc b/arch/f85/decoder.cc index 149ca9b9..96f24815 100644 --- a/arch/f85/decoder.cc +++ b/arch/f85/decoder.cc @@ -63,7 +63,7 @@ public: return seekToPattern(ANY_RECORD_PATTERN); } - void decodeSectorRecord() + void decodeSectorRecord() override { /* Skip sync bits and ID byte. */ @@ -84,7 +84,7 @@ public: _sector->status = Sector::DATA_MISSING; /* unintuitive but correct */ } - void decodeDataRecord() + void decodeDataRecord() override { /* Skip sync bits ID byte. */ diff --git a/arch/fb100/decoder.cc b/arch/fb100/decoder.cc index 46fad9ca..fd5891f9 100644 --- a/arch/fb100/decoder.cc +++ b/arch/fb100/decoder.cc @@ -109,7 +109,7 @@ public: return seekToPattern(SECTOR_ID_PATTERN); } - void decodeSectorRecord() + void decodeSectorRecord() override { auto rawbits = readRawBits(FB100_RECORD_SIZE*16); diff --git a/arch/macintosh/decoder.cc b/arch/macintosh/decoder.cc index ca17993f..e20c6b37 100644 --- a/arch/macintosh/decoder.cc +++ b/arch/macintosh/decoder.cc @@ -134,7 +134,7 @@ public: return seekToPattern(ANY_RECORD_PATTERN); } - void decodeSectorRecord() + void decodeSectorRecord() override { if (readRaw24() != MAC_SECTOR_RECORD) return; @@ -163,7 +163,7 @@ public: _sector->status = Sector::DATA_MISSING; /* unintuitive but correct */ } - void decodeDataRecord() + void decodeDataRecord() override { if (readRaw24() != MAC_DATA_RECORD) return; @@ -183,7 +183,7 @@ public: _sector->data.writer().append(userData.slice(12, 512)).append(userData.slice(0, 12)); } - std::set requiredSectors(unsigned cylinder, unsigned head) const + std::set requiredSectors(unsigned cylinder, unsigned head) const override { int count; if (cylinder < 16) diff --git a/arch/micropolis/decoder.cc b/arch/micropolis/decoder.cc index 28b774c2..b9ad8146 100644 --- a/arch/micropolis/decoder.cc +++ b/arch/micropolis/decoder.cc @@ -106,7 +106,7 @@ public: return clock; } - void decodeSectorRecord() + void decodeSectorRecord() override { readRawBits(48); auto rawbits = readRawBits(MICROPOLIS_ENCODED_SECTOR_SIZE*16); diff --git a/arch/mx/decoder.cc b/arch/mx/decoder.cc index 25b5ca59..670d1517 100644 --- a/arch/mx/decoder.cc +++ b/arch/mx/decoder.cc @@ -30,7 +30,7 @@ public: AbstractDecoder(config) {} - void beginTrack() + void beginTrack() override { _clock = _sector->clock = seekToPattern(ID_PATTERN); _currentSector = 0; @@ -47,7 +47,7 @@ public: return _clock; } - void decodeSectorRecord() + void decodeSectorRecord() override { /* Skip the ID pattern and track word, which is only present on the * first sector. We don't trust the track word because some driver diff --git a/arch/tids990/decoder.cc b/arch/tids990/decoder.cc index c03e28e0..ebb2d2cb 100644 --- a/arch/tids990/decoder.cc +++ b/arch/tids990/decoder.cc @@ -52,7 +52,7 @@ public: return seekToPattern(ANY_RECORD_PATTERN); } - void decodeSectorRecord() + void decodeSectorRecord() override { auto bits = readRawBits(TIDS990_SECTOR_RECORD_SIZE*16); auto bytes = decodeFmMfm(bits).slice(0, TIDS990_SECTOR_RECORD_SIZE); @@ -74,7 +74,7 @@ public: _sector->status = Sector::DATA_MISSING; /* correct but unintuitive */ } - void decodeDataRecord() + void decodeDataRecord() override { auto bits = readRawBits(TIDS990_DATA_RECORD_SIZE*16); auto bytes = decodeFmMfm(bits).slice(0, TIDS990_DATA_RECORD_SIZE); diff --git a/arch/victor9k/decoder.cc b/arch/victor9k/decoder.cc index aa0df30c..50a349ea 100644 --- a/arch/victor9k/decoder.cc +++ b/arch/victor9k/decoder.cc @@ -64,7 +64,7 @@ public: return seekToPattern(ANY_RECORD_PATTERN); } - void decodeSectorRecord() + void decodeSectorRecord() override { /* Check the ID. */ @@ -89,7 +89,7 @@ public: _sector->status = Sector::DATA_MISSING; /* unintuitive but correct */ } - void decodeDataRecord() + void decodeDataRecord() override { /* Check the ID. */ diff --git a/arch/zilogmcz/decoder.cc b/arch/zilogmcz/decoder.cc index 20d01ee4..c39f0f6e 100644 --- a/arch/zilogmcz/decoder.cc +++ b/arch/zilogmcz/decoder.cc @@ -26,7 +26,7 @@ public: return seekToPattern(SECTOR_START_PATTERN); } - void decodeSectorRecord() + void decodeSectorRecord() override { readRawBits(14);