mirror of
https://github.com/davidgiven/fluxengine.git
synced 2025-10-31 11:17:01 -07:00
Another attempt at making filesystem sector ordering work again.
This commit is contained in:
@@ -6,57 +6,61 @@
|
||||
#include "fmt/format.h"
|
||||
#include "proto.h"
|
||||
#include "image.h"
|
||||
#include "lib/layout.h"
|
||||
#include "lib/config.pb.h"
|
||||
#include "lib/logger.h"
|
||||
#include <algorithm>
|
||||
#include <ctype.h>
|
||||
|
||||
std::unique_ptr<ImageReader> ImageReader::create(const ImageReaderProto& config)
|
||||
{
|
||||
switch (config.format_case())
|
||||
{
|
||||
case ImageReaderProto::kDim:
|
||||
return ImageReader::createDimImageReader(config);
|
||||
switch (config.format_case())
|
||||
{
|
||||
case ImageReaderProto::kDim:
|
||||
return ImageReader::createDimImageReader(config);
|
||||
|
||||
case ImageReaderProto::kD88:
|
||||
return ImageReader::createD88ImageReader(config);
|
||||
case ImageReaderProto::kD88:
|
||||
return ImageReader::createD88ImageReader(config);
|
||||
|
||||
case ImageReaderProto::kFdi:
|
||||
return ImageReader::createFdiImageReader(config);
|
||||
case ImageReaderProto::kFdi:
|
||||
return ImageReader::createFdiImageReader(config);
|
||||
|
||||
case ImageReaderProto::kImd:
|
||||
return ImageReader::createIMDImageReader(config);
|
||||
case ImageReaderProto::kImd:
|
||||
return ImageReader::createIMDImageReader(config);
|
||||
|
||||
case ImageReaderProto::kImg:
|
||||
return ImageReader::createImgImageReader(config);
|
||||
case ImageReaderProto::kImg:
|
||||
return ImageReader::createImgImageReader(config);
|
||||
|
||||
case ImageReaderProto::kDiskcopy:
|
||||
return ImageReader::createDiskCopyImageReader(config);
|
||||
case ImageReaderProto::kDiskcopy:
|
||||
return ImageReader::createDiskCopyImageReader(config);
|
||||
|
||||
case ImageReaderProto::kJv3:
|
||||
return ImageReader::createJv3ImageReader(config);
|
||||
case ImageReaderProto::kJv3:
|
||||
return ImageReader::createJv3ImageReader(config);
|
||||
|
||||
case ImageReaderProto::kD64:
|
||||
return ImageReader::createD64ImageReader(config);
|
||||
case ImageReaderProto::kD64:
|
||||
return ImageReader::createD64ImageReader(config);
|
||||
|
||||
case ImageReaderProto::kNfd:
|
||||
return ImageReader::createNFDImageReader(config);
|
||||
case ImageReaderProto::kNfd:
|
||||
return ImageReader::createNFDImageReader(config);
|
||||
|
||||
case ImageReaderProto::kNsi:
|
||||
return ImageReader::createNsiImageReader(config);
|
||||
case ImageReaderProto::kNsi:
|
||||
return ImageReader::createNsiImageReader(config);
|
||||
|
||||
case ImageReaderProto::kTd0:
|
||||
return ImageReader::createTd0ImageReader(config);
|
||||
case ImageReaderProto::kTd0:
|
||||
return ImageReader::createTd0ImageReader(config);
|
||||
|
||||
default:
|
||||
Error() << "bad input file config";
|
||||
return std::unique_ptr<ImageReader>();
|
||||
}
|
||||
default:
|
||||
Error() << "bad input file config";
|
||||
return std::unique_ptr<ImageReader>();
|
||||
}
|
||||
}
|
||||
|
||||
void ImageReader::updateConfigForFilename(ImageReaderProto* proto, const std::string& filename)
|
||||
void ImageReader::updateConfigForFilename(
|
||||
ImageReaderProto* proto, const std::string& filename)
|
||||
{
|
||||
static const std::map<std::string, std::function<void(ImageReaderProto*)>> formats =
|
||||
{
|
||||
static const std::map<std::string, std::function<void(ImageReaderProto*)>>
|
||||
formats = {
|
||||
// clang-format off
|
||||
{".adf", [](auto* proto) { proto->mutable_img(); }},
|
||||
{".d64", [](auto* proto) { proto->mutable_d64(); }},
|
||||
{".d81", [](auto* proto) { proto->mutable_img(); }},
|
||||
@@ -74,21 +78,43 @@ void ImageReader::updateConfigForFilename(ImageReaderProto* proto, const std::st
|
||||
{".td0", [](auto* proto) { proto->mutable_td0(); }},
|
||||
{".vgi", [](auto* proto) { proto->mutable_img(); }},
|
||||
{".xdf", [](auto* proto) { proto->mutable_img(); }},
|
||||
};
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
for (const auto& it : formats)
|
||||
{
|
||||
if (endsWith(filename, it.first))
|
||||
{
|
||||
it.second(proto);
|
||||
proto->set_filename(filename);
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (const auto& it : formats)
|
||||
{
|
||||
if (endsWith(filename, it.first))
|
||||
{
|
||||
it.second(proto);
|
||||
proto->set_filename(filename);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Error() << fmt::format("unrecognised image filename '{}'", filename);
|
||||
Error() << fmt::format("unrecognised image filename '{}'", filename);
|
||||
}
|
||||
|
||||
ImageReader::ImageReader(const ImageReaderProto& config):
|
||||
_config(config)
|
||||
{}
|
||||
ImageReader::ImageReader(const ImageReaderProto& config): _config(config) {}
|
||||
|
||||
std::unique_ptr<Image> ImageReader::readMappedImage()
|
||||
{
|
||||
auto rawImage = readImage();
|
||||
|
||||
if (!_config.filesystem_sector_order())
|
||||
return rawImage;
|
||||
|
||||
Logger() << "READER: converting from filesystem sector order to disk order";
|
||||
std::set<std::shared_ptr<const Sector>> sectors;
|
||||
for (const auto& e : *rawImage)
|
||||
{
|
||||
auto& trackLayout =
|
||||
Layout::getLayoutOfTrack(e->logicalTrack, e->logicalSide);
|
||||
auto newSector = std::make_shared<Sector>();
|
||||
*newSector = *e;
|
||||
newSector->logicalSector =
|
||||
trackLayout.filesystemToLogicalSectorMap.at(e->logicalSector);
|
||||
sectors.insert(newSector);
|
||||
}
|
||||
|
||||
return std::make_unique<Image>(sectors);
|
||||
}
|
||||
|
||||
@@ -9,32 +9,48 @@ class ImageReaderProto;
|
||||
class ImageReader
|
||||
{
|
||||
public:
|
||||
ImageReader(const ImageReaderProto& config);
|
||||
virtual ~ImageReader() {};
|
||||
ImageReader(const ImageReaderProto& config);
|
||||
virtual ~ImageReader(){};
|
||||
|
||||
public:
|
||||
static std::unique_ptr<ImageReader> create(const ImageReaderProto& config);
|
||||
static void updateConfigForFilename(ImageReaderProto* proto, const std::string& filename);
|
||||
static void updateConfigForFilename(
|
||||
ImageReaderProto* proto, const std::string& filename);
|
||||
|
||||
public:
|
||||
static std::unique_ptr<ImageReader> createD64ImageReader(const ImageReaderProto& config);
|
||||
static std::unique_ptr<ImageReader> createDiskCopyImageReader(const ImageReaderProto& config);
|
||||
static std::unique_ptr<ImageReader> createImgImageReader(const ImageReaderProto& config);
|
||||
static std::unique_ptr<ImageReader> createJv3ImageReader(const ImageReaderProto& config);
|
||||
static std::unique_ptr<ImageReader> createIMDImageReader(const ImageReaderProto& config);
|
||||
static std::unique_ptr<ImageReader> createNsiImageReader(const ImageReaderProto& config);
|
||||
static std::unique_ptr<ImageReader> createTd0ImageReader(const ImageReaderProto& config);
|
||||
static std::unique_ptr<ImageReader> createDimImageReader(const ImageReaderProto& config);
|
||||
static std::unique_ptr<ImageReader> createFdiImageReader(const ImageReaderProto& config);
|
||||
static std::unique_ptr<ImageReader> createD88ImageReader(const ImageReaderProto& config);
|
||||
static std::unique_ptr<ImageReader> createNFDImageReader(const ImageReaderProto& config);
|
||||
static std::unique_ptr<ImageReader> createD64ImageReader(
|
||||
const ImageReaderProto& config);
|
||||
static std::unique_ptr<ImageReader> createDiskCopyImageReader(
|
||||
const ImageReaderProto& config);
|
||||
static std::unique_ptr<ImageReader> createImgImageReader(
|
||||
const ImageReaderProto& config);
|
||||
static std::unique_ptr<ImageReader> createJv3ImageReader(
|
||||
const ImageReaderProto& config);
|
||||
static std::unique_ptr<ImageReader> createIMDImageReader(
|
||||
const ImageReaderProto& config);
|
||||
static std::unique_ptr<ImageReader> createNsiImageReader(
|
||||
const ImageReaderProto& config);
|
||||
static std::unique_ptr<ImageReader> createTd0ImageReader(
|
||||
const ImageReaderProto& config);
|
||||
static std::unique_ptr<ImageReader> createDimImageReader(
|
||||
const ImageReaderProto& config);
|
||||
static std::unique_ptr<ImageReader> createFdiImageReader(
|
||||
const ImageReaderProto& config);
|
||||
static std::unique_ptr<ImageReader> createD88ImageReader(
|
||||
const ImageReaderProto& config);
|
||||
static std::unique_ptr<ImageReader> createNFDImageReader(
|
||||
const ImageReaderProto& config);
|
||||
|
||||
public:
|
||||
virtual std::unique_ptr<Image> readImage() = 0;
|
||||
/* Directly reads the image. */
|
||||
virtual std::unique_ptr<Image> readImage() = 0;
|
||||
|
||||
/* Reads the image, and then applies any optional mapping to go from
|
||||
* filesystem ordering to disk ordering. */
|
||||
std::unique_ptr<Image> readMappedImage();
|
||||
|
||||
protected:
|
||||
const ImageReaderProto& _config;
|
||||
const ImageReaderProto& _config;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -2,8 +2,7 @@ syntax = "proto2";
|
||||
|
||||
import "lib/common.proto";
|
||||
|
||||
message ImgInputOutputProto {
|
||||
}
|
||||
message ImgInputOutputProto {}
|
||||
|
||||
message DiskCopyInputProto {}
|
||||
message ImdInputProto {}
|
||||
@@ -17,24 +16,26 @@ message D88InputProto {}
|
||||
message NFDInputProto {}
|
||||
|
||||
// NEXT_TAG: 14
|
||||
message ImageReaderProto {
|
||||
optional string filename = 1 [(help) = "filename of input sector image"];
|
||||
optional bool filesystem_sector_order = 13 [
|
||||
(help) = "read/write sector image in filesystem order",
|
||||
default = false ];
|
||||
message ImageReaderProto
|
||||
{
|
||||
optional string filename = 1 [ (help) = "filename of input sector image" ];
|
||||
optional bool filesystem_sector_order = 13 [
|
||||
(help) = "read/write sector image in filesystem order",
|
||||
default = false
|
||||
];
|
||||
|
||||
oneof format {
|
||||
ImgInputOutputProto img = 2;
|
||||
DiskCopyInputProto diskcopy = 3;
|
||||
ImdInputProto imd = 4;
|
||||
Jv3InputProto jv3 = 5;
|
||||
D64InputProto d64 = 6;
|
||||
NsiInputProto nsi = 7;
|
||||
Td0InputProto td0 = 8;
|
||||
DimInputProto dim = 9;
|
||||
FdiInputProto fdi = 10;
|
||||
D88InputProto d88 = 11;
|
||||
oneof format
|
||||
{
|
||||
ImgInputOutputProto img = 2;
|
||||
DiskCopyInputProto diskcopy = 3;
|
||||
ImdInputProto imd = 4;
|
||||
Jv3InputProto jv3 = 5;
|
||||
D64InputProto d64 = 6;
|
||||
NsiInputProto nsi = 7;
|
||||
Td0InputProto td0 = 8;
|
||||
DimInputProto dim = 9;
|
||||
FdiInputProto fdi = 10;
|
||||
D88InputProto d88 = 11;
|
||||
NFDInputProto nfd = 12;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,48 +6,52 @@
|
||||
#include "utils.h"
|
||||
#include "lib/config.pb.h"
|
||||
#include "proto.h"
|
||||
#include "lib/layout.h"
|
||||
#include "lib/logger.h"
|
||||
#include "fmt/format.h"
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
std::unique_ptr<ImageWriter> ImageWriter::create(const ImageWriterProto& config)
|
||||
{
|
||||
switch (config.format_case())
|
||||
{
|
||||
case ImageWriterProto::kImg:
|
||||
return ImageWriter::createImgImageWriter(config);
|
||||
switch (config.format_case())
|
||||
{
|
||||
case ImageWriterProto::kImg:
|
||||
return ImageWriter::createImgImageWriter(config);
|
||||
|
||||
case ImageWriterProto::kD64:
|
||||
return ImageWriter::createD64ImageWriter(config);
|
||||
case ImageWriterProto::kD64:
|
||||
return ImageWriter::createD64ImageWriter(config);
|
||||
|
||||
case ImageWriterProto::kLdbs:
|
||||
return ImageWriter::createLDBSImageWriter(config);
|
||||
case ImageWriterProto::kLdbs:
|
||||
return ImageWriter::createLDBSImageWriter(config);
|
||||
|
||||
case ImageWriterProto::kDiskcopy:
|
||||
return ImageWriter::createDiskCopyImageWriter(config);
|
||||
case ImageWriterProto::kDiskcopy:
|
||||
return ImageWriter::createDiskCopyImageWriter(config);
|
||||
|
||||
case ImageWriterProto::kNsi:
|
||||
return ImageWriter::createNsiImageWriter(config);
|
||||
case ImageWriterProto::kNsi:
|
||||
return ImageWriter::createNsiImageWriter(config);
|
||||
|
||||
case ImageWriterProto::kRaw:
|
||||
return ImageWriter::createRawImageWriter(config);
|
||||
case ImageWriterProto::kRaw:
|
||||
return ImageWriter::createRawImageWriter(config);
|
||||
|
||||
case ImageWriterProto::kD88:
|
||||
return ImageWriter::createD88ImageWriter(config);
|
||||
case ImageWriterProto::kD88:
|
||||
return ImageWriter::createD88ImageWriter(config);
|
||||
|
||||
case ImageWriterProto::kImd:
|
||||
return ImageWriter::createImdImageWriter(config);
|
||||
|
||||
default:
|
||||
Error() << "bad output image config";
|
||||
return std::unique_ptr<ImageWriter>();
|
||||
}
|
||||
case ImageWriterProto::kImd:
|
||||
return ImageWriter::createImdImageWriter(config);
|
||||
|
||||
default:
|
||||
Error() << "bad output image config";
|
||||
return std::unique_ptr<ImageWriter>();
|
||||
}
|
||||
}
|
||||
|
||||
void ImageWriter::updateConfigForFilename(ImageWriterProto* proto, const std::string& filename)
|
||||
void ImageWriter::updateConfigForFilename(
|
||||
ImageWriterProto* proto, const std::string& filename)
|
||||
{
|
||||
static const std::map<std::string, std::function<void(ImageWriterProto*)>> formats =
|
||||
{
|
||||
static const std::map<std::string, std::function<void(ImageWriterProto*)>>
|
||||
formats = {
|
||||
// clang-format off
|
||||
{".adf", [](auto* proto) { proto->mutable_img(); }},
|
||||
{".d64", [](auto* proto) { proto->mutable_d64(); }},
|
||||
{".d81", [](auto* proto) { proto->mutable_img(); }},
|
||||
@@ -62,105 +66,103 @@ void ImageWriter::updateConfigForFilename(ImageWriterProto* proto, const std::st
|
||||
{".st", [](auto* proto) { proto->mutable_img(); }},
|
||||
{".vgi", [](auto* proto) { proto->mutable_img(); }},
|
||||
{".xdf", [](auto* proto) { proto->mutable_img(); }},
|
||||
};
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
for (const auto& it : formats)
|
||||
{
|
||||
if (endsWith(filename, it.first))
|
||||
{
|
||||
it.second(proto);
|
||||
proto->set_filename(filename);
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (const auto& it : formats)
|
||||
{
|
||||
if (endsWith(filename, it.first))
|
||||
{
|
||||
it.second(proto);
|
||||
proto->set_filename(filename);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Error() << fmt::format("unrecognised image filename '{}'", filename);
|
||||
Error() << fmt::format("unrecognised image filename '{}'", filename);
|
||||
}
|
||||
|
||||
ImageWriter::ImageWriter(const ImageWriterProto& config):
|
||||
_config(config)
|
||||
{}
|
||||
ImageWriter::ImageWriter(const ImageWriterProto& config): _config(config) {}
|
||||
|
||||
void ImageWriter::writeCsv(const Image& image, const std::string& filename)
|
||||
{
|
||||
std::ofstream f(filename, std::ios::out);
|
||||
if (!f.is_open())
|
||||
Error() << "cannot open CSV report file";
|
||||
std::ofstream f(filename, std::ios::out);
|
||||
if (!f.is_open())
|
||||
Error() << "cannot open CSV report file";
|
||||
|
||||
f << "\"Physical track\","
|
||||
"\"Physical side\","
|
||||
"\"Logical sector\","
|
||||
"\"Logical track\","
|
||||
"\"Logical side\","
|
||||
"\"Clock (ns)\","
|
||||
"\"Header start (ns)\","
|
||||
"\"Header end (ns)\","
|
||||
"\"Data start (ns)\","
|
||||
"\"Data end (ns)\","
|
||||
"\"Raw data address (bytes)\","
|
||||
"\"User payload length (bytes)\","
|
||||
"\"Status\""
|
||||
"\n";
|
||||
f << "\"Physical track\","
|
||||
"\"Physical side\","
|
||||
"\"Logical sector\","
|
||||
"\"Logical track\","
|
||||
"\"Logical side\","
|
||||
"\"Clock (ns)\","
|
||||
"\"Header start (ns)\","
|
||||
"\"Header end (ns)\","
|
||||
"\"Data start (ns)\","
|
||||
"\"Data end (ns)\","
|
||||
"\"Raw data address (bytes)\","
|
||||
"\"User payload length (bytes)\","
|
||||
"\"Status\""
|
||||
"\n";
|
||||
|
||||
for (const auto& sector : image)
|
||||
{
|
||||
f << fmt::format("{},{},{},{},{},{},{},{},{},{},{},{},{}\n",
|
||||
sector->physicalTrack,
|
||||
sector->physicalHead,
|
||||
sector->logicalSector,
|
||||
sector->logicalTrack,
|
||||
sector->logicalSide,
|
||||
sector->clock,
|
||||
sector->headerStartTime,
|
||||
sector->headerEndTime,
|
||||
sector->dataStartTime,
|
||||
sector->dataEndTime,
|
||||
sector->position,
|
||||
sector->data.size(),
|
||||
Sector::statusToString(sector->status)
|
||||
);
|
||||
}
|
||||
for (const auto& sector : image)
|
||||
{
|
||||
f << fmt::format("{},{},{},{},{},{},{},{},{},{},{},{},{}\n",
|
||||
sector->physicalTrack,
|
||||
sector->physicalHead,
|
||||
sector->logicalSector,
|
||||
sector->logicalTrack,
|
||||
sector->logicalSide,
|
||||
sector->clock,
|
||||
sector->headerStartTime,
|
||||
sector->headerEndTime,
|
||||
sector->dataStartTime,
|
||||
sector->dataEndTime,
|
||||
sector->position,
|
||||
sector->data.size(),
|
||||
Sector::statusToString(sector->status));
|
||||
}
|
||||
}
|
||||
|
||||
void ImageWriter::printMap(const Image& image)
|
||||
{
|
||||
Geometry geometry = image.getGeometry();
|
||||
Geometry geometry = image.getGeometry();
|
||||
|
||||
int badSectors = 0;
|
||||
int missingSectors = 0;
|
||||
int totalSectors = 0;
|
||||
int badSectors = 0;
|
||||
int missingSectors = 0;
|
||||
int totalSectors = 0;
|
||||
|
||||
std::cout << " Tracks -> ";
|
||||
for (unsigned i = 10; i < geometry.numTracks; i += 10)
|
||||
std::cout << fmt::format("{:<10d}", i/10);
|
||||
std::cout << std::endl;
|
||||
std::cout << "H.SS ";
|
||||
for (unsigned i = 0; i < geometry.numTracks; i++)
|
||||
std::cout << fmt::format("{}", i%10);
|
||||
std::cout << std::endl;
|
||||
std::cout << " Tracks -> ";
|
||||
for (unsigned i = 10; i < geometry.numTracks; i += 10)
|
||||
std::cout << fmt::format("{:<10d}", i / 10);
|
||||
std::cout << std::endl;
|
||||
std::cout << "H.SS ";
|
||||
for (unsigned i = 0; i < geometry.numTracks; i++)
|
||||
std::cout << fmt::format("{}", i % 10);
|
||||
std::cout << std::endl;
|
||||
|
||||
for (int side = 0; side < geometry.numSides; side++)
|
||||
{
|
||||
int maxSector = geometry.firstSector + geometry.numSectors - 1;
|
||||
for (int sectorId = 0; sectorId <= maxSector; sectorId++)
|
||||
{
|
||||
if (sectorId < geometry.firstSector)
|
||||
continue;
|
||||
for (int side = 0; side < geometry.numSides; side++)
|
||||
{
|
||||
int maxSector = geometry.firstSector + geometry.numSectors - 1;
|
||||
for (int sectorId = 0; sectorId <= maxSector; sectorId++)
|
||||
{
|
||||
if (sectorId < geometry.firstSector)
|
||||
continue;
|
||||
|
||||
std::cout << fmt::format("{}.{:2} ", side, sectorId);
|
||||
for (int track = 0; track < geometry.numTracks; track++)
|
||||
{
|
||||
const auto& sector = image.get(track, side, sectorId);
|
||||
if (!sector)
|
||||
{
|
||||
std::cout << 'X';
|
||||
missingSectors++;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (sector->status)
|
||||
{
|
||||
case Sector::OK:
|
||||
std::cout << fmt::format("{}.{:2} ", side, sectorId);
|
||||
for (int track = 0; track < geometry.numTracks; track++)
|
||||
{
|
||||
const auto& sector = image.get(track, side, sectorId);
|
||||
if (!sector)
|
||||
{
|
||||
std::cout << 'X';
|
||||
missingSectors++;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (sector->status)
|
||||
{
|
||||
case Sector::OK:
|
||||
std::cout << '.';
|
||||
break;
|
||||
|
||||
@@ -178,25 +180,50 @@ void ImageWriter::printMap(const Image& image)
|
||||
std::cout << '?';
|
||||
break;
|
||||
}
|
||||
}
|
||||
totalSectors++;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
int goodSectors = totalSectors - missingSectors - badSectors;
|
||||
if (totalSectors == 0)
|
||||
std::cout << "No sectors in output; skipping analysis" << std::endl;
|
||||
else
|
||||
{
|
||||
std::cout << "Good sectors: " << goodSectors << "/" << totalSectors
|
||||
<< " (" << (100*goodSectors/totalSectors) << "%)"
|
||||
<< std::endl;
|
||||
std::cout << "Missing sectors: " << missingSectors << "/" << totalSectors
|
||||
<< " (" << (100*missingSectors/totalSectors) << "%)"
|
||||
<< std::endl;
|
||||
std::cout << "Bad sectors: " << badSectors << "/" << totalSectors
|
||||
<< " (" << (100*badSectors/totalSectors) << "%)"
|
||||
<< std::endl;
|
||||
}
|
||||
totalSectors++;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
int goodSectors = totalSectors - missingSectors - badSectors;
|
||||
if (totalSectors == 0)
|
||||
std::cout << "No sectors in output; skipping analysis" << std::endl;
|
||||
else
|
||||
{
|
||||
std::cout << "Good sectors: " << goodSectors << "/" << totalSectors
|
||||
<< " (" << (100 * goodSectors / totalSectors) << "%)"
|
||||
<< std::endl;
|
||||
std::cout << "Missing sectors: " << missingSectors << "/"
|
||||
<< totalSectors << " ("
|
||||
<< (100 * missingSectors / totalSectors) << "%)" << std::endl;
|
||||
std::cout << "Bad sectors: " << badSectors << "/" << totalSectors
|
||||
<< " (" << (100 * badSectors / totalSectors) << "%)"
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void ImageWriter::writeMappedImage(const Image& image)
|
||||
{
|
||||
if (_config.filesystem_sector_order())
|
||||
{
|
||||
Logger()
|
||||
<< "WRITER: converting from disk sector order to filesystem order";
|
||||
|
||||
std::set<std::shared_ptr<const Sector>> sectors;
|
||||
for (const auto& e : image)
|
||||
{
|
||||
auto& trackLayout =
|
||||
Layout::getLayoutOfTrack(e->logicalTrack, e->logicalSide);
|
||||
auto newSector = std::make_shared<Sector>();
|
||||
*newSector = *e;
|
||||
newSector->logicalSector =
|
||||
trackLayout.logicalToFilesystemSectorMap.at(e->logicalSector);
|
||||
sectors.insert(newSector);
|
||||
}
|
||||
|
||||
writeImage(Image(sectors));
|
||||
}
|
||||
else
|
||||
writeImage(image);
|
||||
}
|
||||
|
||||
@@ -7,29 +7,44 @@ class Image;
|
||||
class ImageWriter
|
||||
{
|
||||
public:
|
||||
ImageWriter(const ImageWriterProto& config);
|
||||
virtual ~ImageWriter() {};
|
||||
ImageWriter(const ImageWriterProto& config);
|
||||
virtual ~ImageWriter(){};
|
||||
|
||||
public:
|
||||
static std::unique_ptr<ImageWriter> create(const ImageWriterProto& config);
|
||||
static void updateConfigForFilename(ImageWriterProto* proto, const std::string& filename);
|
||||
static void updateConfigForFilename(
|
||||
ImageWriterProto* proto, const std::string& filename);
|
||||
|
||||
static std::unique_ptr<ImageWriter> createD64ImageWriter(const ImageWriterProto& config);
|
||||
static std::unique_ptr<ImageWriter> createDiskCopyImageWriter(const ImageWriterProto& config);
|
||||
static std::unique_ptr<ImageWriter> createImgImageWriter(const ImageWriterProto& config);
|
||||
static std::unique_ptr<ImageWriter> createLDBSImageWriter(const ImageWriterProto& config);
|
||||
static std::unique_ptr<ImageWriter> createNsiImageWriter(const ImageWriterProto& config);
|
||||
static std::unique_ptr<ImageWriter> createRawImageWriter(const ImageWriterProto& config);
|
||||
static std::unique_ptr<ImageWriter> createD88ImageWriter(const ImageWriterProto& config);
|
||||
static std::unique_ptr<ImageWriter> createImdImageWriter(const ImageWriterProto& config);
|
||||
static std::unique_ptr<ImageWriter> createD64ImageWriter(
|
||||
const ImageWriterProto& config);
|
||||
static std::unique_ptr<ImageWriter> createDiskCopyImageWriter(
|
||||
const ImageWriterProto& config);
|
||||
static std::unique_ptr<ImageWriter> createImgImageWriter(
|
||||
const ImageWriterProto& config);
|
||||
static std::unique_ptr<ImageWriter> createLDBSImageWriter(
|
||||
const ImageWriterProto& config);
|
||||
static std::unique_ptr<ImageWriter> createNsiImageWriter(
|
||||
const ImageWriterProto& config);
|
||||
static std::unique_ptr<ImageWriter> createRawImageWriter(
|
||||
const ImageWriterProto& config);
|
||||
static std::unique_ptr<ImageWriter> createD88ImageWriter(
|
||||
const ImageWriterProto& config);
|
||||
static std::unique_ptr<ImageWriter> createImdImageWriter(
|
||||
const ImageWriterProto& config);
|
||||
|
||||
public:
|
||||
void printMap(const Image& sectors);
|
||||
void writeCsv(const Image& sectors, const std::string& filename);
|
||||
virtual void writeImage(const Image& sectors) = 0;
|
||||
void printMap(const Image& sectors);
|
||||
void writeCsv(const Image& sectors, const std::string& filename);
|
||||
|
||||
/* Writes a raw image. */
|
||||
virtual void writeImage(const Image& sectors) = 0;
|
||||
|
||||
/* Writes an image applying any optional mapping from disk sector numbering
|
||||
* to filesystem sector numbering. */
|
||||
void writeMappedImage(const Image& sectors);
|
||||
|
||||
protected:
|
||||
const ImageWriterProto& _config;
|
||||
const ImageWriterProto& _config;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -5,61 +5,82 @@ import "lib/common.proto";
|
||||
|
||||
message D64OutputProto {}
|
||||
|
||||
message LDBSOutputProto {
|
||||
enum DataRate {
|
||||
RATE_HD = 0;
|
||||
RATE_DD = 1;
|
||||
RATE_SD = 2;
|
||||
RATE_ED = 3;
|
||||
RATE_GUESS = -1;
|
||||
}
|
||||
message LDBSOutputProto
|
||||
{
|
||||
enum DataRate
|
||||
{
|
||||
RATE_HD = 0;
|
||||
RATE_DD = 1;
|
||||
RATE_SD = 2;
|
||||
RATE_ED = 3;
|
||||
RATE_GUESS = -1;
|
||||
}
|
||||
|
||||
enum RecordingMode {
|
||||
RECMODE_MFM = 0;
|
||||
RECMODE_FM = 1;
|
||||
RECMODE_GCR_MAC = 0x12;
|
||||
RECMODE_GCR_PRODOS = 0x14;
|
||||
RECMODE_GCR_LISA = 0x22;
|
||||
RECMODE_GUESS = -1;
|
||||
}
|
||||
enum RecordingMode
|
||||
{
|
||||
RECMODE_MFM = 0;
|
||||
RECMODE_FM = 1;
|
||||
RECMODE_GCR_MAC = 0x12;
|
||||
RECMODE_GCR_PRODOS = 0x14;
|
||||
RECMODE_GCR_LISA = 0x22;
|
||||
RECMODE_GUESS = -1;
|
||||
}
|
||||
|
||||
optional DataRate data_rate = 1 [default=RATE_GUESS, (help) = "data rate to use in LDBS file"];
|
||||
optional RecordingMode recording_mode = 2 [default=RECMODE_GUESS, (help) = "recording mode to use in LDBS file"];
|
||||
optional DataRate data_rate = 1
|
||||
[ default = RATE_GUESS, (help) = "data rate to use in LDBS file" ];
|
||||
optional RecordingMode recording_mode = 2 [
|
||||
default = RECMODE_GUESS,
|
||||
(help) = "recording mode to use in LDBS file"
|
||||
];
|
||||
}
|
||||
|
||||
message DiskCopyOutputProto {}
|
||||
message NsiOutputProto {}
|
||||
message RawOutputProto {}
|
||||
message D88OutputProto {}
|
||||
message ImdOutputProto {
|
||||
enum DataRate {
|
||||
RATE_HD = 0;
|
||||
RATE_DD = 1;
|
||||
RATE_SD = 2;
|
||||
RATE_GUESS = -1;
|
||||
}
|
||||
message ImdOutputProto
|
||||
{
|
||||
enum DataRate
|
||||
{
|
||||
RATE_HD = 0;
|
||||
RATE_DD = 1;
|
||||
RATE_SD = 2;
|
||||
RATE_GUESS = -1;
|
||||
}
|
||||
|
||||
enum RecordingMode {
|
||||
RECMODE_MFM = 0;
|
||||
RECMODE_FM = 1;
|
||||
RECMODE_GUESS = -1;
|
||||
}
|
||||
optional DataRate data_rate = 1 [default=RATE_GUESS, (help) = "data rate to use in IMD file"];
|
||||
optional RecordingMode recording_mode = 2 [default=RECMODE_GUESS, (help) = "recording mode (FM or MFM encoding) to use in IMD file"];
|
||||
optional string comment = 3 [(help) = "comment to set in IMD file"];
|
||||
enum RecordingMode
|
||||
{
|
||||
RECMODE_MFM = 0;
|
||||
RECMODE_FM = 1;
|
||||
RECMODE_GUESS = -1;
|
||||
}
|
||||
optional DataRate data_rate = 1
|
||||
[ default = RATE_GUESS, (help) = "data rate to use in IMD file" ];
|
||||
optional RecordingMode recording_mode = 2 [
|
||||
default = RECMODE_GUESS,
|
||||
(help) = "recording mode (FM or MFM encoding) to use in IMD file"
|
||||
];
|
||||
optional string comment = 3 [ (help) = "comment to set in IMD file" ];
|
||||
}
|
||||
|
||||
message ImageWriterProto {
|
||||
optional string filename = 1 [(help) = "filename of output sector image"];
|
||||
oneof format {
|
||||
ImgInputOutputProto img = 2;
|
||||
D64OutputProto d64 = 3;
|
||||
LDBSOutputProto ldbs = 4;
|
||||
DiskCopyOutputProto diskcopy = 5;
|
||||
NsiOutputProto nsi = 6;
|
||||
RawOutputProto raw = 7;
|
||||
D88OutputProto d88 = 8;
|
||||
ImdOutputProto imd = 9;
|
||||
}
|
||||
}
|
||||
// NEXT_TAG: 11
|
||||
message ImageWriterProto
|
||||
{
|
||||
optional string filename = 1 [ (help) = "filename of output sector image" ];
|
||||
optional bool filesystem_sector_order = 10 [
|
||||
(help) = "read/write sector image in filesystem order",
|
||||
default = false
|
||||
];
|
||||
|
||||
oneof format
|
||||
{
|
||||
ImgInputOutputProto img = 2;
|
||||
D64OutputProto d64 = 3;
|
||||
LDBSOutputProto ldbs = 4;
|
||||
DiskCopyOutputProto diskcopy = 5;
|
||||
NsiOutputProto nsi = 6;
|
||||
RawOutputProto raw = 7;
|
||||
D88OutputProto d88 = 8;
|
||||
ImdOutputProto imd = 9;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,8 +182,8 @@ const Layout& Layout::getLayoutOfTrack(unsigned track, unsigned side)
|
||||
|
||||
for (int i = 0; i < layout->numSectors; i++)
|
||||
{
|
||||
unsigned l = layout->logicalSectorOrder[i];
|
||||
unsigned f = layout->filesystemSectorOrder[i];
|
||||
unsigned f = layout->logicalSectorOrder[i];
|
||||
unsigned l = layout->filesystemSectorOrder[i];
|
||||
layout->filesystemToLogicalSectorMap[f] = l;
|
||||
layout->logicalToFilesystemSectorMap[l] = f;
|
||||
}
|
||||
|
||||
@@ -558,7 +558,7 @@ void readDiskCommand(
|
||||
writer.printMap(*diskflux->image);
|
||||
if (config.decoder().has_write_csv_to())
|
||||
writer.writeCsv(*diskflux->image, config.decoder().write_csv_to());
|
||||
writer.writeImage(*diskflux->image);
|
||||
writer.writeMappedImage(*diskflux->image);
|
||||
}
|
||||
|
||||
void rawReadDiskCommand(FluxSource& fluxsource, FluxSink& fluxsink)
|
||||
|
||||
@@ -44,14 +44,14 @@ public:
|
||||
|
||||
void flushChanges() override
|
||||
{
|
||||
_writer->writeImage(*_image);
|
||||
_writer->writeMappedImage(*_image);
|
||||
_changed = false;
|
||||
}
|
||||
|
||||
void discardChanges() override
|
||||
{
|
||||
if (_reader)
|
||||
_image = _reader->readImage();
|
||||
_image = _reader->readMappedImage();
|
||||
else
|
||||
{
|
||||
_image = std::make_shared<Image>();
|
||||
|
||||
@@ -73,7 +73,7 @@ int mainWrite(int argc, const char* argv[])
|
||||
flags.parseFlagsWithConfigFiles(argc, argv, formats);
|
||||
|
||||
std::unique_ptr<ImageReader> reader(ImageReader::create(config.image_reader()));
|
||||
std::shared_ptr<Image> image = reader->readImage();
|
||||
std::shared_ptr<Image> image = reader->readMappedImage();
|
||||
|
||||
std::unique_ptr<AbstractEncoder> encoder(AbstractEncoder::create(config.encoder()));
|
||||
std::unique_ptr<FluxSink> fluxSink(FluxSink::create(config.flux_sink()));
|
||||
|
||||
@@ -319,8 +319,8 @@ public:
|
||||
runOnWorkerThread(
|
||||
[this]()
|
||||
{
|
||||
auto image =
|
||||
ImageReader::create(config.image_reader())->readImage();
|
||||
auto image = ImageReader::create(config.image_reader())
|
||||
->readMappedImage();
|
||||
auto encoder = AbstractEncoder::create(config.encoder());
|
||||
auto fluxSink = FluxSink::create(config.flux_sink());
|
||||
|
||||
@@ -386,7 +386,7 @@ public:
|
||||
{
|
||||
auto imageWriter =
|
||||
ImageWriter::create(config.image_writer());
|
||||
imageWriter->writeImage(*image);
|
||||
imageWriter->writeMappedImage(*image);
|
||||
});
|
||||
}
|
||||
catch (const ErrorException& e)
|
||||
|
||||
Reference in New Issue
Block a user