mirror of
				https://github.com/davidgiven/fluxengine.git
				synced 2025-10-24 11:11:02 -07:00 
			
		
		
		
	Attach the underlying raw records to Sector structures; add a .raw exporter for
getting the MFM/FM/GCR stream.
This commit is contained in:
		
							
								
								
									
										18
									
								
								doc/using.md
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								doc/using.md
									
									
									
									
									
								
							| @@ -282,14 +282,22 @@ FluxEngine also supports a number of file system image formats. When using the | ||||
|    | ||||
|   - `<filename.ldbs>` | ||||
|  | ||||
| 	Write to a [LDBS generic image | ||||
| 	file](https://www.seasip.info/Unix/LibDsk/ldbs.html). **Write only.** | ||||
|   Write to a [LDBS generic image | ||||
|   file](https://www.seasip.info/Unix/LibDsk/ldbs.html). **Write only.** | ||||
|  | ||||
|   - `<filename.d64>` | ||||
|    | ||||
| 	Write to a [D64 image | ||||
| 	file](http://unusedino.de/ec64/technical/formats/d64.html), commonly used | ||||
| 	by Commodore 64 emulators. **Write only.** | ||||
|   Write to a [D64 image | ||||
|   file](http://unusedino.de/ec64/technical/formats/d64.html), commonly used by | ||||
|   Commodore 64 emulators. **Write only.** | ||||
|  | ||||
|   - `<filename.raw>` | ||||
|  | ||||
|   Write undecoded data to a raw binary file. **Write only.** This gives you the | ||||
|   underlying MFM, FM or GCR stream, without actually doing the decode into | ||||
|   user-visible bytes. However, the decode is still done in order to check for | ||||
|   correctness. Individual records are separated by three `\\0` bytes and tracks | ||||
|   are seperated by four `\\0` bytes; tracks are emitted in CHS order. | ||||
|  | ||||
| ### High density disks | ||||
|  | ||||
|   | ||||
| @@ -132,6 +132,7 @@ void AbstractDecoder::pushRecord(const Fluxmap::Position& start, const Fluxmap:: | ||||
|  | ||||
| 	auto record = std::make_shared<Record>(); | ||||
| 	_trackdata->records.push_back(record); | ||||
| 	_sector->records.push_back(record); | ||||
| 	 | ||||
| 	record->startTime = start.ns(); | ||||
| 	record->endTime = end.ns(); | ||||
|   | ||||
| @@ -29,6 +29,9 @@ std::unique_ptr<ImageWriter> ImageWriter::create(const ImageWriterProto& config) | ||||
| 		case ImageWriterProto::kNsi: | ||||
| 			return ImageWriter::createNsiImageWriter(config); | ||||
|  | ||||
| 		case ImageWriterProto::kRaw: | ||||
| 			return ImageWriter::createRawImageWriter(config); | ||||
|  | ||||
| 		default: | ||||
| 			Error() << "bad output image config"; | ||||
| 			return std::unique_ptr<ImageWriter>(); | ||||
| @@ -45,8 +48,9 @@ void ImageWriter::updateConfigForFilename(ImageWriterProto* proto, const std::st | ||||
| 		{".diskcopy", [&]() { proto->mutable_diskcopy(); }}, | ||||
| 		{".img",      [&]() { proto->mutable_img(); }}, | ||||
| 		{".ldbs",     [&]() { proto->mutable_ldbs(); }}, | ||||
| 		{".st",       [&]() { proto->mutable_img(); }}, | ||||
| 		{".nsi",      [&]() { proto->mutable_nsi(); }}, | ||||
| 		{".raw",      [&]() { proto->mutable_raw(); }}, | ||||
| 		{".st",       [&]() { proto->mutable_img(); }}, | ||||
| 		{".xdf",      [&]() { proto->mutable_img(); }}, | ||||
| 	}; | ||||
|  | ||||
|   | ||||
| @@ -14,16 +14,12 @@ public: | ||||
|     static std::unique_ptr<ImageWriter> create(const ImageWriterProto& config); | ||||
| 	static void updateConfigForFilename(ImageWriterProto* proto, const std::string& filename); | ||||
|  | ||||
|     static std::unique_ptr<ImageWriter> createImgImageWriter( | ||||
| 		const ImageWriterProto& config); | ||||
|     static std::unique_ptr<ImageWriter> createLDBSImageWriter( | ||||
| 		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> createNsiImageWriter( | ||||
| 		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); | ||||
|  | ||||
| public: | ||||
| 	void printMap(const Image& sectors); | ||||
|   | ||||
| @@ -29,6 +29,7 @@ message LDBSOutputProto { | ||||
|  | ||||
| message DiskCopyOutputProto {} | ||||
| message NsiOutputProto {} | ||||
| message RawOutputProto {} | ||||
|  | ||||
| message ImageWriterProto { | ||||
| 	optional string filename = 1 [(help) = "filename of output sector image"]; | ||||
| @@ -38,6 +39,7 @@ message ImageWriterProto { | ||||
| 		LDBSOutputProto ldbs = 4; | ||||
| 		DiskCopyOutputProto diskcopy = 5; | ||||
| 		NsiOutputProto nsi = 6; | ||||
| 		RawOutputProto raw = 7; | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										73
									
								
								lib/imagewriter/rawimagewriter.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								lib/imagewriter/rawimagewriter.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,73 @@ | ||||
| #include "globals.h" | ||||
| #include "flags.h" | ||||
| #include "sector.h" | ||||
| #include "imagewriter/imagewriter.h" | ||||
| #include "fmt/format.h" | ||||
| #include "decoders/decoders.h" | ||||
| #include "image.h" | ||||
| #include "arch/northstar/northstar.h" | ||||
| #include "lib/imagewriter/imagewriter.pb.h" | ||||
| #include <algorithm> | ||||
| #include <iostream> | ||||
| #include <fstream> | ||||
|  | ||||
| class RawImageWriter : public ImageWriter | ||||
| { | ||||
| public: | ||||
| 	RawImageWriter(const ImageWriterProto& config): | ||||
| 		ImageWriter(config) | ||||
| 	{} | ||||
|  | ||||
| 	void writeImage(const Image& image) | ||||
| 	{ | ||||
| 		const Geometry& geometry = image.getGeometry(); | ||||
|  | ||||
| 		size_t trackSize = geometry.numSectors * geometry.sectorSize; | ||||
|  | ||||
| 		if (geometry.numTracks * trackSize == 0) { | ||||
| 			std::cout << "RAW: no sectors in output; skipping image file generation." << std::endl; | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| 		std::cout << fmt::format("RAW: writing {} cylinders, {} sides\n", | ||||
| 				geometry.numTracks, geometry.numSides); | ||||
|  | ||||
| 		std::ofstream outputFile(_config.filename(), std::ios::out | std::ios::binary); | ||||
| 		if (!outputFile.is_open()) | ||||
| 			Error() << "RAW: cannot open output file"; | ||||
|  | ||||
| 		unsigned sectorFileOffset; | ||||
| 		for (int track = 0; track < geometry.numTracks * geometry.numSides; track++) | ||||
| 		{ | ||||
| 			int side = (track < geometry.numTracks) ? 0 : 1; | ||||
|  | ||||
| 			std::vector<std::shared_ptr<Record>> records; | ||||
| 			for (int sectorId = 0; sectorId < geometry.numSectors; sectorId++) | ||||
| 			{ | ||||
| 				const auto& sector = image.get(track % geometry.numTracks, side, sectorId); | ||||
| 				if (sector) | ||||
| 					records.insert(records.end(), sector->records.begin(), sector->records.end()); | ||||
| 			} | ||||
| 			 | ||||
| 			std::sort(records.begin(), records.end(), | ||||
| 				[&](std::shared_ptr<Record> left, std::shared_ptr<Record> right) { | ||||
| 					return left->startTime < right->startTime; | ||||
| 				}); | ||||
|  | ||||
| 			for (const auto& record : records) | ||||
| 			{ | ||||
| 				record->rawData.writeTo(outputFile); | ||||
| 				Bytes(3).writeTo(outputFile); | ||||
| 			} | ||||
| 			Bytes(1).writeTo(outputFile); | ||||
| 		} | ||||
| 	} | ||||
| }; | ||||
|  | ||||
|  | ||||
| std::unique_ptr<ImageWriter> ImageWriter::createRawImageWriter( | ||||
| 	const ImageWriterProto& config) | ||||
| { | ||||
|     return std::unique_ptr<ImageWriter>(new RawImageWriter(config)); | ||||
| } | ||||
|  | ||||
| @@ -4,6 +4,8 @@ | ||||
| #include "bytes.h" | ||||
| #include "fluxmap.h" | ||||
|  | ||||
| class Record; | ||||
|  | ||||
| /*  | ||||
|  * Note that sectors here used zero-based numbering throughout (to make the | ||||
|  * maths easier); traditionally floppy disk use 0-based track numbering and | ||||
| @@ -38,6 +40,7 @@ public: | ||||
|     int logicalSide = 0; | ||||
|     int logicalSector = 0; | ||||
|     Bytes data; | ||||
| 	std::vector<std::shared_ptr<Record>> records; | ||||
|  | ||||
| 	std::tuple<int, int, int, Status> key() const | ||||
| 	{ return std::make_tuple(logicalTrack, logicalSide, logicalSector, status); } | ||||
|   | ||||
| @@ -470,6 +470,7 @@ buildlibrary libbackend.a \ | ||||
|     lib/imagewriter/imgimagewriter.cc \ | ||||
|     lib/imagewriter/ldbsimagewriter.cc \ | ||||
|     lib/imagewriter/nsiimagewriter.cc \ | ||||
|     lib/imagewriter/rawimagewriter.cc \ | ||||
|     lib/ldbs.cc \ | ||||
|     lib/proto.cc \ | ||||
|     lib/reader.cc \ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user