mirror of
https://github.com/davidgiven/fluxengine.git
synced 2025-10-31 11:17:01 -07:00
Compare commits
1 Commits
FluxEngine
...
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