mirror of
				https://github.com/davidgiven/fluxengine.git
				synced 2025-10-24 11:11:02 -07:00 
			
		
		
		
	Compare commits
	
		
			1 Commits
		
	
	
		
			builds
			...
			better-pul
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 537324c952 | 
| @@ -8,10 +8,10 @@ | ||||
| #include "fmt/format.h" | ||||
| #include <numeric> | ||||
|  | ||||
| static DoubleFlag clockDecodeThreshold( | ||||
|     { "--clock-decode-threshold" }, | ||||
|     "Pulses below this fraction of a clock tick are considered spurious and ignored.", | ||||
|     0.80); | ||||
| static DoubleFlag pulseAccuracyFactor( | ||||
|     { "--pulse-accuracy-factor" }, | ||||
|     "Pulses must be within this much of an expected clock tick to register (in clock periods).", | ||||
|     0.4); | ||||
|  | ||||
| static SettableFlag showClockHistogram( | ||||
|     { "--show-clock-histogram" }, | ||||
| @@ -114,7 +114,20 @@ nanoseconds_t Fluxmap::guessClock() const | ||||
|     if (showClockHistogram) | ||||
|     { | ||||
|         std::cout << "Clock detection histogram:" << std::endl; | ||||
|         double blocks_per_count = 320.0/max; | ||||
|  | ||||
|         auto show_noise_and_signal_levels = [=] { | ||||
|             /* Must be 12 chars in left margin */ | ||||
|             std::cout << fmt::format("        0% >{:>{}}{:>{}}{:<{}}< 100%\n", | ||||
|                 "|", | ||||
|                 int((noise_floor*blocks_per_count)/8), | ||||
|                 "|", | ||||
|                 int((signal_level - noise_floor)*blocks_per_count/8), | ||||
|                 "", | ||||
|                 int((max - signal_level)*blocks_per_count/8)); | ||||
|         }; | ||||
|  | ||||
|         show_noise_and_signal_levels(); | ||||
| 		bool skipping = true; | ||||
|         for (int i=0; i<256; i++) | ||||
| 		{ | ||||
| @@ -122,14 +135,14 @@ nanoseconds_t Fluxmap::guessClock() const | ||||
| 			if (value < noise_floor/2) | ||||
| 			{ | ||||
| 				if (!skipping) | ||||
| 					std::cout << "..." << std::endl; | ||||
| 					show_noise_and_signal_levels(); | ||||
| 				skipping = true; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				skipping = false; | ||||
|  | ||||
| 				int bar = 320*value/max; | ||||
| 				int bar = value * blocks_per_count; | ||||
| 				int fullblocks = bar / 8; | ||||
|  | ||||
| 				std::string s; | ||||
| @@ -137,7 +150,8 @@ nanoseconds_t Fluxmap::guessClock() const | ||||
| 					s += BLOCK_ELEMENTS[8]; | ||||
| 				s += BLOCK_ELEMENTS[bar & 7]; | ||||
|  | ||||
| 				std::cout << fmt::format("{:.2f} {:6} {}", (double)i * US_PER_TICK, value, s); | ||||
|                 /* Must be 10 chars in left margin */ | ||||
| 				std::cout << fmt::format("{:5.2f}{:6} {}", (double)i * US_PER_TICK, value, s); | ||||
| 				std::cout << std::endl; | ||||
| 			} | ||||
| 		} | ||||
| @@ -161,7 +175,7 @@ nanoseconds_t Fluxmap::guessClock() const | ||||
| const RawBits Fluxmap::decodeToBits(nanoseconds_t clockPeriod) const | ||||
| { | ||||
|     int pulses = duration() / clockPeriod; | ||||
|     nanoseconds_t lowerThreshold = clockPeriod * clockDecodeThreshold; | ||||
|     nanoseconds_t pulseAccuracy = pulseAccuracyFactor * clockPeriod; | ||||
|  | ||||
|     auto bitmap = std::make_unique<std::vector<bool>>(pulses); | ||||
|     auto indices = std::make_unique<std::vector<size_t>>(); | ||||
| @@ -178,13 +192,17 @@ const RawBits Fluxmap::decodeToBits(nanoseconds_t clockPeriod) const | ||||
|             timestamp += interval * NS_PER_TICK; | ||||
|             if (opcode == -1) | ||||
|                 goto abort; | ||||
|             else if ((opcode == 0x80) && (timestamp >= lowerThreshold)) | ||||
|             else if (opcode == 0x80) | ||||
|                 break; | ||||
|             else if (opcode == 0x81) | ||||
|                 indices->push_back(count); | ||||
|         } | ||||
|  | ||||
|         int clocks = (timestamp + clockPeriod/2) / clockPeriod; | ||||
|         nanoseconds_t expectedClock = clocks*clockPeriod; | ||||
|         if (abs(expectedClock - timestamp) > pulseAccuracy) | ||||
|             continue; | ||||
|  | ||||
|         count += clocks; | ||||
|         if (count >= bitmap->size()) | ||||
|             goto abort; | ||||
| @@ -197,7 +215,7 @@ abort: | ||||
|     return rawbits; | ||||
| } | ||||
|  | ||||
| nanoseconds_t AbstractDecoder::guessClock(Fluxmap& fluxmap) const | ||||
| nanoseconds_t AbstractDecoder::guessClock(Fluxmap& fluxmap, unsigned physicalTrack) const | ||||
| { | ||||
|     return fluxmap.guessClock(); | ||||
| } | ||||
|   | ||||
| @@ -22,7 +22,7 @@ class AbstractDecoder | ||||
| public: | ||||
|     virtual ~AbstractDecoder() {} | ||||
|  | ||||
|     virtual nanoseconds_t guessClock(Fluxmap& fluxmap) const; | ||||
|     virtual nanoseconds_t guessClock(Fluxmap& fluxmap, unsigned physicalTrack) const; | ||||
|     virtual RawRecordVector extractRecords(const RawBits& rawbits) const = 0; | ||||
|     virtual SectorVector decodeToSectors(const RawRecordVector& rawrecords, | ||||
|             unsigned physicalTrack) = 0; | ||||
|   | ||||
| @@ -69,7 +69,7 @@ SectorVector AbstractIbmDecoder::decodeToSectors(const RawRecordVector& rawRecor | ||||
|     return sectors; | ||||
| } | ||||
|  | ||||
| nanoseconds_t IbmMfmDecoder::guessClock(Fluxmap& fluxmap) const | ||||
| nanoseconds_t IbmMfmDecoder::guessClock(Fluxmap& fluxmap, unsigned physicalTrack) const | ||||
| { | ||||
|     return fluxmap.guessClock() / 2; | ||||
| } | ||||
|   | ||||
| @@ -65,7 +65,7 @@ public: | ||||
|         AbstractIbmDecoder(sectorIdBase) | ||||
|     {} | ||||
|  | ||||
|     nanoseconds_t guessClock(Fluxmap& fluxmap) const; | ||||
|     nanoseconds_t guessClock(Fluxmap& fluxmap, unsigned physicalTrack) const; | ||||
|     int recordMatcher(uint64_t fifo) const; | ||||
|  | ||||
| protected: | ||||
|   | ||||
| @@ -6,10 +6,16 @@ | ||||
| #include "sector.h" | ||||
| #include "macintosh.h" | ||||
| #include "bytes.h" | ||||
| #include "flags.h" | ||||
| #include "fmt/format.h" | ||||
| #include <string.h> | ||||
| #include <algorithm> | ||||
|  | ||||
| static BoolFlag guessClockFlag( | ||||
| 	{ "--guess-clock" }, | ||||
| 	"Guess the clock rate rather than using the hard-coded table.", | ||||
|     false); | ||||
|  | ||||
| static int decode_data_gcr(uint8_t gcr) | ||||
| { | ||||
|     switch (gcr) | ||||
| @@ -144,6 +150,10 @@ SectorVector MacintoshDecoder::decodeToSectors( | ||||
|                     break; | ||||
|                 nextSector = decode_data_gcr(rawbytes[4]); | ||||
|                 nextSide = decode_data_gcr(rawbytes[5]); | ||||
|                 if (nextSector > 11) | ||||
|                     break; | ||||
|                 if (nextSide > 1) | ||||
|                     break; | ||||
|                 uint8_t formatByte = decode_data_gcr(rawbytes[6]); | ||||
|                 uint8_t wantedsum = decode_data_gcr(rawbytes[7]); | ||||
|  | ||||
| @@ -189,3 +199,19 @@ int MacintoshDecoder::recordMatcher(uint64_t fifo) const | ||||
| 		return 24; | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| nanoseconds_t MacintoshDecoder::guessClock(Fluxmap& fluxmap, unsigned physicalTrack) const | ||||
| { | ||||
|     if (guessClockFlag) | ||||
|         return AbstractDecoder::guessClock(fluxmap, physicalTrack); | ||||
|  | ||||
|     if (physicalTrack < 16) | ||||
|         return 2750; | ||||
|     if (physicalTrack < 32) | ||||
|         return 3000; | ||||
|     if (physicalTrack < 48) | ||||
|         return 3250; | ||||
|     if (physicalTrack < 64) | ||||
|         return 3580; | ||||
|     return 4000; | ||||
| } | ||||
|   | ||||
| @@ -17,6 +17,7 @@ public: | ||||
|  | ||||
|     SectorVector decodeToSectors(const RawRecordVector& rawRecords, unsigned physicalTrack); | ||||
|     int recordMatcher(uint64_t fifo) const; | ||||
|     nanoseconds_t guessClock(Fluxmap& fluxmap, unsigned physicalTrack) const; | ||||
| }; | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -147,7 +147,7 @@ void readDiskCommand(AbstractDecoder& decoder, const std::string& outputFilename | ||||
| 		{ | ||||
| 			std::unique_ptr<Fluxmap> fluxmap = track->read(); | ||||
|  | ||||
| 			nanoseconds_t clockPeriod = decoder.guessClock(*fluxmap); | ||||
| 			nanoseconds_t clockPeriod = decoder.guessClock(*fluxmap, track->track); | ||||
| 			if (clockPeriod == 0) | ||||
| 			{ | ||||
| 				std::cout << "       no clock detected; giving up" << std::endl; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user