mirror of
				https://github.com/davidgiven/fluxengine.git
				synced 2025-10-24 11:11:02 -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 tracks = 1; | ||||
| 	optional int32 heads = 2; | ||||
| 	optional int32 sectors = 3; | ||||
| 	repeated Format format = 4; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -6,6 +6,7 @@ | ||||
| #include "imagewriter/imagewriter.h" | ||||
| #include "fmt/format.h" | ||||
| #include "ldbs.h" | ||||
| #include "lib/config.pb.h" | ||||
| #include <algorithm> | ||||
| #include <iostream> | ||||
| #include <fstream> | ||||
| @@ -24,15 +25,15 @@ static int sectors_per_track(int track) | ||||
| class D64ImageWriter : public ImageWriter | ||||
| { | ||||
| public: | ||||
| 	D64ImageWriter(const SectorSet& sectors, const ImageSpec& spec): | ||||
| 		ImageWriter(sectors, spec) | ||||
| 	D64ImageWriter(const Config_OutputFile& config): | ||||
| 		ImageWriter(config) | ||||
| 	{} | ||||
|  | ||||
| 	void writeImage() | ||||
| 	void writeImage(const SectorSet& sectors) | ||||
| 	{ | ||||
| 		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()) | ||||
| 			Error() << "cannot open output file"; | ||||
|  | ||||
| @@ -55,9 +56,8 @@ public: | ||||
|     } | ||||
| }; | ||||
|  | ||||
| std::unique_ptr<ImageWriter> ImageWriter::createD64ImageWriter( | ||||
| 	const SectorSet& sectors, const ImageSpec& spec) | ||||
| std::unique_ptr<ImageWriter> ImageWriter::createD64ImageWriter(const Config_OutputFile& config) | ||||
| { | ||||
|     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 "fmt/format.h" | ||||
| #include "ldbs.h" | ||||
| #include "lib/config.pb.h" | ||||
| #include <algorithm> | ||||
| #include <iostream> | ||||
| #include <fstream> | ||||
| @@ -27,35 +28,44 @@ static void write_and_update_checksum(ByteWriter& bw, uint32_t& checksum, const | ||||
| class DiskCopyImageWriter : public ImageWriter | ||||
| { | ||||
| public: | ||||
| 	DiskCopyImageWriter(const SectorSet& sectors, const ImageSpec& spec): | ||||
| 		ImageWriter(sectors, spec) | ||||
| 	DiskCopyImageWriter(const Config_OutputFile& config): | ||||
| 		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; | ||||
|  | ||||
| 		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" | ||||
| 		          << fmt::format("{} tracks, {} heads, {} sectors, {} bytes per sector; {}\n", | ||||
| 				  		spec.cylinders, spec.heads, spec.sectors, spec.bytes, | ||||
| 				  		numCylinders, numHeads, numSectors, numBytes, | ||||
| 						mfm ? "MFM" : "GCR"); | ||||
|  | ||||
| 		auto sectors_per_track = [&](int track) -> int | ||||
| 		{ | ||||
| 			if (mfm) | ||||
| 				return spec.sectors; | ||||
| 				return numSectors; | ||||
|  | ||||
| 			if (track < 16) | ||||
| 				return 12; | ||||
| @@ -77,9 +87,9 @@ public: | ||||
| 		uint32_t tagChecksum = 0; | ||||
| 		uint32_t offset = 0x54; | ||||
| 		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); | ||||
| 				for (int sectorId = 0; sectorId < sectorCount; sectorId++) | ||||
| @@ -97,9 +107,9 @@ public: | ||||
| 		uint32_t sectorDataEnd = offset; | ||||
| 		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); | ||||
| 					for (int sectorId = 0; sectorId < sectorCount; sectorId++) | ||||
| @@ -124,14 +134,14 @@ public: | ||||
| 		if (mfm) | ||||
| 		{ | ||||
| 			format = 0x22; | ||||
| 			if (spec.sectors == 18) | ||||
| 			if (numSectors == 18) | ||||
| 				encoding = 3; | ||||
| 			else | ||||
| 				encoding = 2; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			if (spec.heads == 2) | ||||
| 			if (numHeads == 2) | ||||
| 			{ | ||||
| 				encoding = 1; | ||||
| 				format = 0x22; | ||||
| @@ -155,14 +165,14 @@ public: | ||||
| 		bw.write_8(format); /* format byte */ | ||||
| 		bw.write_be16(0x0100); /* magic number */ | ||||
|  | ||||
| 		image.writeToFile(spec.filename); | ||||
| 		image.writeToFile(_config.filename()); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| 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 "imagewriter/imagewriter.h" | ||||
| #include "utils.h" | ||||
| #include "lib/config.pb.h" | ||||
| #include "fmt/format.h" | ||||
| #include <iostream> | ||||
| #include <fstream> | ||||
|  | ||||
| #if 0 | ||||
| std::map<std::string, ImageWriter::Constructor> ImageWriter::formats = | ||||
| { | ||||
| 	{".adf", ImageWriter::createImgImageWriter}, | ||||
| @@ -19,48 +21,27 @@ std::map<std::string, ImageWriter::Constructor> ImageWriter::formats = | ||||
| 	{".ldbs", ImageWriter::createLDBSImageWriter}, | ||||
| 	{".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; | ||||
|  | ||||
| 	for (const auto& e : formats) | ||||
| 	{ | ||||
| 		if (endsWith(filename, e.first)) | ||||
| 			return e.second; | ||||
| 	} | ||||
|  | ||||
| 	return NULL; | ||||
| 	if (config.has_img()) | ||||
| 		return ImageWriter::createImgImageWriter(config); | ||||
| 	else | ||||
| 		Error() << "bad output image config"; | ||||
| } | ||||
|  | ||||
| std::unique_ptr<ImageWriter> ImageWriter::create(const SectorSet& sectors, const ImageSpec& spec) | ||||
| { | ||||
| 	verifyImageSpec(spec); | ||||
| 	return findConstructor(spec)(sectors, spec); | ||||
| } | ||||
| //void ImageWriter::verifyImageSpec(const ImageSpec& spec) | ||||
| //{ | ||||
| //	if (!findConstructor(spec)) | ||||
| //		Error() << "unrecognised output image filename extension"; | ||||
| //} | ||||
|  | ||||
| void ImageWriter::verifyImageSpec(const ImageSpec& spec) | ||||
| { | ||||
| 	if (!findConstructor(spec)) | ||||
| 		Error() << "unrecognised output image filename extension"; | ||||
| } | ||||
|  | ||||
| ImageWriter::ImageWriter(const SectorSet& sectors, const ImageSpec& spec): | ||||
|     sectors(sectors), | ||||
|     spec(spec) | ||||
| ImageWriter::ImageWriter(const Config_OutputFile& config): | ||||
| 	_config(config) | ||||
| {} | ||||
|  | ||||
| void ImageWriter::adjustGeometry() | ||||
| { | ||||
| 	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) | ||||
| void ImageWriter::writeCsv(const SectorSet& sectors, const std::string& filename) | ||||
| { | ||||
| 	std::ofstream f(filename, std::ios::out); | ||||
| 	if (!f.is_open()) | ||||
| @@ -81,47 +62,45 @@ void ImageWriter::writeCsv(const std::string& filename) | ||||
| 		"\"Status\"" | ||||
| 		"\n"; | ||||
|  | ||||
| 	for (int track = 0; track < spec.cylinders; track++) | ||||
| 	for (const auto& it : sectors.get()) | ||||
| 	{ | ||||
| 		for (int head = 0; head < spec.heads; head++) | ||||
| 		{ | ||||
| 			for (int sectorId = 0; sectorId < spec.sectors; sectorId++) | ||||
| 			{ | ||||
| 				f << fmt::format("{},{},", track, head); | ||||
| 				const auto& sector = sectors.get(track, head, sectorId); | ||||
| 				if (!sector) | ||||
| 					f << fmt::format(",,{},,,,,,,,sector not found\n", sectorId); | ||||
| 				else | ||||
| 					f << fmt::format("{},{},{},{},{},{},{},{},{},{},{}\n", | ||||
| 						sector->logicalTrack, | ||||
| 						sector->logicalSide, | ||||
| 						sector->logicalSector, | ||||
| 						sector->clock, | ||||
| 						sector->headerStartTime, | ||||
| 						sector->headerEndTime, | ||||
| 						sector->dataStartTime, | ||||
| 						sector->dataEndTime, | ||||
| 						sector->position.bytes, | ||||
| 						sector->data.size(), | ||||
| 						Sector::statusToString(sector->status) | ||||
| 					); | ||||
| 			} | ||||
| 		} | ||||
| 		const auto& sector = it.second; | ||||
| 		f << fmt::format("{},{},{},{},{},{},{},{},{},{},{},{},{}\n", | ||||
| 			sector->physicalTrack, | ||||
| 			sector->physicalSide, | ||||
| 			sector->logicalTrack, | ||||
| 			sector->logicalSide, | ||||
| 			sector->logicalSector, | ||||
| 			sector->clock, | ||||
| 			sector->headerStartTime, | ||||
| 			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 missingSectors = 0; | ||||
| 	int totalSectors = 0; | ||||
| 	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); | ||||
| 			for (int track = 0; track < spec.cylinders; track++) | ||||
| 			for (int track = 0; track < numCylinders; track++) | ||||
| 			{ | ||||
| 				const auto& sector = sectors.get(track, head, sectorId); | ||||
| 				if (!sector) | ||||
|   | ||||
| @@ -2,47 +2,33 @@ | ||||
| #define IMAGEWRITER_H | ||||
|  | ||||
| class SectorSet; | ||||
| class ImageSpec; | ||||
| class Config_OutputFile; | ||||
|  | ||||
| class ImageWriter | ||||
| { | ||||
| public: | ||||
| 	ImageWriter(const SectorSet& sectors, const ImageSpec& spec); | ||||
| 	ImageWriter(const Config_OutputFile& config); | ||||
| 	virtual ~ImageWriter() {}; | ||||
|  | ||||
| public: | ||||
|     static std::unique_ptr<ImageWriter> create(const SectorSet& sectors, const ImageSpec& spec); | ||||
| 	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> create(const Config_OutputFile& config); | ||||
|  | ||||
|     static std::unique_ptr<ImageWriter> createImgImageWriter( | ||||
| 		const SectorSet& sectors, const ImageSpec& spec); | ||||
| 		const Config_OutputFile& config); | ||||
|     static std::unique_ptr<ImageWriter> createLDBSImageWriter( | ||||
| 		const SectorSet& sectors, const ImageSpec& spec); | ||||
| 		const Config_OutputFile& config); | ||||
|     static std::unique_ptr<ImageWriter> createD64ImageWriter( | ||||
| 		const SectorSet& sectors, const ImageSpec& spec); | ||||
| 		const Config_OutputFile& config); | ||||
|     static std::unique_ptr<ImageWriter> createDiskCopyImageWriter( | ||||
| 		const SectorSet& sectors, const ImageSpec& spec); | ||||
|  | ||||
| 	static Constructor findConstructor(const ImageSpec& spec); | ||||
| 		const Config_OutputFile& config); | ||||
|  | ||||
| public: | ||||
| 	virtual void adjustGeometry(); | ||||
| 	void printMap(); | ||||
| 	void writeCsv(const std::string& filename); | ||||
| 	virtual void writeImage() = 0; | ||||
| 	void printMap(const SectorSet& sectors); | ||||
| 	void writeCsv(const SectorSet& sectors, const std::string& filename); | ||||
| 	virtual void writeImage(const SectorSet& sectors) = 0; | ||||
|  | ||||
| protected: | ||||
| 	const SectorSet& sectors; | ||||
| 	ImageSpec spec; | ||||
| 	const Config_OutputFile& _config; | ||||
| }; | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -4,6 +4,7 @@ | ||||
| #include "sector.h" | ||||
| #include "sectorset.h" | ||||
| #include "imagewriter/imagewriter.h" | ||||
| #include "lib/config.pb.h" | ||||
| #include "fmt/format.h" | ||||
| #include <algorithm> | ||||
| #include <iostream> | ||||
| @@ -12,16 +13,17 @@ | ||||
| class ImgImageWriter : public ImageWriter | ||||
| { | ||||
| public: | ||||
| 	ImgImageWriter(const SectorSet& sectors, const ImageSpec& spec): | ||||
| 		ImageWriter(sectors, spec) | ||||
| 	ImgImageWriter(const Config_OutputFile& config): | ||||
| 		ImageWriter(config) | ||||
| 	{} | ||||
|  | ||||
| 	void writeImage() | ||||
| 	void writeImage(const SectorSet& sectors) | ||||
| 	{ | ||||
| 		unsigned numCylinders = spec.cylinders; | ||||
| 		unsigned numHeads = spec.heads; | ||||
| 		unsigned numSectors = spec.sectors; | ||||
| 		unsigned numBytes = spec.bytes; | ||||
| 		unsigned numCylinders; | ||||
| 		unsigned numHeads; | ||||
| 		unsigned numSectors; | ||||
| 		unsigned numBytes; | ||||
| 		sectors.calculateSize(numCylinders, numHeads, numSectors, numBytes); | ||||
|  | ||||
| 		size_t headSize = numSectors * numBytes; | ||||
| 		size_t trackSize = headSize * numHeads; | ||||
| @@ -32,7 +34,7 @@ public: | ||||
| 						numCylinders * trackSize / 1024) | ||||
| 				<< 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()) | ||||
| 			Error() << "cannot open output file"; | ||||
|  | ||||
| @@ -55,7 +57,7 @@ public: | ||||
| }; | ||||
|  | ||||
| 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 "fmt/format.h" | ||||
| #include "ldbs.h" | ||||
| #include "lib/config.pb.h" | ||||
| #include <algorithm> | ||||
| #include <iostream> | ||||
| #include <fstream> | ||||
| @@ -13,18 +14,20 @@ | ||||
| class LDBSImageWriter : public ImageWriter | ||||
| { | ||||
| public: | ||||
| 	LDBSImageWriter(const SectorSet& sectors, const ImageSpec& spec): | ||||
| 		ImageWriter(sectors, spec) | ||||
| 	LDBSImageWriter(const Config_OutputFile& config): | ||||
| 		ImageWriter(config) | ||||
| 	{} | ||||
|  | ||||
| 	void writeImage() | ||||
| 	void writeImage(const SectorSet& sectors) | ||||
| 	{ | ||||
|         LDBS ldbs; | ||||
|  | ||||
| 		unsigned numCylinders = spec.cylinders; | ||||
| 		unsigned numHeads = spec.heads; | ||||
| 		unsigned numSectors = spec.sectors; | ||||
| 		unsigned numBytes = spec.bytes; | ||||
| 		unsigned numCylinders; | ||||
| 		unsigned numHeads; | ||||
| 		unsigned numSectors; | ||||
| 		unsigned numBytes; | ||||
| 		sectors.calculateSize(numCylinders, numHeads, numSectors, numBytes); | ||||
|  | ||||
| 		std::cout << fmt::format("writing {} tracks, {} heads, {} sectors, {} bytes per sector", | ||||
| 						numCylinders, numHeads, | ||||
| 						numSectors, numBytes) | ||||
| @@ -95,12 +98,11 @@ public: | ||||
|  | ||||
|         uint32_t trackDirectoryAddress = ldbs.put(trackDirectory, LDBS_TRACK_BLOCK); | ||||
|         Bytes data = ldbs.write(trackDirectoryAddress); | ||||
|         data.writeToFile(spec.filename); | ||||
|         data.writeToFile(_config.filename()); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| std::unique_ptr<ImageWriter> ImageWriter::createLDBSImageWriter( | ||||
| 	const SectorSet& sectors, const ImageSpec& spec) | ||||
| std::unique_ptr<ImageWriter> ImageWriter::createLDBSImageWriter(const Config_OutputFile& config) | ||||
| { | ||||
|     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, | ||||
| }; | ||||
|  | ||||
| //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( | ||||
|     { "--write-flux", "-f" }, | ||||
|     "write the raw magnetic flux to this file", | ||||
| @@ -66,16 +56,6 @@ static StringFlag csvFile( | ||||
|  | ||||
| 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() | ||||
| { | ||||
| 	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())) | ||||
| 		{ | ||||
| #if 0 | ||||
| 		auto track = std::make_unique<Track>(location | ||||
| 	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; | ||||
| 			auto track = std::make_unique<Track>(cylinder, side); | ||||
| 			track->fluxsource = &fluxsource; | ||||
|  | ||||
| 		std::map<int, std::unique_ptr<Sector>> readSectors; | ||||
| 		for (int retry = ::retries; retry >= 0; retry--) | ||||
| 		{ | ||||
| 			track->readFluxmap(); | ||||
| 			decoder.decodeToSectors(*track); | ||||
| 			std::map<int, std::unique_ptr<Sector>> readSectors; | ||||
| 			for (int retry = ::retries; retry >= 0; retry--) | ||||
| 			{ | ||||
| 				track->readFluxmap(); | ||||
| 				decoder.decodeToSectors(*track); | ||||
|  | ||||
| 			std::cout << "       "; | ||||
| 				std::cout << fmt::format("{} records, {} sectors; ", | ||||
| 					track->rawrecords.size(), | ||||
| 					track->sectors.size()); | ||||
| 				if (track->sectors.size() > 0) | ||||
| 					std::cout << fmt::format("{:.2f}us clock ({:.0f}kHz); ", | ||||
| 						track->sectors.begin()->clock / 1000.0, | ||||
|                         1000000.0 / track->sectors.begin()->clock); | ||||
| 				std::cout << "       "; | ||||
| 					std::cout << fmt::format("{} records, {} sectors; ", | ||||
| 						track->rawrecords.size(), | ||||
| 						track->sectors.size()); | ||||
| 					if (track->sectors.size() > 0) | ||||
| 						std::cout << fmt::format("{:.2f}us clock ({:.0f}kHz); ", | ||||
| 							track->sectors.begin()->clock / 1000.0, | ||||
| 							1000000.0 / track->sectors.begin()->clock); | ||||
|  | ||||
| 				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) | ||||
| 					for (auto& sector : track->sectors) | ||||
| 					{ | ||||
| 						std::cout << std::endl | ||||
| 								<< "       Failed to read sector " << sector->logicalSector | ||||
| 								<< " (" << Sector::statusToString((Sector::Status)sector->status) << "); "; | ||||
| 						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 | ||||
| 									<< "       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; | ||||
| 					} | ||||
| 				} | ||||
| 				for (unsigned logicalSector : requiredSectors) | ||||
| 				{ | ||||
| 					std::cout << "\n" | ||||
| 					          << "       Required sector " << logicalSector << " missing; "; | ||||
| 					hasBadSectors = true; | ||||
| 				} | ||||
|  | ||||
| 				if (hasBadSectors) | ||||
| 					failures = false; | ||||
| 					if (hasBadSectors) | ||||
| 						failures = false; | ||||
|  | ||||
| 				std::cout << std::endl | ||||
| 						<< "       "; | ||||
| 					std::cout << std::endl | ||||
| 							<< "       "; | ||||
|  | ||||
| 				if (!hasBadSectors) | ||||
| 					if (!hasBadSectors) | ||||
| 						break; | ||||
|  | ||||
| 				if (!track->fluxsource->retryable()) | ||||
| 					break; | ||||
|  | ||||
| 			if (!track->fluxsource->retryable()) | ||||
| 				break; | ||||
|             if (retry == 0) | ||||
|                 std::cout << "giving up" << 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 (retry == 0) | ||||
| 					std::cout << "giving up" << std::endl | ||||
| 							  << "       "; | ||||
| 				else | ||||
| 					std::cout << retry << " retries remaining" << 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 (dumpRecords) | ||||
| 			{ | ||||
| 				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); | ||||
| 					printedTrack = true; | ||||
| 					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; | ||||
| 				} | ||||
|  | ||||
| 				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"; | ||||
|     //writeSectorsToFile(allSectors, outputSpec); | ||||
| 	writer.printMap(allSectors); | ||||
| 	if (!csvFile.get().empty()) | ||||
| 		writer.writeCsv(allSectors, csvFile.get()); | ||||
| 	writer.writeImage(allSectors); | ||||
|  | ||||
| 	if (failures) | ||||
| 		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[]) | ||||
| { | ||||
| Error() << "unimplemented"; | ||||
| #if 0 | ||||
|     auto filenames = flags.parseFlagsWithFilenames(argc, argv); | ||||
|     if (filenames.size() != 2) | ||||
|         syntax(); | ||||
| @@ -32,6 +34,7 @@ int mainConvertImage(int argc, const char* argv[]) | ||||
| 	writer->adjustGeometry(); | ||||
| 	writer->printMap(); | ||||
| 	writer->writeImage(); | ||||
| #endif | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|   | ||||
| @@ -40,11 +40,7 @@ int mainRead(int argc, const char* argv[]) | ||||
| 	else | ||||
| 		Error() << "no input disk format specified"; | ||||
|  | ||||
| 	std::unique_ptr<ImageWriter> writer; | ||||
| //	if (config.output().file().has_img()) | ||||
| //		write.reset(new ImgImageWriter()); | ||||
| //	else | ||||
| //		Error() << "no output image format specified"; | ||||
| 	std::unique_ptr<ImageWriter> writer(ImageWriter::create(config.output().file())); | ||||
|  | ||||
| 	readDiskCommand(*fluxSource, *decoder, *writer); | ||||
|  | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| input { | ||||
| 	disk { | ||||
| 		fluxfile: "samples/brother-clean.flux" | ||||
| 		brother {} | ||||
| 	} | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user