Split the FluxmapReader and FluxPattern files.

This commit is contained in:
David Given
2024-10-02 00:42:06 +02:00
parent fc8d0283b1
commit a6981ff7ef
28 changed files with 221 additions and 174 deletions

View File

@@ -4,6 +4,7 @@
#include "lib/core/crc.h"
#include "lib/fluxmap.h"
#include "lib/decoders/fluxmapreader.h"
#include "lib/decoders/fluxpattern.h"
#include "lib/sector.h"
#include "lib/core/bytes.h"
#include "fmt/format.h"

View File

@@ -4,6 +4,7 @@
#include "lib/core/crc.h"
#include "lib/fluxmap.h"
#include "lib/decoders/fluxmapreader.h"
#include "lib/decoders/fluxpattern.h"
#include "lib/sector.h"
#include "lib/core/bytes.h"
#include "fmt/format.h"

View File

@@ -1,6 +1,7 @@
#include "lib/core/globals.h"
#include "lib/fluxmap.h"
#include "lib/decoders/fluxmapreader.h"
#include "lib/decoders/fluxpattern.h"
#include "protocol.h"
#include "lib/decoders/decoders.h"
#include "lib/sector.h"

View File

@@ -1,6 +1,7 @@
#include "lib/core/globals.h"
#include "lib/fluxmap.h"
#include "lib/decoders/fluxmapreader.h"
#include "lib/decoders/fluxpattern.h"
#include "protocol.h"
#include "lib/decoders/decoders.h"
#include "lib/sector.h"

View File

@@ -1,6 +1,7 @@
#include "lib/core/globals.h"
#include "lib/fluxmap.h"
#include "lib/decoders/fluxmapreader.h"
#include "lib/decoders/fluxpattern.h"
#include "lib/decoders/decoders.h"
#include "lib/encoders/encoders.h"
#include "brother.h"

View File

@@ -1,6 +1,7 @@
#include "lib/core/globals.h"
#include "lib/fluxmap.h"
#include "lib/decoders/fluxmapreader.h"
#include "lib/decoders/fluxpattern.h"
#include "protocol.h"
#include "lib/decoders/decoders.h"
#include "lib/sector.h"

View File

@@ -1,6 +1,7 @@
#include "lib/core/globals.h"
#include "lib/fluxmap.h"
#include "lib/decoders/fluxmapreader.h"
#include "lib/decoders/fluxpattern.h"
#include "protocol.h"
#include "lib/decoders/decoders.h"
#include "lib/sector.h"

View File

@@ -1,6 +1,7 @@
#include "lib/core/globals.h"
#include "lib/fluxmap.h"
#include "lib/decoders/fluxmapreader.h"
#include "lib/decoders/fluxpattern.h"
#include "protocol.h"
#include "lib/decoders/decoders.h"
#include "lib/sector.h"

View File

@@ -4,6 +4,7 @@
#include "lib/core/crc.h"
#include "lib/fluxmap.h"
#include "lib/decoders/fluxmapreader.h"
#include "lib/decoders/fluxpattern.h"
#include "lib/sector.h"
#include "arch/ibm/ibm.pb.h"
#include "lib/proto.h"

View File

@@ -1,6 +1,7 @@
#include "lib/core/globals.h"
#include "lib/fluxmap.h"
#include "lib/decoders/fluxmapreader.h"
#include "lib/decoders/fluxpattern.h"
#include "protocol.h"
#include "lib/decoders/decoders.h"
#include "lib/sector.h"

View File

@@ -1,6 +1,7 @@
#include "lib/core/globals.h"
#include "lib/fluxmap.h"
#include "lib/decoders/fluxmapreader.h"
#include "lib/decoders/fluxpattern.h"
#include "lib/decoders/decoders.h"
#include "lib/sector.h"
#include "micropolis.h"

View File

@@ -4,6 +4,7 @@
#include "lib/core/crc.h"
#include "lib/fluxmap.h"
#include "lib/decoders/fluxmapreader.h"
#include "lib/decoders/fluxpattern.h"
#include "lib/sector.h"
#include <string.h>

View File

@@ -14,6 +14,7 @@
#include "lib/core/globals.h"
#include "lib/fluxmap.h"
#include "lib/decoders/fluxmapreader.h"
#include "lib/decoders/fluxpattern.h"
#include "lib/decoders/decoders.h"
#include "lib/sector.h"
#include "northstar.h"

View File

@@ -3,6 +3,7 @@
#include "lib/core/crc.h"
#include "lib/fluxmap.h"
#include "lib/decoders/fluxmapreader.h"
#include "lib/decoders/fluxpattern.h"
#include "lib/sector.h"
#include "lib/core/bytes.h"
#include "rolandd20.h"

View File

@@ -1,6 +1,7 @@
#include "lib/core/globals.h"
#include "lib/fluxmap.h"
#include "lib/decoders/fluxmapreader.h"
#include "lib/decoders/fluxpattern.h"
#include "protocol.h"
#include "lib/decoders/decoders.h"
#include "lib/sector.h"

View File

@@ -5,16 +5,20 @@
#include "lib/core/crc.h"
#include "lib/fluxmap.h"
#include "lib/decoders/fluxmapreader.h"
#include "lib/decoders/fluxpattern.h"
#include "lib/sector.h"
#include <string.h>
constexpr uint64_t HEADER_BITS = 0xaaaaaaaa44895554LL;
constexpr uint64_t DATA_BITS = 0xaaaaaaaa44895545LL;
constexpr uint64_t DATA_BITS = 0xaaaaaaaa44895545LL;
static const FluxPattern HEADER_PATTERN(64, HEADER_BITS);
static const FluxPattern DATA_PATTERN(64, DATA_BITS);
const FluxMatchers ANY_RECORD_PATTERN{&HEADER_PATTERN, &DATA_PATTERN};
const FluxMatchers ANY_RECORD_PATTERN {
&HEADER_PATTERN,
&DATA_PATTERN
};
class TartuDecoder : public Decoder
{
@@ -25,7 +29,9 @@ public:
{
}
void beginTrack() override {}
void beginTrack() override
{
}
nanoseconds_t advanceToNextRecord() override
{
@@ -39,7 +45,7 @@ public:
auto bits = readRawBits(16 * 4);
auto bytes = decodeFmMfm(bits).slice(0, 4);
ByteReader br(bytes);
uint8_t track = br.read_8();
_sector->logicalTrack = track >> 1;
@@ -48,7 +54,7 @@ public:
_sector->logicalSector = br.read_8();
uint8_t wantChecksum = br.read_8();
uint8_t gotChecksum = ~sumBytes(bytes.slice(0, 3));
if (wantChecksum == gotChecksum)
_sector->status = Sector::DATA_MISSING;
@@ -59,15 +65,14 @@ public:
{
if (readRaw64() != DATA_BITS)
return;
const auto& bits = readRawBits(129 * 16);
const auto& bytes = decodeFmMfm(bits).slice(0, 129);
_sector->data = bytes.slice(0, 128);
uint8_t wantChecksum = bytes.reader().seek(128).read_8();
uint8_t gotChecksum = ~sumBytes(_sector->data);
_sector->status =
(wantChecksum == gotChecksum) ? Sector::OK : Sector::BAD_CHECKSUM;
_sector->status = (wantChecksum == gotChecksum) ? Sector::OK : Sector::BAD_CHECKSUM;
}
private:
@@ -78,3 +83,4 @@ std::unique_ptr<Decoder> createTartuDecoder(const DecoderProto& config)
{
return std::unique_ptr<Decoder>(new TartuDecoder(config));
}

View File

@@ -5,6 +5,7 @@
#include "lib/core/crc.h"
#include "lib/fluxmap.h"
#include "lib/decoders/fluxmapreader.h"
#include "lib/decoders/fluxpattern.h"
#include "lib/sector.h"
#include <string.h>
#include <fmt/format.h>

View File

@@ -1,6 +1,7 @@
#include "lib/core/globals.h"
#include "lib/fluxmap.h"
#include "lib/decoders/fluxmapreader.h"
#include "lib/decoders/fluxpattern.h"
#include "protocol.h"
#include "lib/decoders/decoders.h"
#include "lib/sector.h"

View File

@@ -1,6 +1,7 @@
#include "lib/core/globals.h"
#include "lib/fluxmap.h"
#include "lib/decoders/fluxmapreader.h"
#include "lib/decoders/fluxpattern.h"
#include "protocol.h"
#include "lib/decoders/decoders.h"
#include "lib/sector.h"

View File

@@ -29,6 +29,7 @@ cxxlibrary(
"./lib/decoders/decoders.cc",
"./lib/decoders/fluxdecoder.cc",
"./lib/decoders/fluxmapreader.cc",
"./lib/decoders/fluxpattern.cc",
"./lib/decoders/fmmfm.cc",
"./lib/encoders/encoders.cc",
"./lib/fl2.cc",
@@ -159,6 +160,7 @@ cxxlibrary(
"lib/decoders/decoders.h": "./lib/decoders/decoders.h",
"lib/decoders/fluxdecoder.h": "./lib/decoders/fluxdecoder.h",
"lib/decoders/fluxmapreader.h": "./lib/decoders/fluxmapreader.h",
"lib/decoders/fluxpattern.h": "./lib/decoders/fluxpattern.h",
"lib/decoders/rawbits.h": "./lib/decoders/rawbits.h",
"lib/encoders/encoders.h": "./lib/encoders/encoders.h",
"lib/scp.h": "./lib/scp.h",

View File

@@ -220,3 +220,17 @@ uint32_t unbcd(uint32_t bcd)
return dec;
}
int findLowestSetBit(uint64_t value)
{
if (!value)
return 0;
int bit = 1;
while (!(value & 1))
{
value >>= 1;
bit++;
}
return bit;
}

View File

@@ -21,6 +21,7 @@ extern std::string tohex(const std::string& s);
extern bool doesFileExist(const std::string& filename);
extern int countSetBits(uint32_t word);
extern uint32_t unbcd(uint32_t bcd);
extern int findLowestSetBit(uint64_t value);
template <class K, class V>
std::map<V, K> reverseMap(const std::map<K, V>& map)

View File

@@ -8,6 +8,7 @@
class Sector;
class Fluxmap;
class FluxMatcher;
class FluxmapReader;
class RawBits;
class DecoderProto;

View File

@@ -2,7 +2,7 @@
#include "lib/config.h"
#include "lib/fluxmap.h"
#include "lib/decoders/fluxmapreader.h"
#include "lib/flags.h"
#include "lib/decoders/fluxpattern.h"
#include "lib/proto.h"
#include "protocol.h"
#include <numeric>
@@ -81,110 +81,6 @@ unsigned FluxmapReader::readInterval(nanoseconds_t clock)
return ticks;
}
static int findLowestSetBit(uint64_t value)
{
if (!value)
return 0;
int bit = 1;
while (!(value & 1))
{
value >>= 1;
bit++;
}
return bit;
}
FluxPattern::FluxPattern(unsigned bits, uint64_t pattern): _bits(bits)
{
const uint64_t TOPBIT = 1ULL << 63;
assert(pattern != 0);
unsigned lowbit = findLowestSetBit(pattern) - 1;
pattern <<= 64 - bits;
_highzeroes = 0;
while (!(pattern & TOPBIT))
{
pattern <<= 1;
_highzeroes++;
}
_length = 0;
while (pattern != TOPBIT)
{
unsigned interval = 0;
do
{
pattern <<= 1;
interval++;
} while (!(pattern & TOPBIT));
_intervals.push_back(interval);
_length += interval;
}
if (lowbit)
{
_lowzero = true;
/* Note that length does *not* include this interval. */
_intervals.push_back(lowbit + 1);
}
}
bool FluxPattern::matches(const unsigned* end, FluxMatch& match) const
{
const double clockDecodeThreshold =
globalConfig()->decoder().bit_error_threshold();
const unsigned* start = end - _intervals.size();
unsigned candidatelength = std::accumulate(start, end - _lowzero, 0);
if (!candidatelength)
return false;
match.clock = (double)candidatelength / (double)_length;
unsigned exactIntervals = _intervals.size() - _lowzero;
for (unsigned i = 0; i < exactIntervals; i++)
{
double ii = match.clock * (double)_intervals[i];
double ci = (double)start[i];
double error = fabs((ii - ci) / match.clock);
if (error > clockDecodeThreshold)
return false;
}
if (_lowzero)
{
double ii = match.clock * (double)_intervals[exactIntervals];
double ci = (double)start[exactIntervals];
double error = (ii - ci) / match.clock;
if (error > clockDecodeThreshold)
return false;
}
match.matcher = this;
match.intervals = _intervals.size();
match.zeroes = _highzeroes;
return true;
}
FluxMatchers::FluxMatchers(
const std::initializer_list<const FluxMatcher*> matchers):
_matchers(matchers)
{
_intervals = 0;
for (const auto* matcher : matchers)
_intervals = std::max(_intervals, matcher->intervals());
}
bool FluxMatchers::matches(const unsigned* intervals, FluxMatch& match) const
{
for (const auto* matcher : _matchers)
{
if (matcher->matches(intervals, match))
return true;
}
return false;
}
void FluxmapReader::seek(nanoseconds_t ns)
{
unsigned ticks = ns / NS_PER_TICK;

View File

@@ -5,67 +5,8 @@
#include "lib/flags.h"
#include "protocol.h"
class FluxMatcher;
class DecoderProto;
struct FluxMatch
{
const FluxMatcher* matcher;
unsigned intervals;
double clock;
unsigned zeroes;
};
class FluxMatcher
{
public:
virtual ~FluxMatcher() {}
/* Returns the number of intervals matched */
virtual bool matches(const unsigned* intervals, FluxMatch& match) const = 0;
virtual unsigned intervals() const = 0;
};
class FluxPattern : public FluxMatcher
{
public:
FluxPattern(unsigned bits, uint64_t patterns);
bool matches(const unsigned* intervals, FluxMatch& match) const override;
unsigned intervals() const override
{
return _intervals.size();
}
private:
std::vector<unsigned> _intervals;
unsigned _length;
unsigned _bits;
unsigned _highzeroes;
bool _lowzero = false;
public:
friend void test_patternconstruction();
friend void test_patternmatching();
};
class FluxMatchers : public FluxMatcher
{
public:
FluxMatchers(const std::initializer_list<const FluxMatcher*> matchers);
bool matches(const unsigned* intervals, FluxMatch& match) const override;
unsigned intervals() const override
{
return _intervals;
}
private:
unsigned _intervals;
std::vector<const FluxMatcher*> _matchers;
};
class FluxMatcher;
class FluxmapReader
{

100
lib/decoders/fluxpattern.cc Normal file
View File

@@ -0,0 +1,100 @@
#include "lib/core/globals.h"
#include "lib/config.h"
#include "lib/fluxmap.h"
#include "lib/decoders/fluxpattern.h"
#include "lib/proto.h"
#include "protocol.h"
#include <numeric>
#include <math.h>
#include <strings.h>
FluxPattern::FluxPattern(unsigned bits, uint64_t pattern): _bits(bits)
{
const uint64_t TOPBIT = 1ULL << 63;
assert(pattern != 0);
unsigned lowbit = findLowestSetBit(pattern) - 1;
pattern <<= 64 - bits;
_highzeroes = 0;
while (!(pattern & TOPBIT))
{
pattern <<= 1;
_highzeroes++;
}
_length = 0;
while (pattern != TOPBIT)
{
unsigned interval = 0;
do
{
pattern <<= 1;
interval++;
} while (!(pattern & TOPBIT));
_intervals.push_back(interval);
_length += interval;
}
if (lowbit)
{
_lowzero = true;
/* Note that length does *not* include this interval. */
_intervals.push_back(lowbit + 1);
}
}
bool FluxPattern::matches(const unsigned* end, FluxMatch& match) const
{
const double clockDecodeThreshold =
globalConfig()->decoder().bit_error_threshold();
const unsigned* start = end - _intervals.size();
unsigned candidatelength = std::accumulate(start, end - _lowzero, 0);
if (!candidatelength)
return false;
match.clock = (double)candidatelength / (double)_length;
unsigned exactIntervals = _intervals.size() - _lowzero;
for (unsigned i = 0; i < exactIntervals; i++)
{
double ii = match.clock * (double)_intervals[i];
double ci = (double)start[i];
double error = fabs((ii - ci) / match.clock);
if (error > clockDecodeThreshold)
return false;
}
if (_lowzero)
{
double ii = match.clock * (double)_intervals[exactIntervals];
double ci = (double)start[exactIntervals];
double error = (ii - ci) / match.clock;
if (error > clockDecodeThreshold)
return false;
}
match.matcher = this;
match.intervals = _intervals.size();
match.zeroes = _highzeroes;
return true;
}
FluxMatchers::FluxMatchers(
const std::initializer_list<const FluxMatcher*> matchers):
_matchers(matchers)
{
_intervals = 0;
for (const auto* matcher : matchers)
_intervals = std::max(_intervals, matcher->intervals());
}
bool FluxMatchers::matches(const unsigned* intervals, FluxMatch& match) const
{
for (const auto* matcher : _matchers)
{
if (matcher->matches(intervals, match))
return true;
}
return false;
}

View File

@@ -0,0 +1,68 @@
#pragma once
#include "lib/core/utils.h"
#include "lib/fluxmap.h"
#include "lib/flags.h"
#include "protocol.h"
class FluxMatcher;
class DecoderProto;
struct FluxMatch
{
const FluxMatcher* matcher;
unsigned intervals;
double clock;
unsigned zeroes;
};
class FluxMatcher
{
public:
virtual ~FluxMatcher() {}
/* Returns the number of intervals matched */
virtual bool matches(const unsigned* intervals, FluxMatch& match) const = 0;
virtual unsigned intervals() const = 0;
};
class FluxPattern : public FluxMatcher
{
public:
FluxPattern(unsigned bits, uint64_t patterns);
bool matches(const unsigned* intervals, FluxMatch& match) const override;
unsigned intervals() const override
{
return _intervals.size();
}
private:
std::vector<unsigned> _intervals;
unsigned _length;
unsigned _bits;
unsigned _highzeroes;
bool _lowzero = false;
public:
friend void test_patternconstruction();
friend void test_patternmatching();
};
class FluxMatchers : public FluxMatcher
{
public:
FluxMatchers(const std::initializer_list<const FluxMatcher*> matchers);
bool matches(const unsigned* intervals, FluxMatch& match) const override;
unsigned intervals() const override
{
return _intervals;
}
private:
unsigned _intervals;
std::vector<const FluxMatcher*> _matchers;
};

View File

@@ -1,6 +1,6 @@
#include "lib/core/globals.h"
#include "lib/fluxmap.h"
#include "lib/decoders/fluxmapreader.h"
#include "lib/decoders/fluxpattern.h"
#include <sstream>
typedef std::vector<unsigned> ivector;