From 239cecff9eb68c0dff97c0f2264ba902ea30e2ea Mon Sep 17 00:00:00 2001 From: David Given Date: Thu, 15 Jul 2021 23:43:07 +0200 Subject: [PATCH] Convert all the encoders and imagereaders to the new scheme. --- arch/amiga/encoder.cc | 5 +++-- arch/brother/encoder.cc | 5 +++-- arch/c64/encoder.cc | 7 +++--- arch/ibm/encoder.cc | 5 +++-- arch/macintosh/encoder.cc | 5 +++-- arch/northstar/encoder.cc | 7 +++--- arch/tids990/encoder.cc | 5 +++-- lib/encoders/encoders.h | 5 ++--- lib/image.h | 11 ++++----- lib/imagereader/d64imagereader.cc | 23 ++++++++++--------- lib/imagereader/diskcopyimagereader.cc | 18 ++++++++++----- lib/imagereader/imagereader.cc | 1 + lib/imagereader/imagereader.h | 3 ++- lib/imagereader/imdimagereader.cc | 18 ++++++++++----- lib/imagereader/imgimagereader.cc | 14 +++++++----- lib/imagereader/jv3imagereader.cc | 11 ++++----- lib/imagereader/nsiimagereader.cc | 31 ++++++++++++++++---------- lib/writer.cc | 5 +++-- 18 files changed, 108 insertions(+), 71 deletions(-) diff --git a/arch/amiga/encoder.cc b/arch/amiga/encoder.cc index 4859393a..832fe9c1 100644 --- a/arch/amiga/encoder.cc +++ b/arch/amiga/encoder.cc @@ -6,6 +6,7 @@ #include "crc.h" #include "sectorset.h" #include "writer.h" +#include "image.h" #include "arch/amiga/amiga.pb.h" #include "lib/encoders/encoders.pb.h" @@ -105,7 +106,7 @@ public: _config(config.amiga()) {} public: - std::unique_ptr encode(int physicalTrack, int physicalSide, const SectorSet& allSectors) + std::unique_ptr encode(int physicalTrack, int physicalSide, const Image& image) { if ((physicalTrack < 0) || (physicalTrack >= AMIGA_TRACKS_PER_DISK)) return std::unique_ptr(); @@ -119,7 +120,7 @@ public: for (int sectorId=0; sectorId encode(int physicalTrack, int physicalSide, const SectorSet& allSectors) + std::unique_ptr encode(int physicalTrack, int physicalSide, const Image& image) { int logicalTrack; if (physicalSide != 0) @@ -172,7 +173,7 @@ public: double dataMs = headerMs + postHeaderSpacingMs; unsigned dataCursor = dataMs*1e3 / clockRateUs; - const auto& sectorData = allSectors.get(logicalTrack, 0, sectorId); + const auto* sectorData = image.get(logicalTrack, 0, sectorId); fillBitmapTo(bits, cursor, headerCursor, { true, false }); write_sector_header(bits, cursor, logicalTrack, sectorId); diff --git a/arch/c64/encoder.cc b/arch/c64/encoder.cc index 53f74be7..b11ac53d 100644 --- a/arch/c64/encoder.cc +++ b/arch/c64/encoder.cc @@ -7,6 +7,7 @@ #include "sectorset.h" #include "sector.h" #include "writer.h" +#include "image.h" #include "fmt/format.h" #include "arch/c64/c64.pb.h" #include "lib/encoders/encoders.pb.h" @@ -212,7 +213,7 @@ public: {} public: - std::unique_ptr encode(int physicalTrack, int physicalSide, const SectorSet& allSectors) + std::unique_ptr encode(int physicalTrack, int physicalSide, const Image& image) { /* The format ID Character # 1 and # 2 are in the .d64 image only present * in track 18 sector zero which contains the BAM info in byte 162 and 163. @@ -221,7 +222,7 @@ public: * contains the BAM. */ - const auto& sectorData = allSectors.get(C64_BAM_TRACK*2, 0, 0); //Read de BAM to get the DISK ID bytes + const auto* sectorData = image.get(C64_BAM_TRACK*2, 0, 0); //Read de BAM to get the DISK ID bytes if (sectorData) { ByteReader br(sectorData->data); @@ -247,7 +248,7 @@ public: unsigned writtenSectors = 0; for (int sectorId=0; sectorId encode(int physicalTrack, int physicalSide, const SectorSet& allSectors) + std::unique_ptr encode(int physicalTrack, int physicalSide, const Image& image) { IbmEncoderProto::TrackdataProto trackdata; getTrackFormat(trackdata, physicalTrack, physicalSide); @@ -175,7 +176,7 @@ public: writeFillerBytes(trackdata.gap3(), gapFill); first = false; - const auto& sectorData = allSectors.get(physicalTrack, physicalSide, sectorId); + const auto* sectorData = image.get(physicalTrack, physicalSide, sectorId); if (!sectorData) { /* If there are any missing sectors, this is an empty track. */ diff --git a/arch/macintosh/encoder.cc b/arch/macintosh/encoder.cc index 84e6b6db..26025a51 100644 --- a/arch/macintosh/encoder.cc +++ b/arch/macintosh/encoder.cc @@ -6,6 +6,7 @@ #include "crc.h" #include "sectorset.h" #include "writer.h" +#include "image.h" #include "fmt/format.h" #include "lib/encoders/encoders.pb.h" #include "arch/macintosh/macintosh.pb.h" @@ -209,7 +210,7 @@ public: {} public: - std::unique_ptr encode(int physicalTrack, int physicalSide, const SectorSet& allSectors) + std::unique_ptr encode(int physicalTrack, int physicalSide, const Image& image) { if ((physicalTrack < 0) || (physicalTrack >= MAC_TRACKS_PER_DISK)) return std::unique_ptr(); @@ -225,7 +226,7 @@ public: unsigned numSectors = sectorsForTrack(physicalTrack); for (int sectorId=0; sectorId encode(int physicalTrack, int physicalSide, const SectorSet& allSectors) + std::unique_ptr encode(int physicalTrack, int physicalSide, const Image& image) { int bitsPerRevolution = 100000; double clockRateUs = 4.00; @@ -116,7 +117,7 @@ public: if ((physicalTrack < 0) || (physicalTrack >= 35)) return std::unique_ptr(); - const auto& sector = allSectors.get(physicalTrack, physicalSide, 0); + const auto* sector = image.get(physicalTrack, physicalSide, 0); if (sector->data.size() == NORTHSTAR_PAYLOAD_SIZE_SD) { bitsPerRevolution /= 2; // FM @@ -129,7 +130,7 @@ public: for (int sectorId = 0; sectorId < 10; sectorId++) { - const auto& sectorData = allSectors.get(physicalTrack, physicalSide, sectorId); + const auto* sectorData = image.get(physicalTrack, physicalSide, sectorId); write_sector(bits, cursor, sectorData); } diff --git a/arch/tids990/encoder.cc b/arch/tids990/encoder.cc index d0bff891..82213047 100644 --- a/arch/tids990/encoder.cc +++ b/arch/tids990/encoder.cc @@ -6,6 +6,7 @@ #include "crc.h" #include "sectorset.h" #include "writer.h" +#include "image.h" #include "arch/tids990/tids990.pb.h" #include "lib/encoders/encoders.pb.h" #include @@ -60,7 +61,7 @@ private: } public: - std::unique_ptr encode(int physicalTrack, int physicalSide, const SectorSet& allSectors) + std::unique_ptr encode(int physicalTrack, int physicalSide, const Image& image) { double clockRateUs = 1e3 / _config.clock_rate_khz() / 2.0; int bitsPerRevolution = (_config.track_length_ms() * 1000.0) / clockRateUs; @@ -80,7 +81,7 @@ public: writeBytes(_config.gap3_bytes(), 0x55); first = false; - const auto& sectorData = allSectors.get(physicalTrack, physicalSide, sectorId); + const auto* sectorData = image.get(physicalTrack, physicalSide, sectorId); if (!sectorData) Error() << fmt::format("format tried to find sector {} which wasn't in the input file", sectorId); diff --git a/lib/encoders/encoders.h b/lib/encoders/encoders.h index 6bd6674f..0994be08 100644 --- a/lib/encoders/encoders.h +++ b/lib/encoders/encoders.h @@ -1,10 +1,9 @@ #ifndef ENCODERS_H #define ENCODERS_H -class FluxSource; class Fluxmap; -class SectorSet; class EncoderProto; +class Image; class AbstractEncoder { @@ -15,7 +14,7 @@ public: public: virtual std::unique_ptr encode( - int physicalTrack, int physicalSide, const SectorSet& allSectors) = 0; + int physicalCylinder, int physicalHead, const Image& image) = 0; }; #endif diff --git a/lib/image.h b/lib/image.h index 59c8a4fa..e288dc38 100644 --- a/lib/image.h +++ b/lib/image.h @@ -3,10 +3,11 @@ struct Geometry { - unsigned numTracks; - unsigned numSides; - unsigned numSectors; - unsigned sectorSize; + unsigned numTracks = 0; + unsigned numSides = 0; + unsigned numSectors = 0; + unsigned sectorSize = 0; + bool irregular = false; }; class Image @@ -43,7 +44,7 @@ public: const_iterator begin() const { return const_iterator(_sectors.cbegin()); } const_iterator end() const { return const_iterator(_sectors.cend()); } - void setGeometry(Geometry& geometry) { _geometry = geometry; } + void setGeometry(Geometry geometry) { _geometry = geometry; } const Geometry& getGeometry() const { return _geometry; } private: diff --git a/lib/imagereader/d64imagereader.cc b/lib/imagereader/d64imagereader.cc index 08e9c691..1e7d0433 100644 --- a/lib/imagereader/d64imagereader.cc +++ b/lib/imagereader/d64imagereader.cc @@ -4,6 +4,7 @@ #include "sectorset.h" #include "imagereader/imagereader.h" #include "fmt/format.h" +#include "image.h" #include "proto.h" #include #include @@ -16,7 +17,7 @@ public: ImageReader(config) {} - SectorSet readImage() + Image readImage() { std::ifstream inputFile(_config.filename(), std::ios::in | std::ios::binary); if (!inputFile.is_open()) @@ -53,7 +54,7 @@ public: return 17; }; - SectorSet sectors; + Image image; for (int track = 0; track < 40; track++) { int numSectors = sectorsPerTrack(track); @@ -62,24 +63,22 @@ public: { for (int sectorId = 0; sectorId < numSectors; sectorId++) { - if ((offset < inputFileSize)) - { //still data available sector OK - br.seek(offset); + Sector* sector = image.put(track, head, sectorId); + if ((offset < inputFileSize)) + { //still data available sector OK + br.seek(offset); Bytes payload = br.read(256); offset += 256; - std::unique_ptr& sector = sectors.get(physicalCylinder, head, sectorId); - sector.reset(new Sector); sector->status = Sector::OK; sector->logicalTrack = track; sector->physicalCylinder = physicalCylinder; sector->logicalSide = sector->physicalHead = head; sector->logicalSector = sectorId; sector->data.writer().append(payload); - } else + } + else { //no more data in input file. Write sectors with status: DATA_MISSING - std::unique_ptr& sector = sectors.get(physicalCylinder, head, sectorId); - sector.reset(new Sector); sector->status = Sector::DATA_MISSING; sector->logicalTrack = track; sector->physicalCylinder = physicalCylinder; @@ -89,7 +88,9 @@ public: } } } - return sectors; + + image.calculateSize(); + return image; } }; diff --git a/lib/imagereader/diskcopyimagereader.cc b/lib/imagereader/diskcopyimagereader.cc index 43d19a4f..441255f7 100644 --- a/lib/imagereader/diskcopyimagereader.cc +++ b/lib/imagereader/diskcopyimagereader.cc @@ -3,6 +3,7 @@ #include "sector.h" #include "sectorset.h" #include "imagereader/imagereader.h" +#include "image.h" #include "lib/config.pb.h" #include "fmt/format.h" #include @@ -16,7 +17,7 @@ public: ImageReader(config) {} - SectorSet readImage() + Image readImage() { std::ifstream inputFile(_config.filename(), std::ios::in | std::ios::binary); if (!inputFile.is_open()) @@ -89,7 +90,7 @@ public: uint32_t dataPtr = 0x54; uint32_t tagPtr = dataPtr + dataSize; - SectorSet sectors; + Image image; for (int track = 0; track < numCylinders; track++) { int numSectors = sectorsPerTrack(track); @@ -105,8 +106,7 @@ public: Bytes tag = br.read(12); tagPtr += 12; - std::unique_ptr& sector = sectors.get(track, head, sectorId); - sector.reset(new Sector); + Sector* sector = image.put(track, head, sectorId); sector->status = Sector::OK; sector->logicalTrack = sector->physicalCylinder = track; sector->logicalSide = sector->physicalHead = head; @@ -115,7 +115,15 @@ public: } } } - return sectors; + + image.setGeometry({ + .numTracks = numCylinders, + .numSides = numHeads, + .numSectors = 12, + .sectorSize = 512 + 12, + .irregular = true + }); + return image; } }; diff --git a/lib/imagereader/imagereader.cc b/lib/imagereader/imagereader.cc index d6a1c25c..3c8a4795 100644 --- a/lib/imagereader/imagereader.cc +++ b/lib/imagereader/imagereader.cc @@ -6,6 +6,7 @@ #include "utils.h" #include "fmt/format.h" #include "proto.h" +#include "image.h" #include "lib/config.pb.h" #include #include diff --git a/lib/imagereader/imagereader.h b/lib/imagereader/imagereader.h index 5fe44054..843420cf 100644 --- a/lib/imagereader/imagereader.h +++ b/lib/imagereader/imagereader.h @@ -4,6 +4,7 @@ class SectorSet; class ImageSpec; class ImageReaderProto; +class Image; class ImageReader { @@ -24,7 +25,7 @@ public: static std::unique_ptr createNsiImageReader(const ImageReaderProto& config); public: - virtual SectorSet readImage() = 0; + virtual Image readImage() = 0; protected: const ImageReaderProto& _config; diff --git a/lib/imagereader/imdimagereader.cc b/lib/imagereader/imdimagereader.cc index 79fa0ce0..51eae370 100644 --- a/lib/imagereader/imdimagereader.cc +++ b/lib/imagereader/imdimagereader.cc @@ -3,6 +3,7 @@ #include "sector.h" #include "sectorset.h" #include "imagereader/imagereader.h" +#include "image.h" #include "lib/config.pb.h" #include "fmt/format.h" #include @@ -47,6 +48,7 @@ static unsigned getModulationandSpeed(uint8_t flags, bool *mfm) default: Error() << fmt::format("don't understand IMD disks with this modulation and speed {}", flags); + throw 0; } } @@ -88,7 +90,7 @@ public: ImageReader(config) {} - SectorSet readImage() + Image readImage() /* IMAGE FILE FORMAT The overall layout of an ImageDisk .IMD image file is: @@ -120,7 +122,7 @@ public: Bytes data; data.writer() += inputFile; ByteReader br(data); - SectorSet sectors; + Image image; TrackHeader header = {0, 0, 0, 0, 0}; unsigned n = 0; @@ -191,8 +193,7 @@ public: for (int s = 0; s < header.numSectors; s++) { Bytes sectordata; - std::unique_ptr& sector = sectors.get(header.track, header.Head, sector_map[s]); - sector.reset(new Sector); + Sector* sector = image.put(header.track, header.Head, sector_map[s]); //read the status of the sector unsigned int Status_Sector = br.read_8(); headerPtr++; @@ -259,6 +260,13 @@ public: } //Write format detected in IMD image to screen to help user set the right write parameters + image.setGeometry({ + .numTracks = header.track, + .numSides = header.Head + 1U, + .numSectors = header.numSectors, + .sectorSize = sectorSize + }); + size_t headSize = header.numSectors * sectorSize; size_t trackSize = headSize * (header.Head + 1); @@ -268,7 +276,7 @@ public: mfm ? "MFM" : "FM", Modulation_Speed, header.numSectors, sectorSize, sector_skew, (header.track+1) * trackSize / 1024); - return sectors; + return image; } }; diff --git a/lib/imagereader/imgimagereader.cc b/lib/imagereader/imgimagereader.cc index cf8452d6..b44433f1 100644 --- a/lib/imagereader/imgimagereader.cc +++ b/lib/imagereader/imgimagereader.cc @@ -3,6 +3,7 @@ #include "sector.h" #include "sectorset.h" #include "imagereader/imagereader.h" +#include "image.h" #include "lib/config.pb.h" #include "fmt/format.h" #include @@ -16,13 +17,13 @@ public: ImageReader(config) {} - SectorSet readImage() + Image readImage() { std::ifstream inputFile(_config.filename(), std::ios::in | std::ios::binary); if (!inputFile.is_open()) Error() << "cannot open input file"; - SectorSet sectors; + Image image; int trackCount = 0; for (int track = 0; track < _config.img().tracks(); track++) { @@ -40,8 +41,7 @@ public: Bytes data(trackdata.sector_size()); inputFile.read((char*) data.begin(), data.size()); - std::unique_ptr& sector = sectors.get(physicalCylinder, side, sectorId); - sector.reset(new Sector); + Sector* sector = image.put(physicalCylinder, side, sectorId); sector->status = Sector::OK; sector->logicalTrack = track; sector->physicalCylinder = physicalCylinder; @@ -54,10 +54,12 @@ public: trackCount++; } + image.calculateSize(); + const Geometry& geometry = image.getGeometry(); std::cout << fmt::format("reading {} tracks, {} sides, {} kB total\n", - trackCount, _config.img().sides(), + geometry.numTracks, geometry.numSides, inputFile.tellg() / 1024); - return sectors; + return image; } private: diff --git a/lib/imagereader/jv3imagereader.cc b/lib/imagereader/jv3imagereader.cc index 4ec41c9b..c0aba345 100644 --- a/lib/imagereader/jv3imagereader.cc +++ b/lib/imagereader/jv3imagereader.cc @@ -3,6 +3,7 @@ #include "sector.h" #include "sectorset.h" #include "imagereader/imagereader.h" +#include "image.h" #include "fmt/format.h" #include "lib/config.pb.h" #include @@ -81,7 +82,7 @@ public: ImageReader(config) {} - SectorSet readImage() + Image readImage() { std::ifstream inputFile(_config.filename(), std::ios::in | std::ios::binary); if (!inputFile.is_open()) @@ -90,7 +91,7 @@ public: inputFile.seekg( 0, std::ios::end); unsigned inputFileSize = inputFile.tellg(); unsigned headerPtr = 0; - SectorSet sectors; + Image image; for (;;) { unsigned dataPtr = headerPtr + 2901*3 + 1; @@ -110,8 +111,7 @@ public: inputFile.read((char*) data.begin(), sectorSize); unsigned head = !!(header.flags & JV3_SIDE); - std::unique_ptr& sector = sectors.get(header.track, head, header.sector); - sector.reset(new Sector); + Sector* sector = image.put(header.track, head, header.sector); sector->status = Sector::OK; sector->logicalTrack = sector->physicalCylinder = header.track; sector->logicalSide = sector->physicalHead = head; @@ -128,7 +128,8 @@ public: headerPtr = dataPtr; } - return sectors; + image.calculateSize(); + return image; } }; diff --git a/lib/imagereader/nsiimagereader.cc b/lib/imagereader/nsiimagereader.cc index d1f261fb..0ded1b8f 100644 --- a/lib/imagereader/nsiimagereader.cc +++ b/lib/imagereader/nsiimagereader.cc @@ -5,6 +5,7 @@ #include "sector.h" #include "sectorset.h" #include "imagereader/imagereader.h" +#include "image.h" #include "fmt/format.h" #include "lib/imagereader/imagereader.pb.h" #include @@ -18,7 +19,7 @@ public: ImageReader(config) {} - SectorSet readImage() + Image readImage() { std::ifstream inputFile(_config.filename(), std::ios::in | std::ios::binary); if (!inputFile.is_open()) @@ -31,10 +32,10 @@ public: std::cout << "NSI: Autodetecting geometry based on file size: " << fsize << std::endl; - int numCylinders = 35; - int numSectors = 10; - int numHeads = 2; - int sectorSize = 512; + unsigned numCylinders = 35; + unsigned numSectors = 10; + unsigned numHeads = 2; + unsigned sectorSize = 512; switch (fsize) { case 358400: @@ -64,14 +65,14 @@ public: numCylinders * numHeads * trackSize / 1024) << std::endl; - SectorSet sectors; + Image image; unsigned sectorFileOffset; - for (int head = 0; head < numHeads; head++) + for (unsigned head = 0; head < numHeads; head++) { - for (int track = 0; track < numCylinders; track++) + for (unsigned track = 0; track < numCylinders; track++) { - for (int sectorId = 0; sectorId < numSectors; sectorId++) + for (unsigned sectorId = 0; sectorId < numSectors; sectorId++) { if (head == 0) { /* Head 0 is from track 0-34 */ sectorFileOffset = track * trackSize + sectorId * sectorSize; @@ -87,8 +88,7 @@ public: Bytes data(sectorSize); inputFile.read((char*) data.begin(), sectorSize); - std::unique_ptr& sector = sectors.get(track, head, sectorId); - sector.reset(new Sector); + Sector* sector = image.put(track, head, sectorId); sector->status = Sector::OK; sector->logicalTrack = sector->physicalCylinder = track; sector->logicalSide = sector->physicalHead = head; @@ -97,7 +97,14 @@ public: } } } - return sectors; + + image.setGeometry({ + .numTracks = numCylinders, + .numSides = numHeads, + .numSectors = numSectors, + .sectorSize = sectorSize + }); + return image; } }; diff --git a/lib/writer.cc b/lib/writer.cc index 7f51eb54..c7507a2f 100644 --- a/lib/writer.cc +++ b/lib/writer.cc @@ -13,6 +13,7 @@ #include "record.h" #include "sector.h" #include "sectorset.h" +#include "image.h" #include "lib/config.pb.h" #include "proto.h" @@ -67,11 +68,11 @@ void fillBitmapTo(std::vector& bitmap, void writeDiskCommand(ImageReader& imageReader, AbstractEncoder& encoder, FluxSink& fluxSink) { - SectorSet allSectors = imageReader.readImage(); + Image image = imageReader.readImage(); writeTracks(fluxSink, [&](int physicalTrack, int physicalSide) -> std::unique_ptr { - return encoder.encode(physicalTrack, physicalSide, allSectors); + return encoder.encode(physicalTrack, physicalSide, image); } ); }