mirror of
https://github.com/davidgiven/fluxengine.git
synced 2025-10-31 11:17:01 -07:00
Refactor to use FluxmapReader.
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
#include "decoders.h"
|
||||
#include "record.h"
|
||||
#include "protocol.h"
|
||||
#include "rawbits.h"
|
||||
#include "fmt/format.h"
|
||||
|
||||
static DoubleFlag clockDecodeThreshold(
|
||||
@@ -44,9 +45,13 @@ nanoseconds_t Fluxmap::guessClock() const
|
||||
|
||||
uint32_t buckets[256] = {};
|
||||
size_t cursor = 0;
|
||||
FluxmapReader fr(*this);
|
||||
while (cursor < bytes())
|
||||
{
|
||||
uint32_t interval = getAndIncrement(cursor);
|
||||
unsigned interval;
|
||||
int opcode = fr.readPulse(interval);
|
||||
if (opcode != 0x80)
|
||||
break;
|
||||
if (interval > 0xff)
|
||||
continue;
|
||||
buckets[interval]++;
|
||||
@@ -152,35 +157,39 @@ nanoseconds_t Fluxmap::guessClock() const
|
||||
}
|
||||
|
||||
/* Decodes a fluxmap into a nice aligned array of bits. */
|
||||
std::vector<bool> Fluxmap::decodeToBits(nanoseconds_t clockPeriod) const
|
||||
const RawBits Fluxmap::decodeToBits(nanoseconds_t clockPeriod) const
|
||||
{
|
||||
int pulses = duration() / clockPeriod;
|
||||
nanoseconds_t lowerThreshold = clockPeriod * clockDecodeThreshold;
|
||||
|
||||
std::vector<bool> bitmap(pulses);
|
||||
auto bitmap = std::make_unique<std::vector<bool>>(pulses);
|
||||
auto indices = std::make_unique<std::vector<size_t>>();
|
||||
|
||||
unsigned count = 0;
|
||||
size_t cursor = 0;
|
||||
nanoseconds_t timestamp = 0;
|
||||
FluxmapReader fr(*this);
|
||||
for (;;)
|
||||
{
|
||||
while (timestamp < lowerThreshold)
|
||||
{
|
||||
if (cursor >= bytes())
|
||||
unsigned interval;
|
||||
int opcode = fr.readPulse(interval);
|
||||
if (opcode == -1)
|
||||
goto abort;
|
||||
uint8_t interval = getAndIncrement(cursor);
|
||||
timestamp += interval * NS_PER_TICK;
|
||||
}
|
||||
|
||||
int clocks = (timestamp + clockPeriod/2) / clockPeriod;
|
||||
count += clocks;
|
||||
if (count >= bitmap.size())
|
||||
if (count >= bitmap->size())
|
||||
goto abort;
|
||||
bitmap[count] = true;
|
||||
bitmap->at(count) = true;
|
||||
timestamp = 0;
|
||||
}
|
||||
abort:
|
||||
|
||||
return bitmap;
|
||||
RawBits rawbits(std::move(bitmap), std::move(indices));
|
||||
return rawbits;
|
||||
}
|
||||
|
||||
nanoseconds_t AbstractDecoder::guessClock(Fluxmap& fluxmap) const
|
||||
@@ -188,7 +197,7 @@ nanoseconds_t AbstractDecoder::guessClock(Fluxmap& fluxmap) const
|
||||
return fluxmap.guessClock();
|
||||
}
|
||||
|
||||
RawRecordVector AbstractSoftSectorDecoder::extractRecords(std::vector<bool> bits) const
|
||||
RawRecordVector AbstractSoftSectorDecoder::extractRecords(const RawBits& rawbits) const
|
||||
{
|
||||
RawRecordVector records;
|
||||
uint64_t fifo = 0;
|
||||
@@ -204,15 +213,15 @@ RawRecordVector AbstractSoftSectorDecoder::extractRecords(std::vector<bool> bits
|
||||
std::unique_ptr<RawRecord>(
|
||||
new RawRecord(
|
||||
matchStart,
|
||||
bits.begin() + matchStart,
|
||||
bits.begin() + end)
|
||||
rawbits.begin() + matchStart,
|
||||
rawbits.begin() + end)
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
while (cursor < bits.size())
|
||||
while (cursor < rawbits.size())
|
||||
{
|
||||
fifo = (fifo << 1) | bits[cursor++];
|
||||
fifo = (fifo << 1) | rawbits[cursor++];
|
||||
|
||||
int match = recordMatcher(fifo);
|
||||
if (match > 0)
|
||||
@@ -226,3 +235,29 @@ RawRecordVector AbstractSoftSectorDecoder::extractRecords(std::vector<bool> bits
|
||||
return records;
|
||||
}
|
||||
|
||||
RawRecordVector AbstractHardSectorDecoder::extractRecords(const RawBits& rawbits) const
|
||||
{
|
||||
RawRecordVector records;
|
||||
int matchStart = 0;
|
||||
|
||||
auto pushRecord = [&](size_t end)
|
||||
{
|
||||
records.push_back(
|
||||
std::unique_ptr<RawRecord>(
|
||||
new RawRecord(
|
||||
matchStart,
|
||||
rawbits.begin() + matchStart,
|
||||
rawbits.begin() + end)
|
||||
)
|
||||
);
|
||||
matchStart = end;
|
||||
};
|
||||
|
||||
for (size_t index : rawbits.indices())
|
||||
pushRecord(index);
|
||||
pushRecord(rawbits.size());
|
||||
|
||||
return records;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
class Sector;
|
||||
class Fluxmap;
|
||||
class RawRecord;
|
||||
class RawBits;
|
||||
|
||||
typedef std::vector<std::unique_ptr<RawRecord>> RawRecordVector;
|
||||
typedef std::vector<std::unique_ptr<Sector>> SectorVector;
|
||||
|
||||
@@ -17,7 +19,7 @@ public:
|
||||
virtual ~AbstractDecoder() {}
|
||||
|
||||
virtual nanoseconds_t guessClock(Fluxmap& fluxmap) const;
|
||||
virtual RawRecordVector extractRecords(std::vector<bool> bits) const = 0;
|
||||
virtual RawRecordVector extractRecords(const RawBits& rawbits) const = 0;
|
||||
virtual SectorVector decodeToSectors(const RawRecordVector& rawrecords,
|
||||
unsigned physicalTrack) = 0;
|
||||
};
|
||||
@@ -27,9 +29,17 @@ class AbstractSoftSectorDecoder : public AbstractDecoder
|
||||
public:
|
||||
virtual ~AbstractSoftSectorDecoder() {}
|
||||
|
||||
RawRecordVector extractRecords(std::vector<bool> bits) const;
|
||||
RawRecordVector extractRecords(const RawBits& rawbits) const;
|
||||
|
||||
virtual int recordMatcher(uint64_t fifo) const = 0;
|
||||
};
|
||||
|
||||
class AbstractHardSectorDecoder : public AbstractDecoder
|
||||
{
|
||||
public:
|
||||
virtual ~AbstractHardSectorDecoder() {}
|
||||
|
||||
RawRecordVector extractRecords(const RawBits& bits) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
35
lib/decoders/rawbits.h
Normal file
35
lib/decoders/rawbits.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#ifndef RAWBITS_H
|
||||
#define RAWBITS_H
|
||||
|
||||
class RawBits
|
||||
{
|
||||
public:
|
||||
RawBits(std::unique_ptr<std::vector<bool>> bits,
|
||||
std::unique_ptr<std::vector<size_t>> indices):
|
||||
_bits(std::move(bits)),
|
||||
_indices(std::move(indices))
|
||||
{}
|
||||
|
||||
typedef std::vector<bool>::const_iterator const_iterator;
|
||||
|
||||
const_iterator begin() const
|
||||
{ return _bits->begin(); }
|
||||
|
||||
const_iterator end() const
|
||||
{ return _bits->end(); }
|
||||
|
||||
size_t size() const
|
||||
{ return _bits->size(); }
|
||||
|
||||
const bool operator[] (size_t pos) const
|
||||
{ return _bits->at(pos); }
|
||||
|
||||
const std::vector<size_t> indices() const
|
||||
{ return *_indices; }
|
||||
|
||||
private:
|
||||
std::unique_ptr<std::vector<bool>> _bits;
|
||||
std::unique_ptr<std::vector<size_t>> _indices;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -2,23 +2,6 @@
|
||||
#include "fluxmap.h"
|
||||
#include "protocol.h"
|
||||
|
||||
uint32_t Fluxmap::getAndIncrement(size_t& index) const
|
||||
{
|
||||
uint32_t ticks = 0;
|
||||
|
||||
while (index < _bytes.size())
|
||||
{
|
||||
uint8_t b = _bytes[index++];
|
||||
if (b < 0x80)
|
||||
ticks += b;
|
||||
if (b == 0x80)
|
||||
break;
|
||||
/* everything above 0x80 is ignored for now */
|
||||
}
|
||||
|
||||
return ticks;
|
||||
}
|
||||
|
||||
Fluxmap& Fluxmap::appendBytes(const Bytes& bytes)
|
||||
{
|
||||
return appendBytes(&bytes[0], bytes.size());
|
||||
@@ -89,3 +72,33 @@ void Fluxmap::precompensate(int threshold_ticks, int amount_ticks)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int FluxmapReader::read(unsigned& ticks)
|
||||
{
|
||||
ticks = 0;
|
||||
|
||||
while (_cursor < _size)
|
||||
{
|
||||
uint8_t b = _bytes[_cursor++];
|
||||
if (b < 0x80)
|
||||
ticks += b;
|
||||
else
|
||||
return b;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int FluxmapReader::readPulse(unsigned& ticks)
|
||||
{
|
||||
ticks = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
unsigned thisTicks;
|
||||
int opcode = read(thisTicks);
|
||||
ticks += thisTicks;
|
||||
if ((opcode == -1) || (opcode == 0x80))
|
||||
return opcode;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
|
||||
#include "bytes.h"
|
||||
|
||||
class RawBits;
|
||||
|
||||
class Fluxmap
|
||||
{
|
||||
public:
|
||||
uint32_t getAndIncrement(size_t& index) const;
|
||||
|
||||
nanoseconds_t duration() const { return _duration; }
|
||||
size_t bytes() const { return _bytes.size(); }
|
||||
const Bytes& rawBytes() const { return _bytes; }
|
||||
@@ -31,7 +31,7 @@ public:
|
||||
}
|
||||
|
||||
nanoseconds_t guessClock() const;
|
||||
std::vector<bool> decodeToBits(nanoseconds_t clock_period) const;
|
||||
const RawBits decodeToBits(nanoseconds_t clock_period) const;
|
||||
|
||||
Fluxmap& appendBits(const std::vector<bool>& bits, nanoseconds_t clock);
|
||||
|
||||
@@ -43,4 +43,30 @@ private:
|
||||
Bytes _bytes;
|
||||
};
|
||||
|
||||
class FluxmapReader
|
||||
{
|
||||
public:
|
||||
FluxmapReader(const Fluxmap& fluxmap):
|
||||
_fluxmap(fluxmap),
|
||||
_bytes(fluxmap.ptr()),
|
||||
_size(fluxmap.bytes())
|
||||
{
|
||||
rewind();
|
||||
}
|
||||
|
||||
FluxmapReader(const Fluxmap&& fluxmap) = delete;
|
||||
|
||||
void rewind()
|
||||
{ _cursor = 0; }
|
||||
|
||||
int read(unsigned& ticks);
|
||||
int readPulse(unsigned& ticks);
|
||||
|
||||
private:
|
||||
const Fluxmap& _fluxmap;
|
||||
const uint8_t* _bytes;
|
||||
const size_t _size;
|
||||
size_t _cursor;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "record.h"
|
||||
#include "image.h"
|
||||
#include "bytes.h"
|
||||
#include "rawbits.h"
|
||||
#include "fmt/format.h"
|
||||
|
||||
static DataSpecFlag source(
|
||||
@@ -154,7 +155,7 @@ void readDiskCommand(AbstractDecoder& decoder, const std::string& outputFilename
|
||||
}
|
||||
std::cout << fmt::format(" {:.2f} us clock; ", (double)clockPeriod/1000.0) << std::flush;
|
||||
|
||||
auto bitmap = fluxmap->decodeToBits(clockPeriod);
|
||||
const auto& bitmap = fluxmap->decodeToBits(clockPeriod);
|
||||
std::cout << fmt::format("{} bytes encoded; ", bitmap.size()/8) << std::flush;
|
||||
|
||||
auto rawrecords = decoder.extractRecords(bitmap);
|
||||
|
||||
@@ -27,22 +27,7 @@ SectorVector ZilogMczDecoder::decodeToSectors(
|
||||
auto reversed = reverseBits(sliceddata);
|
||||
const auto rawbytes = decodeFmMfm(reversed);
|
||||
|
||||
hexdump(std::cout, rawbytes);
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
return sectors;
|
||||
}
|
||||
|
||||
int ZilogMczDecoder::recordMatcher(uint64_t fifo) const
|
||||
{
|
||||
uint32_t masked = fifo & 0xffffffff;
|
||||
if (masked == ZILOGMCZ_RECORD_SEPARATOR)
|
||||
return 31;
|
||||
return 0;
|
||||
}
|
||||
|
||||
RawRecordVector ZilogMczDecoder::extractRecords(std::vector<bool> bits) const
|
||||
{
|
||||
return AbstractSoftSectorDecoder::extractRecords(reverseBits(bits));
|
||||
}
|
||||
|
||||
@@ -1,19 +1,15 @@
|
||||
#ifndef ZILOGMCZ_H
|
||||
#define ZILOGMCZ_H
|
||||
|
||||
#define ZILOGMCZ_RECORD_SEPARATOR 0xffff5d75
|
||||
|
||||
class Sector;
|
||||
class Fluxmap;
|
||||
|
||||
class ZilogMczDecoder : public AbstractSoftSectorDecoder
|
||||
class ZilogMczDecoder : public AbstractHardSectorDecoder
|
||||
{
|
||||
public:
|
||||
virtual ~ZilogMczDecoder() {}
|
||||
|
||||
SectorVector decodeToSectors(const RawRecordVector& rawRecords, unsigned physicalTrack);
|
||||
int recordMatcher(uint64_t fifo) const;
|
||||
RawRecordVector extractRecords(std::vector<bool> bits) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "decoders.h"
|
||||
#include "image.h"
|
||||
#include "protocol.h"
|
||||
#include "rawbits.h"
|
||||
#include <fmt/format.h>
|
||||
|
||||
static DoubleFlag clockScaleFlag(
|
||||
@@ -51,7 +52,7 @@ int main(int argc, const char* argv[])
|
||||
clockPeriod *= clockScaleFlag;
|
||||
std::cout << fmt::format("{:.2f} us bit clock; ", (double)clockPeriod/1000.0) << std::flush;
|
||||
|
||||
auto bitmap = fluxmap->decodeToBits(clockPeriod);
|
||||
const auto& bitmap = fluxmap->decodeToBits(clockPeriod);
|
||||
std::cout << fmt::format("{} bytes encoded.", bitmap.size()/8) << std::endl;
|
||||
|
||||
if (dumpFluxFlag)
|
||||
@@ -69,9 +70,14 @@ int main(int argc, const char* argv[])
|
||||
size_t cursor = 0;
|
||||
nanoseconds_t seekto = seekFlag*1000000.0;
|
||||
int ticks = 0;
|
||||
while (cursor < fluxmap->bytes())
|
||||
FluxmapReader fr(*fluxmap);
|
||||
for (;;)
|
||||
{
|
||||
ticks += fluxmap->getAndIncrement(cursor);
|
||||
unsigned interval;
|
||||
int opcode = fr.readPulse(interval);
|
||||
if (opcode == -1)
|
||||
break;
|
||||
ticks += interval;
|
||||
|
||||
now = ticks * NS_PER_TICK;
|
||||
if (now >= seekto)
|
||||
@@ -80,9 +86,14 @@ int main(int argc, const char* argv[])
|
||||
|
||||
std::cout << fmt::format("{: 10.3f}:-", ticks*US_PER_TICK);
|
||||
nanoseconds_t lasttransition = 0;
|
||||
while (cursor < fluxmap->bytes())
|
||||
fr.rewind();
|
||||
for (;;)
|
||||
{
|
||||
ticks += fluxmap->getAndIncrement(cursor);
|
||||
unsigned interval;
|
||||
int opcode = fr.readPulse(interval);
|
||||
if (opcode == -1)
|
||||
break;
|
||||
ticks += interval;
|
||||
|
||||
nanoseconds_t transition = ticks*NS_PER_TICK;
|
||||
nanoseconds_t next;
|
||||
|
||||
Reference in New Issue
Block a user