mirror of
https://github.com/davidgiven/fluxengine.git
synced 2025-10-31 11:17:01 -07:00
Begin generating the Brother bitstream and convert it to a fluxmap.
This commit is contained in:
@@ -14,4 +14,7 @@ extern RecordVector decodeBitsToRecordsBrother(const std::vector<bool>& bitmap);
|
||||
|
||||
extern std::vector<std::unique_ptr<Sector>> parseRecordsToSectorsBrother(const RecordVector& records);
|
||||
|
||||
extern void writeBrotherSectorHeader(std::vector<bool>& bits, unsigned& cursor,
|
||||
int track, int sector);
|
||||
|
||||
#endif
|
||||
|
||||
36
lib/brother/encoder.cc
Normal file
36
lib/brother/encoder.cc
Normal file
@@ -0,0 +1,36 @@
|
||||
#include "globals.h"
|
||||
#include "record.h"
|
||||
#include "brother.h"
|
||||
|
||||
static int encode_header_gcr(uint16_t word)
|
||||
{
|
||||
switch (word)
|
||||
{
|
||||
#define GCR_ENTRY(gcr, data) \
|
||||
case data: return gcr;
|
||||
#include "header_gcr.h"
|
||||
#undef GCR_ENTRY
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
|
||||
static void write_bits(std::vector<bool>& bits, unsigned& cursor, uint32_t data, int width)
|
||||
{
|
||||
cursor += width;
|
||||
for (int i=0; i<width; i++)
|
||||
{
|
||||
unsigned pos = cursor - i - 1;
|
||||
if (pos < bits.size())
|
||||
bits[pos] = data & 1;
|
||||
data >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
void writeBrotherSectorHeader(std::vector<bool>& bits, unsigned& cursor,
|
||||
int track, int sector)
|
||||
{
|
||||
write_bits(bits, cursor, BROTHER_SECTOR_RECORD, 32);
|
||||
write_bits(bits, cursor, encode_header_gcr(track), 16);
|
||||
write_bits(bits, cursor, encode_header_gcr(sector), 16);
|
||||
}
|
||||
|
||||
26
lib/encoder.cc
Normal file
26
lib/encoder.cc
Normal file
@@ -0,0 +1,26 @@
|
||||
#include "globals.h"
|
||||
#include "fluxmap.h"
|
||||
#include "protocol.h"
|
||||
|
||||
Fluxmap& Fluxmap::appendBits(const std::vector<bool>& bits, nanoseconds_t clock)
|
||||
{
|
||||
nanoseconds_t now = duration();
|
||||
for (unsigned i=0; i<bits.size(); i++)
|
||||
{
|
||||
now += clock;
|
||||
if (bits[i])
|
||||
{
|
||||
unsigned delta = (now - duration()) / NS_PER_TICK;
|
||||
while (delta > 255)
|
||||
{
|
||||
appendIntervals({ 255 });
|
||||
delta -= 255;
|
||||
}
|
||||
appendIntervals({ (uint8_t)delta });
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#include "fluxmap.h"
|
||||
#include "protocol.h"
|
||||
|
||||
Fluxmap& Fluxmap::appendIntervals(std::vector<uint8_t>& intervals)
|
||||
Fluxmap& Fluxmap::appendIntervals(const std::vector<uint8_t>& intervals)
|
||||
{
|
||||
return appendIntervals(&intervals[0], intervals.size());
|
||||
}
|
||||
|
||||
@@ -19,12 +19,14 @@ public:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Fluxmap& appendIntervals(std::vector<uint8_t>& intervals);
|
||||
Fluxmap& appendIntervals(const std::vector<uint8_t>& intervals);
|
||||
Fluxmap& appendIntervals(const uint8_t* ptr, size_t len);
|
||||
|
||||
nanoseconds_t guessClock() const;
|
||||
std::vector<bool> decodeToBits(nanoseconds_t clock_period) const;
|
||||
|
||||
Fluxmap& appendBits(const std::vector<bool>& bits, nanoseconds_t clock);
|
||||
|
||||
private:
|
||||
nanoseconds_t _duration = 0;
|
||||
int _ticks = 0;
|
||||
|
||||
34
lib/writer.cc
Normal file
34
lib/writer.cc
Normal file
@@ -0,0 +1,34 @@
|
||||
#include "globals.h"
|
||||
#include "flags.h"
|
||||
#include "fluxmap.h"
|
||||
#include "writer.h"
|
||||
#include <regex>
|
||||
|
||||
static const std::regex DEST_REGEX("([^:]*)"
|
||||
"(?::t=([0-9]+)(?:-([0-9]+))?)?"
|
||||
"(?::s=([0-9]+)(?:-([0-9]+))?)?");
|
||||
|
||||
static StringFlag destination(
|
||||
{ "--dest", "-d" },
|
||||
"destination for data",
|
||||
"");
|
||||
|
||||
void writeTrack(int track, int side, const Fluxmap& fluxmap)
|
||||
{
|
||||
Error() << "not implemented yet";
|
||||
}
|
||||
|
||||
void fillBitmapTo(std::vector<bool>& bitmap,
|
||||
unsigned& cursor, unsigned terminateAt,
|
||||
const std::vector<bool>& pattern)
|
||||
{
|
||||
while (cursor < terminateAt)
|
||||
{
|
||||
for (bool b : pattern)
|
||||
{
|
||||
if (cursor < bitmap.size())
|
||||
bitmap[cursor++] = b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
12
lib/writer.h
Normal file
12
lib/writer.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#ifndef WRITER_H
|
||||
#define WRITER_H
|
||||
|
||||
class Fluxmap;
|
||||
|
||||
extern void writeTrack(int track, int side, const Fluxmap& fluxmap);
|
||||
|
||||
extern void fillBitmapTo(std::vector<bool>& bitmap,
|
||||
unsigned& cursor, unsigned terminateAt,
|
||||
const std::vector<bool>& pattern);
|
||||
|
||||
#endif
|
||||
@@ -74,6 +74,7 @@ decoderinc = include_directories('lib/decoders')
|
||||
|
||||
encoderlib = shared_library('encoderlib',
|
||||
[
|
||||
'lib/encoder.cc',
|
||||
],
|
||||
include_directories: [feinc, fmtinc],
|
||||
link_with: [felib, fmtlib]
|
||||
@@ -101,6 +102,6 @@ executable('fe-seek', ['src/fe-seek.cc'], include_dire
|
||||
executable('fe-testbulktransport', ['src/fe-testbulktransport.cc'], include_directories: [feinc], link_with: [felib])
|
||||
executable('fe-readibm', ['src/fe-readibm.cc'], include_directories: [feinc, fmtinc, decoderinc], link_with: [felib, readerlib, decoderlib, fmtlib])
|
||||
executable('fe-readbrother', ['src/fe-readbrother.cc'], include_directories: [feinc, fmtinc, decoderinc, brotherinc], link_with: [felib, readerlib, decoderlib, brotherdecoderlib, fmtlib])
|
||||
executable('fe-writebrother', ['src/fe-writebrother.cc'], include_directories: [feinc, fmtinc, decoderinc, brotherinc], link_with: [felib, writerlib, decoderlib, brotherencoderlib, fmtlib])
|
||||
executable('fe-writebrother', ['src/fe-writebrother.cc'], include_directories: [feinc, fmtinc, brotherinc], link_with: [felib, writerlib, encoderlib, brotherencoderlib, fmtlib])
|
||||
executable('fe-inspect', ['src/fe-inspect.cc'], include_directories: [feinc, fmtinc, decoderinc], link_with: [felib, readerlib, decoderlib, fmtlib])
|
||||
|
||||
|
||||
@@ -7,8 +7,10 @@
|
||||
#include "decoders.h"
|
||||
#include "brother.h"
|
||||
#include "image.h"
|
||||
#include "writer.h"
|
||||
#include <fmt/format.h>
|
||||
#include <fstream>
|
||||
#include <ctype.h>
|
||||
|
||||
static StringFlag inputFilename(
|
||||
{ "--input", "-i" },
|
||||
@@ -27,14 +29,27 @@ static IntFlag postIndexGapMs(
|
||||
|
||||
static DoubleFlag sectorSpacingMs(
|
||||
{ "--sector-spacing" },
|
||||
"Time between successive sector heads (milliseconds).",
|
||||
"Time between successive sector headers (milliseconds).",
|
||||
16.684);
|
||||
|
||||
static DoubleFlag postHeaderSpacingMs(
|
||||
{ "--post-header-spacing" },
|
||||
"Time between a sector's header and data records (milliseconds).",
|
||||
0.694);
|
||||
|
||||
|
||||
static StringFlag sectorSkew(
|
||||
{ "--sector-skew" },
|
||||
"Order in which to write sectors.",
|
||||
"05a3816b4927");
|
||||
|
||||
static int charToInt(char c)
|
||||
{
|
||||
if (isdigit(c))
|
||||
return c - '0';
|
||||
return 10 + tolower(c) - 'a';
|
||||
}
|
||||
|
||||
int main(int argc, const char* argv[])
|
||||
{
|
||||
Flag::parseFlags(argc, argv);
|
||||
@@ -43,28 +58,36 @@ int main(int argc, const char* argv[])
|
||||
Geometry geometry = {78, 1, 12, 256};
|
||||
readSectorsFromFile(allSectors, geometry, inputFilename);
|
||||
|
||||
double lastSectorAtMs = postIndexGapMs + geometry.sectors*sectorSpacingMs;
|
||||
if (lastSectorAtMs > 200.0)
|
||||
Error() << "with that spacing, some sectors won't fit in a track "
|
||||
<< fmt::format("({:.3f}ms out of 200.0ms)", lastSectorAtMs);
|
||||
|
||||
int bitsPerRevolution = 200000.0 / clockRateUs;
|
||||
std::cerr << bitsPerRevolution << " bits per 200ms revolution" << std::endl
|
||||
<< fmt::format("post-index gap: {:.3f}ms\n", postIndexGapMs)
|
||||
<< fmt::format("pre-index gap: {:.3f}ms\n", 200.0 - lastSectorAtMs);
|
||||
<< fmt::format("post-index gap: {:.3f}ms\n", (double)postIndexGapMs);
|
||||
|
||||
const std::string& skew = sectorSkew;
|
||||
for (int track=0; track<geometry.tracks; track++)
|
||||
{
|
||||
std::vector<bool> bits(bitsPerRevolution);
|
||||
unsigned cursor = 0;
|
||||
|
||||
std::cerr << "logical track " << track << std::endl;
|
||||
|
||||
for (int sectorCount=0; sectorCount<geometry.sectors; sectorCount++)
|
||||
{
|
||||
int sectorId = skew.at(sectorCount) - '0';
|
||||
double cursorMs = postIndexGapMs + sectorCount*sectorSpacingMs;
|
||||
std::cerr << "logical sector " << sectorId << " at pos " << cursorMs << std::endl;
|
||||
int sectorId = charToInt(skew.at(sectorCount));
|
||||
double headerMs = postIndexGapMs + sectorCount*sectorSpacingMs;
|
||||
unsigned headerCursor = headerMs*1e3 / clockRateUs;
|
||||
double dataMs = headerMs + postHeaderSpacingMs;
|
||||
unsigned dataCursor = dataMs*1e3 / clockRateUs;
|
||||
|
||||
fillBitmapTo(bits, cursor, headerCursor, { true, false });
|
||||
writeBrotherSectorHeader(bits, cursor, track, sectorId);
|
||||
fillBitmapTo(bits, cursor, dataCursor, { true, false });
|
||||
|
||||
if (cursor > bits.size())
|
||||
Error() << "track data overrun";
|
||||
}
|
||||
|
||||
Fluxmap fluxmap;
|
||||
fluxmap.appendBits(bits, clockRateUs*1e3);
|
||||
}
|
||||
|
||||
std::cerr << "Not implemented yet." << std::endl;
|
||||
|
||||
Reference in New Issue
Block a user