mirror of
				https://github.com/davidgiven/fluxengine.git
				synced 2025-10-24 11:11:02 -07:00 
			
		
		
		
	Compare commits
	
		
			1 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | bb82dc864a | 
| @@ -29,7 +29,6 @@ IncludeBlocks: Preserve | ||||
| IndentCaseLabels: 'true' | ||||
| IndentWidth: '4' | ||||
| IndentWrappedFunctionNames: 'false' | ||||
| IndentPPDirectives: BeforeHash | ||||
| KeepEmptyLinesAtTheStartOfBlocks: 'true' | ||||
| NamespaceIndentation: All | ||||
| PointerAlignment: Left | ||||
|   | ||||
| @@ -19,13 +19,4 @@ message Apple2EncoderProto | ||||
|  | ||||
| 	optional uint32 side_one_track_offset = 3 | ||||
| 		[ default = 0, (help) = "offset to apply to track numbers on side 1" ]; | ||||
|  | ||||
|     optional uint32 post_index_gap_bytes = 4 | ||||
|         [ default = 32, (help) = "the number of resync bytes to write after the index mark" ]; | ||||
|  | ||||
|     optional uint32 post_address_gap_bytes = 5 | ||||
|         [ default = 6, (help) = "the number of resync bytes to write after the address gap" ]; | ||||
|  | ||||
|     optional uint32 post_data_gap_bytes = 6 | ||||
|         [ default = 8, (help) = "the number of resync bytes to write after each sector" ]; | ||||
| } | ||||
|   | ||||
| @@ -79,14 +79,18 @@ private: | ||||
|             auto write_bit = [&](bool val) | ||||
|             { | ||||
|                 if (cursor <= bits.size()) | ||||
|                 { | ||||
|                     bits[cursor] = val; | ||||
|                 } | ||||
|                 cursor++; | ||||
|             }; | ||||
|  | ||||
|             auto write_bits = [&](uint32_t bits, int width) | ||||
|             { | ||||
|                 for (int i = width; i--;) | ||||
|                 { | ||||
|                     write_bit(bits & (1u << i)); | ||||
|                 } | ||||
|             }; | ||||
|  | ||||
|             auto write_gcr44 = [&](uint8_t value) | ||||
| @@ -100,13 +104,15 @@ private: | ||||
|             }; | ||||
|  | ||||
|             // The special "FF40" sequence is used to synchronize the receiving | ||||
|             // shift register. It's written as "0 1111 1111 0"; FF indicates the | ||||
|             // 8 consecutive 1-bits, while "40" indicaes the total number of | ||||
|             // shift register. It's written as "1111 1111 00"; FF indicates the | ||||
|             // 8 consecutive 1-bits, while "40" indicates the total number of | ||||
|             // microseconds. | ||||
|             auto write_ff40 = [&](int n = 1) | ||||
|             { | ||||
|                 for (; n--;) | ||||
|                     write_bits(0xff << 1, 10); | ||||
|                 { | ||||
|                     write_bits(0xff << 2, 10); | ||||
|                 } | ||||
|             }; | ||||
|  | ||||
|             // There is data to encode to disk. | ||||
| @@ -121,9 +127,7 @@ private: | ||||
|             // | ||||
|             // In standard formatting, the first logical sector apparently gets | ||||
|             // extra padding. | ||||
|             write_ff40(sector.logicalSector == 0 | ||||
|                            ? _config.post_index_gap_bytes() | ||||
|                            : _config.post_data_gap_bytes()); | ||||
|             write_ff40(sector.logicalSector == 0 ? 32 : 8); | ||||
|  | ||||
|             int track = sector.logicalTrack; | ||||
|             if (sector.logicalSide == 1) | ||||
| @@ -140,7 +144,7 @@ private: | ||||
|  | ||||
|             // Write data syncing leader: FF40 + APPLE2_DATA_RECORD + sector | ||||
|             // data + sum + DE AA EB (+ mystery bits cut off of the scan?) | ||||
|             write_ff40(_config.post_address_gap_bytes()); | ||||
|             write_ff40(8); | ||||
|             write_bits(APPLE2_DATA_RECORD, 24); | ||||
|  | ||||
|             // Convert the sector data to GCR, append the checksum, and write it | ||||
|   | ||||
| @@ -137,8 +137,10 @@ std::shared_ptr<TrackDataFlux> Decoder::decodeToSectors( | ||||
|  | ||||
|         if (_sector->status != Sector::MISSING) | ||||
|         { | ||||
|             auto trackLayout = Layout::getLayoutOfTrack( | ||||
|                 _sector->logicalTrack, _sector->logicalSide); | ||||
|             if ((_sector->status == Sector::OK) && | ||||
|                 ((_sector->logicalTrack != trackInfo->logicalTrack) || | ||||
|                     (_sector->logicalSide != trackInfo->logicalSide))) | ||||
|                 _sector->status == Sector::WRONG_PLACE; | ||||
|             _trackdata->sectors.push_back(_sector); | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -21,7 +21,7 @@ import "arch/zilogmcz/zilogmcz.proto"; | ||||
| import "lib/fluxsink/fluxsink.proto"; | ||||
| import "lib/common.proto"; | ||||
|  | ||||
| //NEXT: 32 | ||||
| //NEXT: 33 | ||||
| message DecoderProto { | ||||
| 	optional double pulse_debounce_threshold = 1 [default = 0.30, | ||||
| 		(help) = "ignore pulses with intervals shorter than this, in fractions of a clock"]; | ||||
| @@ -66,6 +66,7 @@ message DecoderProto { | ||||
| 	optional string write_csv_to = 23 | ||||
| 		[(help) = "if set, write a CSV report of the disk state"]; | ||||
| 	optional bool skip_unnecessary_tracks = 29 [default = true, | ||||
| 		(help) = "don't read tracks if we already have all necessary sectors"]; | ||||
| 		(help) = "don't read physical tracks if we already have all necessary sectors"]; | ||||
| 	optional bool collate_sectors_from_all_tracks = 32 [default = false, | ||||
| 		(help) = "when creating the image, consider all valid sectors even if they're on the wrong track"]; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -97,9 +97,16 @@ void measureDiskRotation() | ||||
|     log(EndSpeedOperationLogMessage{oneRevolution}); | ||||
| } | ||||
|  | ||||
| static int getEffectiveStatus(int status) | ||||
| { | ||||
|     if ((status == Sector::WRONG_PLACE) && | ||||
|         globalConfig()->decoder().collate_sectors_from_all_tracks()) | ||||
|         return Sector::OK; | ||||
|     return status; | ||||
| } | ||||
|  | ||||
| /* Given a set of sectors, deduplicates them sensibly (e.g. if there is a good | ||||
|  * and bad version of the same sector, the bad version is dropped). */ | ||||
|  | ||||
| static std::set<std::shared_ptr<const Sector>> collectSectors( | ||||
|     std::set<std::shared_ptr<const Sector>>& track_sectors, | ||||
|     bool collapse_conflicts = true) | ||||
| @@ -124,9 +131,11 @@ static std::set<std::shared_ptr<const Sector>> collectSectors( | ||||
|             it->second, | ||||
|             [&](auto left, auto& rightit) -> std::shared_ptr<const Sector> | ||||
|             { | ||||
|                 int leftStatus = left->status; | ||||
|                 auto& right = rightit.second; | ||||
|                 if ((left->status == Sector::OK) && | ||||
|                     (right->status == Sector::OK) && | ||||
|                 int rightStatus = right->status; | ||||
|                 if ((leftStatus == Sector::OK) && | ||||
|                     (rightStatus == Sector::OK) && | ||||
|                     (left->data != right->data)) | ||||
|                 { | ||||
|                     if (!collapse_conflicts) | ||||
| @@ -139,13 +148,13 @@ static std::set<std::shared_ptr<const Sector>> collectSectors( | ||||
|                     s->status = Sector::CONFLICT; | ||||
|                     return s; | ||||
|                 } | ||||
|                 if (left->status == Sector::CONFLICT) | ||||
|                 if (leftStatus == Sector::CONFLICT) | ||||
|                     return left; | ||||
|                 if (right->status == Sector::CONFLICT) | ||||
|                 if (rightStatus == Sector::CONFLICT) | ||||
|                     return right; | ||||
|                 if (left->status == Sector::OK) | ||||
|                 if (leftStatus == Sector::OK) | ||||
|                     return left; | ||||
|                 if (right->status == Sector::OK) | ||||
|                 if (rightStatus == Sector::OK) | ||||
|                     return right; | ||||
|                 return left; | ||||
|             }); | ||||
|   | ||||
| @@ -31,6 +31,8 @@ std::string Sector::statusToString(Status status) | ||||
|             return "present but no data found"; | ||||
|         case Status::CONFLICT: | ||||
|             return "conflicting data"; | ||||
|         case Status::WRONG_PLACE: | ||||
|             return "incorrectly placed"; | ||||
|         default: | ||||
|             return fmt::format("unknown error {}", status); | ||||
|     } | ||||
| @@ -50,6 +52,8 @@ std::string Sector::statusToChar(Status status) | ||||
|             return "!"; | ||||
|         case Status::CONFLICT: | ||||
|             return "*"; | ||||
|         case Status::WRONG_PLACE: | ||||
|             return "/"; | ||||
|         default: | ||||
|             return "?"; | ||||
|     } | ||||
|   | ||||
| @@ -44,6 +44,7 @@ struct Sector : public LogicalLocation | ||||
|         DATA_MISSING, | ||||
|         CONFLICT, | ||||
|         INTERNAL_ERROR, | ||||
|         WRONG_PLACE, | ||||
|     }; | ||||
|  | ||||
|     static std::string statusToString(Status status); | ||||
|   | ||||
| @@ -109,6 +109,10 @@ option_group { | ||||
| 		set_by_default: true | ||||
|  | ||||
| 		config { | ||||
| 			decoder { | ||||
| 				collate_sectors_from_all_tracks: true | ||||
| 			} | ||||
| 			 | ||||
| 			layout { | ||||
| 				format_type: FORMATTYPE_80TRACK | ||||
| 			} | ||||
|   | ||||
		Reference in New Issue
	
	Block a user