mirror of
https://github.com/davidgiven/fluxengine.git
synced 2025-10-31 11:17:01 -07:00
Bash the imagewriter stuff into working with the new config system.
This commit is contained in:
@@ -9,9 +9,6 @@ message ImgInputOutput {
|
|||||||
optional int32 sector_size = 4;
|
optional int32 sector_size = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
optional int32 tracks = 1;
|
|
||||||
optional int32 heads = 2;
|
|
||||||
optional int32 sectors = 3;
|
|
||||||
repeated Format format = 4;
|
repeated Format format = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "imagewriter/imagewriter.h"
|
#include "imagewriter/imagewriter.h"
|
||||||
#include "fmt/format.h"
|
#include "fmt/format.h"
|
||||||
#include "ldbs.h"
|
#include "ldbs.h"
|
||||||
|
#include "lib/config.pb.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
@@ -24,15 +25,15 @@ static int sectors_per_track(int track)
|
|||||||
class D64ImageWriter : public ImageWriter
|
class D64ImageWriter : public ImageWriter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
D64ImageWriter(const SectorSet& sectors, const ImageSpec& spec):
|
D64ImageWriter(const Config_OutputFile& config):
|
||||||
ImageWriter(sectors, spec)
|
ImageWriter(config)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void writeImage()
|
void writeImage(const SectorSet& sectors)
|
||||||
{
|
{
|
||||||
std::cout << "writing D64 triangular image\n";
|
std::cout << "writing D64 triangular image\n";
|
||||||
|
|
||||||
std::ofstream outputFile(spec.filename, std::ios::out | std::ios::binary);
|
std::ofstream outputFile(_config.filename(), std::ios::out | std::ios::binary);
|
||||||
if (!outputFile.is_open())
|
if (!outputFile.is_open())
|
||||||
Error() << "cannot open output file";
|
Error() << "cannot open output file";
|
||||||
|
|
||||||
@@ -55,9 +56,8 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<ImageWriter> ImageWriter::createD64ImageWriter(
|
std::unique_ptr<ImageWriter> ImageWriter::createD64ImageWriter(const Config_OutputFile& config)
|
||||||
const SectorSet& sectors, const ImageSpec& spec)
|
|
||||||
{
|
{
|
||||||
return std::unique_ptr<ImageWriter>(new D64ImageWriter(sectors, spec));
|
return std::unique_ptr<ImageWriter>(new D64ImageWriter(config));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "imagewriter/imagewriter.h"
|
#include "imagewriter/imagewriter.h"
|
||||||
#include "fmt/format.h"
|
#include "fmt/format.h"
|
||||||
#include "ldbs.h"
|
#include "ldbs.h"
|
||||||
|
#include "lib/config.pb.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
@@ -27,35 +28,44 @@ static void write_and_update_checksum(ByteWriter& bw, uint32_t& checksum, const
|
|||||||
class DiskCopyImageWriter : public ImageWriter
|
class DiskCopyImageWriter : public ImageWriter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DiskCopyImageWriter(const SectorSet& sectors, const ImageSpec& spec):
|
DiskCopyImageWriter(const Config_OutputFile& config):
|
||||||
ImageWriter(sectors, spec)
|
ImageWriter(config)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void writeImage()
|
void writeImage(const SectorSet& sectors)
|
||||||
{
|
{
|
||||||
|
unsigned numCylinders;
|
||||||
|
unsigned numHeads;
|
||||||
|
unsigned numSectors;
|
||||||
|
unsigned numBytes;
|
||||||
|
sectors.calculateSize(numCylinders, numHeads, numSectors, numBytes);
|
||||||
|
|
||||||
bool mfm = false;
|
bool mfm = false;
|
||||||
|
|
||||||
if (spec.bytes == 524)
|
switch (numBytes)
|
||||||
{
|
{
|
||||||
/* GCR disk */
|
case 524:
|
||||||
|
/* GCR disk */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 512:
|
||||||
|
/* MFM disk */
|
||||||
|
mfm = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Error() << "this image is not compatible with the DiskCopy 4.2 format";
|
||||||
}
|
}
|
||||||
else if (spec.bytes == 512)
|
|
||||||
{
|
|
||||||
/* MFM disk */
|
|
||||||
mfm = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Error() << "this image is not compatible with the DiskCopy 4.2 format";
|
|
||||||
|
|
||||||
std::cout << "writing DiskCopy 4.2 image\n"
|
std::cout << "writing DiskCopy 4.2 image\n"
|
||||||
<< fmt::format("{} tracks, {} heads, {} sectors, {} bytes per sector; {}\n",
|
<< fmt::format("{} tracks, {} heads, {} sectors, {} bytes per sector; {}\n",
|
||||||
spec.cylinders, spec.heads, spec.sectors, spec.bytes,
|
numCylinders, numHeads, numSectors, numBytes,
|
||||||
mfm ? "MFM" : "GCR");
|
mfm ? "MFM" : "GCR");
|
||||||
|
|
||||||
auto sectors_per_track = [&](int track) -> int
|
auto sectors_per_track = [&](int track) -> int
|
||||||
{
|
{
|
||||||
if (mfm)
|
if (mfm)
|
||||||
return spec.sectors;
|
return numSectors;
|
||||||
|
|
||||||
if (track < 16)
|
if (track < 16)
|
||||||
return 12;
|
return 12;
|
||||||
@@ -77,9 +87,9 @@ public:
|
|||||||
uint32_t tagChecksum = 0;
|
uint32_t tagChecksum = 0;
|
||||||
uint32_t offset = 0x54;
|
uint32_t offset = 0x54;
|
||||||
uint32_t sectorDataStart = offset;
|
uint32_t sectorDataStart = offset;
|
||||||
for (int track = 0; track < spec.cylinders; track++)
|
for (int track = 0; track < numCylinders; track++)
|
||||||
{
|
{
|
||||||
for (int head = 0; head < spec.heads; head++)
|
for (int head = 0; head < numHeads; head++)
|
||||||
{
|
{
|
||||||
int sectorCount = sectors_per_track(track);
|
int sectorCount = sectors_per_track(track);
|
||||||
for (int sectorId = 0; sectorId < sectorCount; sectorId++)
|
for (int sectorId = 0; sectorId < sectorCount; sectorId++)
|
||||||
@@ -97,9 +107,9 @@ public:
|
|||||||
uint32_t sectorDataEnd = offset;
|
uint32_t sectorDataEnd = offset;
|
||||||
if (!mfm)
|
if (!mfm)
|
||||||
{
|
{
|
||||||
for (int track = 0; track < spec.cylinders; track++)
|
for (int track = 0; track < numCylinders; track++)
|
||||||
{
|
{
|
||||||
for (int head = 0; head < spec.heads; head++)
|
for (int head = 0; head < numHeads; head++)
|
||||||
{
|
{
|
||||||
int sectorCount = sectors_per_track(track);
|
int sectorCount = sectors_per_track(track);
|
||||||
for (int sectorId = 0; sectorId < sectorCount; sectorId++)
|
for (int sectorId = 0; sectorId < sectorCount; sectorId++)
|
||||||
@@ -124,14 +134,14 @@ public:
|
|||||||
if (mfm)
|
if (mfm)
|
||||||
{
|
{
|
||||||
format = 0x22;
|
format = 0x22;
|
||||||
if (spec.sectors == 18)
|
if (numSectors == 18)
|
||||||
encoding = 3;
|
encoding = 3;
|
||||||
else
|
else
|
||||||
encoding = 2;
|
encoding = 2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (spec.heads == 2)
|
if (numHeads == 2)
|
||||||
{
|
{
|
||||||
encoding = 1;
|
encoding = 1;
|
||||||
format = 0x22;
|
format = 0x22;
|
||||||
@@ -155,14 +165,14 @@ public:
|
|||||||
bw.write_8(format); /* format byte */
|
bw.write_8(format); /* format byte */
|
||||||
bw.write_be16(0x0100); /* magic number */
|
bw.write_be16(0x0100); /* magic number */
|
||||||
|
|
||||||
image.writeToFile(spec.filename);
|
image.writeToFile(_config.filename());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<ImageWriter> ImageWriter::createDiskCopyImageWriter(
|
std::unique_ptr<ImageWriter> ImageWriter::createDiskCopyImageWriter(
|
||||||
const SectorSet& sectors, const ImageSpec& spec)
|
const Config_OutputFile& config)
|
||||||
{
|
{
|
||||||
return std::unique_ptr<ImageWriter>(new DiskCopyImageWriter(sectors, spec));
|
return std::unique_ptr<ImageWriter>(new DiskCopyImageWriter(config));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -5,10 +5,12 @@
|
|||||||
#include "sectorset.h"
|
#include "sectorset.h"
|
||||||
#include "imagewriter/imagewriter.h"
|
#include "imagewriter/imagewriter.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
#include "lib/config.pb.h"
|
||||||
#include "fmt/format.h"
|
#include "fmt/format.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
|
#if 0
|
||||||
std::map<std::string, ImageWriter::Constructor> ImageWriter::formats =
|
std::map<std::string, ImageWriter::Constructor> ImageWriter::formats =
|
||||||
{
|
{
|
||||||
{".adf", ImageWriter::createImgImageWriter},
|
{".adf", ImageWriter::createImgImageWriter},
|
||||||
@@ -19,48 +21,27 @@ std::map<std::string, ImageWriter::Constructor> ImageWriter::formats =
|
|||||||
{".ldbs", ImageWriter::createLDBSImageWriter},
|
{".ldbs", ImageWriter::createLDBSImageWriter},
|
||||||
{".st", ImageWriter::createImgImageWriter},
|
{".st", ImageWriter::createImgImageWriter},
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
ImageWriter::Constructor ImageWriter::findConstructor(const ImageSpec& spec)
|
std::unique_ptr<ImageWriter> ImageWriter::create(const Config_OutputFile& config)
|
||||||
{
|
{
|
||||||
const auto& filename = spec.filename;
|
if (config.has_img())
|
||||||
|
return ImageWriter::createImgImageWriter(config);
|
||||||
for (const auto& e : formats)
|
else
|
||||||
{
|
Error() << "bad output image config";
|
||||||
if (endsWith(filename, e.first))
|
|
||||||
return e.second;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<ImageWriter> ImageWriter::create(const SectorSet& sectors, const ImageSpec& spec)
|
//void ImageWriter::verifyImageSpec(const ImageSpec& spec)
|
||||||
{
|
//{
|
||||||
verifyImageSpec(spec);
|
// if (!findConstructor(spec))
|
||||||
return findConstructor(spec)(sectors, spec);
|
// Error() << "unrecognised output image filename extension";
|
||||||
}
|
//}
|
||||||
|
|
||||||
void ImageWriter::verifyImageSpec(const ImageSpec& spec)
|
ImageWriter::ImageWriter(const Config_OutputFile& config):
|
||||||
{
|
_config(config)
|
||||||
if (!findConstructor(spec))
|
|
||||||
Error() << "unrecognised output image filename extension";
|
|
||||||
}
|
|
||||||
|
|
||||||
ImageWriter::ImageWriter(const SectorSet& sectors, const ImageSpec& spec):
|
|
||||||
sectors(sectors),
|
|
||||||
spec(spec)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void ImageWriter::adjustGeometry()
|
void ImageWriter::writeCsv(const SectorSet& sectors, const std::string& filename)
|
||||||
{
|
|
||||||
if (!spec.initialised)
|
|
||||||
{
|
|
||||||
sectors.calculateSize(spec.cylinders, spec.heads, spec.sectors, spec.bytes);
|
|
||||||
spec.initialised = true;
|
|
||||||
std::cout << "Autodetecting output geometry\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImageWriter::writeCsv(const std::string& filename)
|
|
||||||
{
|
{
|
||||||
std::ofstream f(filename, std::ios::out);
|
std::ofstream f(filename, std::ios::out);
|
||||||
if (!f.is_open())
|
if (!f.is_open())
|
||||||
@@ -81,47 +62,45 @@ void ImageWriter::writeCsv(const std::string& filename)
|
|||||||
"\"Status\""
|
"\"Status\""
|
||||||
"\n";
|
"\n";
|
||||||
|
|
||||||
for (int track = 0; track < spec.cylinders; track++)
|
for (const auto& it : sectors.get())
|
||||||
{
|
{
|
||||||
for (int head = 0; head < spec.heads; head++)
|
const auto& sector = it.second;
|
||||||
{
|
f << fmt::format("{},{},{},{},{},{},{},{},{},{},{},{},{}\n",
|
||||||
for (int sectorId = 0; sectorId < spec.sectors; sectorId++)
|
sector->physicalTrack,
|
||||||
{
|
sector->physicalSide,
|
||||||
f << fmt::format("{},{},", track, head);
|
sector->logicalTrack,
|
||||||
const auto& sector = sectors.get(track, head, sectorId);
|
sector->logicalSide,
|
||||||
if (!sector)
|
sector->logicalSector,
|
||||||
f << fmt::format(",,{},,,,,,,,sector not found\n", sectorId);
|
sector->clock,
|
||||||
else
|
sector->headerStartTime,
|
||||||
f << fmt::format("{},{},{},{},{},{},{},{},{},{},{}\n",
|
sector->headerEndTime,
|
||||||
sector->logicalTrack,
|
sector->dataStartTime,
|
||||||
sector->logicalSide,
|
sector->dataEndTime,
|
||||||
sector->logicalSector,
|
sector->position.bytes,
|
||||||
sector->clock,
|
sector->data.size(),
|
||||||
sector->headerStartTime,
|
Sector::statusToString(sector->status)
|
||||||
sector->headerEndTime,
|
);
|
||||||
sector->dataStartTime,
|
|
||||||
sector->dataEndTime,
|
|
||||||
sector->position.bytes,
|
|
||||||
sector->data.size(),
|
|
||||||
Sector::statusToString(sector->status)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageWriter::printMap()
|
void ImageWriter::printMap(const SectorSet& sectors)
|
||||||
{
|
{
|
||||||
|
unsigned numCylinders;
|
||||||
|
unsigned numHeads;
|
||||||
|
unsigned numSectors;
|
||||||
|
unsigned numBytes;
|
||||||
|
sectors.calculateSize(numCylinders, numHeads, numSectors, numBytes);
|
||||||
|
|
||||||
int badSectors = 0;
|
int badSectors = 0;
|
||||||
int missingSectors = 0;
|
int missingSectors = 0;
|
||||||
int totalSectors = 0;
|
int totalSectors = 0;
|
||||||
std::cout << "H.SS Tracks --->" << std::endl;
|
std::cout << "H.SS Tracks --->" << std::endl;
|
||||||
for (int head = 0; head < spec.heads; head++)
|
for (int head = 0; head < numHeads; head++)
|
||||||
{
|
{
|
||||||
for (int sectorId = 0; sectorId < spec.sectors; sectorId++)
|
for (int sectorId = 0; sectorId < numSectors; sectorId++)
|
||||||
{
|
{
|
||||||
std::cout << fmt::format("{}.{:2} ", head, sectorId);
|
std::cout << fmt::format("{}.{:2} ", head, sectorId);
|
||||||
for (int track = 0; track < spec.cylinders; track++)
|
for (int track = 0; track < numCylinders; track++)
|
||||||
{
|
{
|
||||||
const auto& sector = sectors.get(track, head, sectorId);
|
const auto& sector = sectors.get(track, head, sectorId);
|
||||||
if (!sector)
|
if (!sector)
|
||||||
|
|||||||
@@ -2,47 +2,33 @@
|
|||||||
#define IMAGEWRITER_H
|
#define IMAGEWRITER_H
|
||||||
|
|
||||||
class SectorSet;
|
class SectorSet;
|
||||||
class ImageSpec;
|
class Config_OutputFile;
|
||||||
|
|
||||||
class ImageWriter
|
class ImageWriter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ImageWriter(const SectorSet& sectors, const ImageSpec& spec);
|
ImageWriter(const Config_OutputFile& config);
|
||||||
virtual ~ImageWriter() {};
|
virtual ~ImageWriter() {};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static std::unique_ptr<ImageWriter> create(const SectorSet& sectors, const ImageSpec& spec);
|
static std::unique_ptr<ImageWriter> create(const Config_OutputFile& config);
|
||||||
static void verifyImageSpec(const ImageSpec& filename);
|
|
||||||
|
|
||||||
private:
|
|
||||||
typedef
|
|
||||||
std::function<
|
|
||||||
std::unique_ptr<ImageWriter>(const SectorSet& sectors, const ImageSpec& spec)
|
|
||||||
>
|
|
||||||
Constructor;
|
|
||||||
|
|
||||||
static std::map<std::string, Constructor> formats;
|
|
||||||
|
|
||||||
static std::unique_ptr<ImageWriter> createImgImageWriter(
|
static std::unique_ptr<ImageWriter> createImgImageWriter(
|
||||||
const SectorSet& sectors, const ImageSpec& spec);
|
const Config_OutputFile& config);
|
||||||
static std::unique_ptr<ImageWriter> createLDBSImageWriter(
|
static std::unique_ptr<ImageWriter> createLDBSImageWriter(
|
||||||
const SectorSet& sectors, const ImageSpec& spec);
|
const Config_OutputFile& config);
|
||||||
static std::unique_ptr<ImageWriter> createD64ImageWriter(
|
static std::unique_ptr<ImageWriter> createD64ImageWriter(
|
||||||
const SectorSet& sectors, const ImageSpec& spec);
|
const Config_OutputFile& config);
|
||||||
static std::unique_ptr<ImageWriter> createDiskCopyImageWriter(
|
static std::unique_ptr<ImageWriter> createDiskCopyImageWriter(
|
||||||
const SectorSet& sectors, const ImageSpec& spec);
|
const Config_OutputFile& config);
|
||||||
|
|
||||||
static Constructor findConstructor(const ImageSpec& spec);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual void adjustGeometry();
|
void printMap(const SectorSet& sectors);
|
||||||
void printMap();
|
void writeCsv(const SectorSet& sectors, const std::string& filename);
|
||||||
void writeCsv(const std::string& filename);
|
virtual void writeImage(const SectorSet& sectors) = 0;
|
||||||
virtual void writeImage() = 0;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const SectorSet& sectors;
|
const Config_OutputFile& _config;
|
||||||
ImageSpec spec;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include "sector.h"
|
#include "sector.h"
|
||||||
#include "sectorset.h"
|
#include "sectorset.h"
|
||||||
#include "imagewriter/imagewriter.h"
|
#include "imagewriter/imagewriter.h"
|
||||||
|
#include "lib/config.pb.h"
|
||||||
#include "fmt/format.h"
|
#include "fmt/format.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@@ -12,16 +13,17 @@
|
|||||||
class ImgImageWriter : public ImageWriter
|
class ImgImageWriter : public ImageWriter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ImgImageWriter(const SectorSet& sectors, const ImageSpec& spec):
|
ImgImageWriter(const Config_OutputFile& config):
|
||||||
ImageWriter(sectors, spec)
|
ImageWriter(config)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void writeImage()
|
void writeImage(const SectorSet& sectors)
|
||||||
{
|
{
|
||||||
unsigned numCylinders = spec.cylinders;
|
unsigned numCylinders;
|
||||||
unsigned numHeads = spec.heads;
|
unsigned numHeads;
|
||||||
unsigned numSectors = spec.sectors;
|
unsigned numSectors;
|
||||||
unsigned numBytes = spec.bytes;
|
unsigned numBytes;
|
||||||
|
sectors.calculateSize(numCylinders, numHeads, numSectors, numBytes);
|
||||||
|
|
||||||
size_t headSize = numSectors * numBytes;
|
size_t headSize = numSectors * numBytes;
|
||||||
size_t trackSize = headSize * numHeads;
|
size_t trackSize = headSize * numHeads;
|
||||||
@@ -32,7 +34,7 @@ public:
|
|||||||
numCylinders * trackSize / 1024)
|
numCylinders * trackSize / 1024)
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
std::ofstream outputFile(spec.filename, std::ios::out | std::ios::binary);
|
std::ofstream outputFile(_config.filename(), std::ios::out | std::ios::binary);
|
||||||
if (!outputFile.is_open())
|
if (!outputFile.is_open())
|
||||||
Error() << "cannot open output file";
|
Error() << "cannot open output file";
|
||||||
|
|
||||||
@@ -55,7 +57,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<ImageWriter> ImageWriter::createImgImageWriter(
|
std::unique_ptr<ImageWriter> ImageWriter::createImgImageWriter(
|
||||||
const SectorSet& sectors, const ImageSpec& spec)
|
const Config_OutputFile& config)
|
||||||
{
|
{
|
||||||
return std::unique_ptr<ImageWriter>(new ImgImageWriter(sectors, spec));
|
return std::unique_ptr<ImageWriter>(new ImgImageWriter(config));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "imagewriter/imagewriter.h"
|
#include "imagewriter/imagewriter.h"
|
||||||
#include "fmt/format.h"
|
#include "fmt/format.h"
|
||||||
#include "ldbs.h"
|
#include "ldbs.h"
|
||||||
|
#include "lib/config.pb.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
@@ -13,18 +14,20 @@
|
|||||||
class LDBSImageWriter : public ImageWriter
|
class LDBSImageWriter : public ImageWriter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LDBSImageWriter(const SectorSet& sectors, const ImageSpec& spec):
|
LDBSImageWriter(const Config_OutputFile& config):
|
||||||
ImageWriter(sectors, spec)
|
ImageWriter(config)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void writeImage()
|
void writeImage(const SectorSet& sectors)
|
||||||
{
|
{
|
||||||
LDBS ldbs;
|
LDBS ldbs;
|
||||||
|
|
||||||
unsigned numCylinders = spec.cylinders;
|
unsigned numCylinders;
|
||||||
unsigned numHeads = spec.heads;
|
unsigned numHeads;
|
||||||
unsigned numSectors = spec.sectors;
|
unsigned numSectors;
|
||||||
unsigned numBytes = spec.bytes;
|
unsigned numBytes;
|
||||||
|
sectors.calculateSize(numCylinders, numHeads, numSectors, numBytes);
|
||||||
|
|
||||||
std::cout << fmt::format("writing {} tracks, {} heads, {} sectors, {} bytes per sector",
|
std::cout << fmt::format("writing {} tracks, {} heads, {} sectors, {} bytes per sector",
|
||||||
numCylinders, numHeads,
|
numCylinders, numHeads,
|
||||||
numSectors, numBytes)
|
numSectors, numBytes)
|
||||||
@@ -95,12 +98,11 @@ public:
|
|||||||
|
|
||||||
uint32_t trackDirectoryAddress = ldbs.put(trackDirectory, LDBS_TRACK_BLOCK);
|
uint32_t trackDirectoryAddress = ldbs.put(trackDirectory, LDBS_TRACK_BLOCK);
|
||||||
Bytes data = ldbs.write(trackDirectoryAddress);
|
Bytes data = ldbs.write(trackDirectoryAddress);
|
||||||
data.writeToFile(spec.filename);
|
data.writeToFile(_config.filename());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<ImageWriter> ImageWriter::createLDBSImageWriter(
|
std::unique_ptr<ImageWriter> ImageWriter::createLDBSImageWriter(const Config_OutputFile& config)
|
||||||
const SectorSet& sectors, const ImageSpec& spec)
|
|
||||||
{
|
{
|
||||||
return std::unique_ptr<ImageWriter>(new LDBSImageWriter(sectors, spec));
|
return std::unique_ptr<ImageWriter>(new LDBSImageWriter(config));
|
||||||
}
|
}
|
||||||
|
|||||||
227
lib/reader.cc
227
lib/reader.cc
@@ -27,16 +27,6 @@ FlagGroup readerFlags
|
|||||||
&fluxmapReaderFlags,
|
&fluxmapReaderFlags,
|
||||||
};
|
};
|
||||||
|
|
||||||
//static DataSpecFlag source(
|
|
||||||
// { "--source", "-s" },
|
|
||||||
// "source for data",
|
|
||||||
// ":t=0-79:s=0-1:d=0");
|
|
||||||
//
|
|
||||||
//static DataSpecFlag output(
|
|
||||||
// { "--output", "-o" },
|
|
||||||
// "output image file to write to",
|
|
||||||
// "");
|
|
||||||
|
|
||||||
static StringFlag destination(
|
static StringFlag destination(
|
||||||
{ "--write-flux", "-f" },
|
{ "--write-flux", "-f" },
|
||||||
"write the raw magnetic flux to this file",
|
"write the raw magnetic flux to this file",
|
||||||
@@ -66,16 +56,6 @@ static StringFlag csvFile(
|
|||||||
|
|
||||||
static std::unique_ptr<FluxSink> outputFluxSink;
|
static std::unique_ptr<FluxSink> outputFluxSink;
|
||||||
|
|
||||||
static void writeSectorsToFile(const SectorSet& sectors, const ImageSpec& spec)
|
|
||||||
{
|
|
||||||
std::unique_ptr<ImageWriter> writer(ImageWriter::create(sectors, spec));
|
|
||||||
writer->adjustGeometry();
|
|
||||||
writer->printMap();
|
|
||||||
if (!csvFile.get().empty())
|
|
||||||
writer->writeCsv(csvFile.get());
|
|
||||||
writer->writeImage();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Track::readFluxmap()
|
void Track::readFluxmap()
|
||||||
{
|
{
|
||||||
std::cout << fmt::format("{0:>3}.{1}: ", physicalTrack, physicalSide) << std::flush;
|
std::cout << fmt::format("{0:>3}.{1}: ", physicalTrack, physicalSide) << std::flush;
|
||||||
@@ -158,131 +138,124 @@ void readDiskCommand(FluxSource& fluxsource, AbstractDecoder& decoder, ImageWrit
|
|||||||
{
|
{
|
||||||
for (int side : iterate(config.sides()))
|
for (int side : iterate(config.sides()))
|
||||||
{
|
{
|
||||||
#if 0
|
auto track = std::make_unique<Track>(cylinder, side);
|
||||||
auto track = std::make_unique<Track>(location
|
track->fluxsource = &fluxsource;
|
||||||
std::vector<std::unique_ptr<Track>> tracks;
|
|
||||||
for (const auto& location : spec.locations)
|
|
||||||
{
|
|
||||||
auto track = std::make_unique<Track>(location.track, location.side);
|
|
||||||
track->fluxsource = fluxSource;
|
|
||||||
tracks.push_back(std::move(track));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
auto track = std::make_unique<Track>(cylinder, side);
|
|
||||||
track->fluxsource = &fluxsource;
|
|
||||||
|
|
||||||
std::map<int, std::unique_ptr<Sector>> readSectors;
|
std::map<int, std::unique_ptr<Sector>> readSectors;
|
||||||
for (int retry = ::retries; retry >= 0; retry--)
|
for (int retry = ::retries; retry >= 0; retry--)
|
||||||
{
|
{
|
||||||
track->readFluxmap();
|
track->readFluxmap();
|
||||||
decoder.decodeToSectors(*track);
|
decoder.decodeToSectors(*track);
|
||||||
|
|
||||||
std::cout << " ";
|
std::cout << " ";
|
||||||
std::cout << fmt::format("{} records, {} sectors; ",
|
std::cout << fmt::format("{} records, {} sectors; ",
|
||||||
track->rawrecords.size(),
|
track->rawrecords.size(),
|
||||||
track->sectors.size());
|
track->sectors.size());
|
||||||
if (track->sectors.size() > 0)
|
if (track->sectors.size() > 0)
|
||||||
std::cout << fmt::format("{:.2f}us clock ({:.0f}kHz); ",
|
std::cout << fmt::format("{:.2f}us clock ({:.0f}kHz); ",
|
||||||
track->sectors.begin()->clock / 1000.0,
|
track->sectors.begin()->clock / 1000.0,
|
||||||
1000000.0 / track->sectors.begin()->clock);
|
1000000.0 / track->sectors.begin()->clock);
|
||||||
|
|
||||||
for (auto& sector : track->sectors)
|
for (auto& sector : track->sectors)
|
||||||
{
|
|
||||||
auto& replacing = readSectors[sector.logicalSector];
|
|
||||||
replace_sector(replacing, sector);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool hasBadSectors = false;
|
|
||||||
std::set<unsigned> requiredSectors = decoder.requiredSectors(*track);
|
|
||||||
for (const auto& i : readSectors)
|
|
||||||
{
|
|
||||||
const auto& sector = i.second;
|
|
||||||
requiredSectors.erase(sector->logicalSector);
|
|
||||||
|
|
||||||
if (sector->status != Sector::OK)
|
|
||||||
{
|
{
|
||||||
std::cout << std::endl
|
auto& replacing = readSectors[sector.logicalSector];
|
||||||
<< " Failed to read sector " << sector->logicalSector
|
replace_sector(replacing, sector);
|
||||||
<< " (" << Sector::statusToString((Sector::Status)sector->status) << "); ";
|
}
|
||||||
|
|
||||||
|
bool hasBadSectors = false;
|
||||||
|
std::set<unsigned> requiredSectors = decoder.requiredSectors(*track);
|
||||||
|
for (const auto& i : readSectors)
|
||||||
|
{
|
||||||
|
const auto& sector = i.second;
|
||||||
|
requiredSectors.erase(sector->logicalSector);
|
||||||
|
|
||||||
|
if (sector->status != Sector::OK)
|
||||||
|
{
|
||||||
|
std::cout << std::endl
|
||||||
|
<< " Failed to read sector " << sector->logicalSector
|
||||||
|
<< " (" << Sector::statusToString((Sector::Status)sector->status) << "); ";
|
||||||
|
hasBadSectors = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (unsigned logicalSector : requiredSectors)
|
||||||
|
{
|
||||||
|
std::cout << "\n"
|
||||||
|
<< " Required sector " << logicalSector << " missing; ";
|
||||||
hasBadSectors = true;
|
hasBadSectors = true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
for (unsigned logicalSector : requiredSectors)
|
|
||||||
{
|
|
||||||
std::cout << "\n"
|
|
||||||
<< " Required sector " << logicalSector << " missing; ";
|
|
||||||
hasBadSectors = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasBadSectors)
|
if (hasBadSectors)
|
||||||
failures = false;
|
failures = false;
|
||||||
|
|
||||||
std::cout << std::endl
|
std::cout << std::endl
|
||||||
<< " ";
|
<< " ";
|
||||||
|
|
||||||
if (!hasBadSectors)
|
if (!hasBadSectors)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!track->fluxsource->retryable())
|
||||||
break;
|
break;
|
||||||
|
if (retry == 0)
|
||||||
if (!track->fluxsource->retryable())
|
std::cout << "giving up" << std::endl
|
||||||
break;
|
<< " ";
|
||||||
if (retry == 0)
|
else
|
||||||
std::cout << "giving up" << std::endl
|
std::cout << retry << " retries remaining" << std::endl;
|
||||||
<< " ";
|
|
||||||
else
|
|
||||||
std::cout << retry << " retries remaining" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dumpRecords)
|
|
||||||
{
|
|
||||||
std::cout << "\nRaw (undecoded) records follow:\n\n";
|
|
||||||
for (auto& record : track->rawrecords)
|
|
||||||
{
|
|
||||||
std::cout << fmt::format("I+{:.2f}us with {:.2f}us clock\n",
|
|
||||||
record.position.ns() / 1000.0, record.clock / 1000.0);
|
|
||||||
hexdump(std::cout, record.data);
|
|
||||||
std::cout << std::endl;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (dumpSectors)
|
if (dumpRecords)
|
||||||
{
|
|
||||||
std::cout << "\nDecoded sectors follow:\n\n";
|
|
||||||
for (auto& sector : track->sectors)
|
|
||||||
{
|
|
||||||
std::cout << fmt::format("{}.{:02}.{:02}: I+{:.2f}us with {:.2f}us clock: status {}\n",
|
|
||||||
sector.logicalTrack, sector.logicalSide, sector.logicalSector,
|
|
||||||
sector.position.ns() / 1000.0, sector.clock / 1000.0,
|
|
||||||
sector.status);
|
|
||||||
hexdump(std::cout, sector.data);
|
|
||||||
std::cout << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int size = 0;
|
|
||||||
bool printedTrack = false;
|
|
||||||
for (auto& i : readSectors)
|
|
||||||
{
|
|
||||||
auto& sector = i.second;
|
|
||||||
if (sector)
|
|
||||||
{
|
{
|
||||||
if (!printedTrack)
|
std::cout << "\nRaw (undecoded) records follow:\n\n";
|
||||||
|
for (auto& record : track->rawrecords)
|
||||||
{
|
{
|
||||||
std::cout << fmt::format("logical track {}.{}; ", sector->logicalTrack, sector->logicalSide);
|
std::cout << fmt::format("I+{:.2f}us with {:.2f}us clock\n",
|
||||||
printedTrack = true;
|
record.position.ns() / 1000.0, record.clock / 1000.0);
|
||||||
|
hexdump(std::cout, record.data);
|
||||||
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
size += sector->data.size();
|
|
||||||
|
|
||||||
std::unique_ptr<Sector>& replacing = allSectors.get(sector->logicalTrack, sector->logicalSide, sector->logicalSector);
|
|
||||||
replace_sector(replacing, *sector);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
std::cout << size << " bytes decoded." << std::endl;
|
if (dumpSectors)
|
||||||
}
|
{
|
||||||
|
std::cout << "\nDecoded sectors follow:\n\n";
|
||||||
|
for (auto& sector : track->sectors)
|
||||||
|
{
|
||||||
|
std::cout << fmt::format("{}.{:02}.{:02}: I+{:.2f}us with {:.2f}us clock: status {}\n",
|
||||||
|
sector.logicalTrack, sector.logicalSide, sector.logicalSector,
|
||||||
|
sector.position.ns() / 1000.0, sector.clock / 1000.0,
|
||||||
|
sector.status);
|
||||||
|
hexdump(std::cout, sector.data);
|
||||||
|
std::cout << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int size = 0;
|
||||||
|
bool printedTrack = false;
|
||||||
|
for (auto& i : readSectors)
|
||||||
|
{
|
||||||
|
auto& sector = i.second;
|
||||||
|
if (sector)
|
||||||
|
{
|
||||||
|
if (!printedTrack)
|
||||||
|
{
|
||||||
|
std::cout << fmt::format("logical track {}.{}; ", sector->logicalTrack, sector->logicalSide);
|
||||||
|
printedTrack = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
size += sector->data.size();
|
||||||
|
|
||||||
|
std::unique_ptr<Sector>& replacing = allSectors.get(sector->logicalTrack, sector->logicalSide, sector->logicalSector);
|
||||||
|
replace_sector(replacing, *sector);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::cout << size << " bytes decoded." << std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Error() << "write to image not done";
|
writer.printMap(allSectors);
|
||||||
//writeSectorsToFile(allSectors, outputSpec);
|
if (!csvFile.get().empty())
|
||||||
|
writer.writeCsv(allSectors, csvFile.get());
|
||||||
|
writer.writeImage(allSectors);
|
||||||
|
|
||||||
if (failures)
|
if (failures)
|
||||||
std::cerr << "Warning: some sectors could not be decoded." << std::endl;
|
std::cerr << "Warning: some sectors could not be decoded." << std::endl;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ static void syntax()
|
|||||||
|
|
||||||
int mainConvertImage(int argc, const char* argv[])
|
int mainConvertImage(int argc, const char* argv[])
|
||||||
{
|
{
|
||||||
|
Error() << "unimplemented";
|
||||||
|
#if 0
|
||||||
auto filenames = flags.parseFlagsWithFilenames(argc, argv);
|
auto filenames = flags.parseFlagsWithFilenames(argc, argv);
|
||||||
if (filenames.size() != 2)
|
if (filenames.size() != 2)
|
||||||
syntax();
|
syntax();
|
||||||
@@ -32,6 +34,7 @@ int mainConvertImage(int argc, const char* argv[])
|
|||||||
writer->adjustGeometry();
|
writer->adjustGeometry();
|
||||||
writer->printMap();
|
writer->printMap();
|
||||||
writer->writeImage();
|
writer->writeImage();
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,11 +40,7 @@ int mainRead(int argc, const char* argv[])
|
|||||||
else
|
else
|
||||||
Error() << "no input disk format specified";
|
Error() << "no input disk format specified";
|
||||||
|
|
||||||
std::unique_ptr<ImageWriter> writer;
|
std::unique_ptr<ImageWriter> writer(ImageWriter::create(config.output().file()));
|
||||||
// if (config.output().file().has_img())
|
|
||||||
// write.reset(new ImgImageWriter());
|
|
||||||
// else
|
|
||||||
// Error() << "no output image format specified";
|
|
||||||
|
|
||||||
readDiskCommand(*fluxSource, *decoder, *writer);
|
readDiskCommand(*fluxSource, *decoder, *writer);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
input {
|
input {
|
||||||
disk {
|
disk {
|
||||||
|
fluxfile: "samples/brother-clean.flux"
|
||||||
brother {}
|
brother {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user