mirror of
				https://github.com/davidgiven/fluxengine.git
				synced 2025-10-24 11:11:02 -07:00 
			
		
		
		
	Merge from master.
This commit is contained in:
		| @@ -133,11 +133,17 @@ public: | ||||
| 				encodeMfm(_bits, _cursor, bytes, _lastBit); | ||||
| 		}; | ||||
|  | ||||
| 		auto writeFillerRawBytes = [&](int count, uint16_t byte) | ||||
| 		{ | ||||
| 			for (int i=0; i<count; i++) | ||||
| 				writeRawBits(byte, 16); | ||||
| 		}; | ||||
|  | ||||
| 		auto writeFillerBytes = [&](int count, uint8_t byte) | ||||
| 		{ | ||||
| 			Bytes bytes = { byte }; | ||||
| 			Bytes b { byte }; | ||||
| 			for (int i=0; i<count; i++) | ||||
| 				writeBytes(bytes); | ||||
| 				writeBytes(b); | ||||
| 		}; | ||||
|  | ||||
| 		double clockRateUs = 1e3 / trackdata.clock_rate_khz(); | ||||
| @@ -160,9 +166,9 @@ public: | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		uint8_t gapFill = trackdata.use_fm() ? 0x00 : 0x4e; | ||||
| 		uint16_t gapFill = trackdata.gap_fill_byte(); | ||||
|  | ||||
| 		writeFillerBytes(trackdata.gap0(), gapFill); | ||||
| 		writeFillerRawBytes(trackdata.gap0(), gapFill); | ||||
| 		if (trackdata.emit_iam()) | ||||
| 		{ | ||||
| 			writeFillerBytes(trackdata.use_fm() ? 6 : 12, 0x00); | ||||
| @@ -172,7 +178,7 @@ public: | ||||
| 					writeRawBits(MFM_IAM_SEPARATOR, 16); | ||||
| 			} | ||||
| 			writeRawBits(trackdata.use_fm() ? FM_IAM_RECORD : MFM_IAM_RECORD, 16); | ||||
| 			writeFillerBytes(trackdata.gap1(), gapFill); | ||||
| 			writeFillerRawBytes(trackdata.gap1(), gapFill); | ||||
| 		} | ||||
|  | ||||
| 		int logicalSide = physicalSide ^ trackdata.swap_sides(); | ||||
| @@ -180,7 +186,7 @@ public: | ||||
| 		for (int sectorId : trackdata.sectors().sector()) | ||||
| 		{ | ||||
| 			if (!first) | ||||
| 				writeFillerBytes(trackdata.gap3(), gapFill); | ||||
| 				writeFillerRawBytes(trackdata.gap3(), gapFill); | ||||
| 			first = false; | ||||
|  | ||||
| 			const auto& sectorData = image.get(physicalTrack, logicalSide, sectorId); | ||||
| @@ -227,7 +233,7 @@ public: | ||||
| 				writeBytes(header.slice(conventionalHeaderStart)); | ||||
| 			} | ||||
|  | ||||
| 			writeFillerBytes(trackdata.gap2(), gapFill); | ||||
| 			writeFillerRawBytes(trackdata.gap2(), gapFill); | ||||
|  | ||||
| 			{ | ||||
| 				Bytes data; | ||||
| @@ -264,7 +270,7 @@ public: | ||||
| 		if (_cursor >= _bits.size()) | ||||
| 			Error() << "track data overrun"; | ||||
| 		while (_cursor < _bits.size()) | ||||
| 			writeFillerBytes(1, gapFill); | ||||
| 			writeFillerRawBytes(1, gapFill); | ||||
|  | ||||
| 		std::unique_ptr<Fluxmap> fluxmap(new Fluxmap); | ||||
| 		fluxmap->appendBits(_bits, clockRateUs*1e3); | ||||
|   | ||||
| @@ -15,7 +15,7 @@ message IbmDecoderProto { | ||||
| } | ||||
|  | ||||
| message IbmEncoderProto { | ||||
| 	// Next: 18 | ||||
| 	// Next: 19 | ||||
| 	message TrackdataProto { | ||||
| 		message SectorsProto { | ||||
| 			repeated int32 sector = 1		[(help) = "write these sectors (in order) on each track"]; | ||||
| @@ -37,6 +37,7 @@ message IbmEncoderProto { | ||||
| 		optional int32 gap3 = 12            [default=80, (help) = "size of gap 4 (the post-data or format gap)"]; | ||||
| 		optional bool swap_sides = 14       [default=false, (help) = "swap side bytes when writing"]; | ||||
| 		optional SectorsProto sectors = 17	[(help) = "write these sectors (in order) on each track"]; | ||||
| 		optional int32 gap_fill_byte = 18   [default=0x9254, (help) = "16-bit raw bit pattern of gap fill byte"]; | ||||
| 	} | ||||
|  | ||||
| 	repeated TrackdataProto trackdata = 1; | ||||
|   | ||||
| @@ -37,7 +37,6 @@ public: | ||||
| 		const FluxMatcher* matcher = nullptr; | ||||
| 		_sector->clock = _fmr->seekToPattern(SECTOR_SYNC_PATTERN, matcher); | ||||
| 		if (matcher == &SECTOR_SYNC_PATTERN) { | ||||
| 			readRawBits(16); | ||||
| 			return SECTOR_RECORD; | ||||
| 		} | ||||
| 		return UNKNOWN_RECORD; | ||||
| @@ -45,6 +44,7 @@ public: | ||||
|  | ||||
| 	void decodeSectorRecord() | ||||
| 	{ | ||||
| 		readRawBits(16); | ||||
| 		auto rawbits = readRawBits(MICROPOLIS_ENCODED_SECTOR_SIZE*16); | ||||
| 		auto bytes = decodeFmMfm(rawbits).slice(0, MICROPOLIS_ENCODED_SECTOR_SIZE); | ||||
| 		ByteReader br(bytes); | ||||
|   | ||||
| @@ -127,13 +127,11 @@ public: | ||||
|  | ||||
| 		if (matcher == &MFM_PATTERN) { | ||||
| 			_sectorType = SECTOR_TYPE_MFM; | ||||
| 			readRawBits(48); | ||||
| 			return SECTOR_RECORD; | ||||
| 		} | ||||
|  | ||||
| 		if (matcher == &FM_PATTERN) { | ||||
| 			_sectorType = SECTOR_TYPE_FM; | ||||
| 			readRawBits(48); | ||||
| 			return SECTOR_RECORD; | ||||
| 		} | ||||
|  | ||||
| @@ -155,6 +153,8 @@ public: | ||||
| 			headerSize = NORTHSTAR_HEADER_SIZE_SD; | ||||
| 		} | ||||
|  | ||||
| 		readRawBits(48); | ||||
|  | ||||
| 		auto rawbits = readRawBits(recordSize * 16); | ||||
| 		auto bytes = decodeFmMfm(rawbits).slice(0, recordSize); | ||||
| 		ByteReader br(bytes); | ||||
|   | ||||
| @@ -93,3 +93,18 @@ void Fluxmap::precompensate(int threshold_ticks, int amount_ticks) | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| std::vector<Fluxmap> Fluxmap::split() { | ||||
|     std::vector<Fluxmap> maps; | ||||
|     Fluxmap map; | ||||
|     for (unsigned i=0; i<_bytes.size(); i++) { | ||||
|         if (_bytes[i] == F_DESYNC) { | ||||
|             maps.push_back(map); | ||||
|             map = Fluxmap(); | ||||
|         } else { | ||||
|             map.appendByte(_bytes[i]); | ||||
|         } | ||||
|     } | ||||
|     maps.push_back(map); | ||||
|     return maps; | ||||
| } | ||||
|   | ||||
| @@ -58,7 +58,8 @@ public: | ||||
|  | ||||
| 	Fluxmap& appendBits(const std::vector<bool>& bits, nanoseconds_t clock); | ||||
|  | ||||
| 	void precompensate(int threshold_ticks, int amount_ticks); | ||||
|     void precompensate(int threshold_ticks, int amount_ticks); | ||||
|     std::vector<Fluxmap> split(); | ||||
|  | ||||
| private: | ||||
| 	uint8_t& findLastByte(); | ||||
|   | ||||
| @@ -92,7 +92,9 @@ public: | ||||
| 		trackheader.header.track_id[2] = 'K'; | ||||
| 		trackheader.header.strack = strack; | ||||
|  | ||||
| 		FluxmapReader fmr(fluxmap); | ||||
| 		auto lastFluxmap = fluxmap.split().back(); | ||||
|  | ||||
| 		FluxmapReader fmr(lastFluxmap); | ||||
| 		Bytes fluxdata; | ||||
| 		ByteWriter fluxdataWriter(fluxdata); | ||||
|  | ||||
|   | ||||
| @@ -40,7 +40,6 @@ public: | ||||
|  | ||||
|         ByteReader headerReader(header); | ||||
|  | ||||
|         // media flag indicates media density, currently unused | ||||
|         char mediaFlag = headerReader.seek(0x1b).read_8(); | ||||
|  | ||||
|         inputFile.seekg( 0, std::ios::end ); | ||||
| @@ -59,13 +58,22 @@ public: | ||||
|         inputFile.read((char*) trackTable.begin(), trackTable.size()); | ||||
|         ByteReader trackTableReader(trackTable); | ||||
|  | ||||
|         int diskSectorsPerTrack = -1; | ||||
|  | ||||
|         if (config.encoder().format_case() != EncoderProto::FormatCase::FORMAT_NOT_SET) | ||||
|             std::cout << "D88: overriding configured format"; | ||||
|  | ||||
|         auto ibm = config.mutable_encoder()->mutable_ibm(); | ||||
|         config.mutable_cylinders()->set_end(0); | ||||
|         if (mediaFlag == 0x20) { | ||||
|             std::cout << "D88: high density mode\n"; | ||||
|             if (config.flux_sink().dest_case() == FluxSinkProto::DestCase::kDrive) { | ||||
|                 config.mutable_flux_sink()->mutable_drive()->set_high_density(true); | ||||
|             } | ||||
|         } else { | ||||
|             std::cout << "D88: single/double density mode\n"; | ||||
|             if (config.flux_sink().dest_case() == FluxSinkProto::DestCase::kDrive) { | ||||
|                 config.mutable_flux_sink()->mutable_drive()->set_high_density(false); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         std::unique_ptr<Image> image(new Image); | ||||
|         for (int track = 0; track < trackTableSize / 4; track++) | ||||
| @@ -109,11 +117,6 @@ public: | ||||
|                 } else if (currentSectorsInTrack != sectorsInTrack) { | ||||
|                     Error() << "D88: mismatched number of sectors in track"; | ||||
|                 } | ||||
|                 if (diskSectorsPerTrack < 0) { | ||||
|                     diskSectorsPerTrack = sectorsInTrack; | ||||
|                 } else if (diskSectorsPerTrack != sectorsInTrack) { | ||||
|                     Error() << "D88: varying numbers of sectors per track is currently unsupported"; | ||||
|                 } | ||||
|                 if (currentTrackCylinder < 0) { | ||||
|                     currentTrackCylinder = cylinder; | ||||
|                 } else if (currentTrackCylinder != cylinder) { | ||||
| @@ -127,7 +130,7 @@ public: | ||||
|                     trackdata->set_sector_size(sectorSize); | ||||
|                     trackdata->set_use_fm(fm); | ||||
|                     if (fm) { | ||||
|                         //trackdata->set_clock_rate_khz(250*300/360); | ||||
|                         trackdata->set_gap_fill_byte(0xffff); | ||||
|                         trackdata->set_idam_byte(0xf57e); | ||||
|                         trackdata->set_dam_byte(0xf56f); | ||||
|                     } | ||||
|   | ||||
| @@ -33,7 +33,7 @@ public: | ||||
| 		std::cout << fmt::format("Writing {} cylinders, {} sides, {} sectors, {} ({} bytes/sector), {} kB total", | ||||
| 				geometry.numTracks, geometry.numSides, | ||||
| 				geometry.numSectors, geometry.sectorSize == 256 ? "SD" : "DD", geometry.sectorSize, | ||||
| 				geometry.numTracks * geometry.sectorSize / 1024) | ||||
| 				geometry.numTracks * geometry.numSides * geometry.numSectors * geometry.sectorSize / 1024) | ||||
| 				<< std::endl; | ||||
|  | ||||
| 		std::ofstream outputFile(_config.filename(), std::ios::out | std::ios::binary); | ||||
|   | ||||
| @@ -141,11 +141,13 @@ void setProtoFieldFromString(ProtoField& protoField, const std::string& value) | ||||
| 			static const std::map<std::string, bool> boolvalues = { | ||||
| 				{ "false", false }, | ||||
| 				{ "f",     false }, | ||||
| 				{ "no",    false }, | ||||
| 				{ "n",     false }, | ||||
| 				{ "0",     false }, | ||||
| 				{ "true",  true }, | ||||
| 				{ "t",     true }, | ||||
| 				{ "n",     true }, | ||||
| 				{ "yes",   true }, | ||||
| 				{ "y",     true }, | ||||
| 				{ "1",     true }, | ||||
| 			}; | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user