diff --git a/lib/brother/brother.h b/lib/brother/brother.h index fcc9defd..514e9e6b 100644 --- a/lib/brother/brother.h +++ b/lib/brother/brother.h @@ -14,4 +14,7 @@ extern RecordVector decodeBitsToRecordsBrother(const std::vector& bitmap); extern std::vector> parseRecordsToSectorsBrother(const RecordVector& records); +extern void writeBrotherSectorHeader(std::vector& bits, unsigned& cursor, + int track, int sector); + #endif diff --git a/lib/brother/encoder.cc b/lib/brother/encoder.cc new file mode 100644 index 00000000..e5403c29 --- /dev/null +++ b/lib/brother/encoder.cc @@ -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& bits, unsigned& cursor, uint32_t data, int width) +{ + cursor += width; + for (int i=0; i>= 1; + } +} + +void writeBrotherSectorHeader(std::vector& 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); +} + diff --git a/lib/encoder.cc b/lib/encoder.cc new file mode 100644 index 00000000..0245f3c9 --- /dev/null +++ b/lib/encoder.cc @@ -0,0 +1,26 @@ +#include "globals.h" +#include "fluxmap.h" +#include "protocol.h" + +Fluxmap& Fluxmap::appendBits(const std::vector& bits, nanoseconds_t clock) +{ + nanoseconds_t now = duration(); + for (unsigned i=0; i 255) + { + appendIntervals({ 255 }); + delta -= 255; + } + appendIntervals({ (uint8_t)delta }); + } + } + + return *this; +} + + diff --git a/lib/fluxmap.cc b/lib/fluxmap.cc index 90ff8a6c..f04fe022 100644 --- a/lib/fluxmap.cc +++ b/lib/fluxmap.cc @@ -2,7 +2,7 @@ #include "fluxmap.h" #include "protocol.h" -Fluxmap& Fluxmap::appendIntervals(std::vector& intervals) +Fluxmap& Fluxmap::appendIntervals(const std::vector& intervals) { return appendIntervals(&intervals[0], intervals.size()); } diff --git a/lib/fluxmap.h b/lib/fluxmap.h index c36f5a3a..f795cfab 100644 --- a/lib/fluxmap.h +++ b/lib/fluxmap.h @@ -19,12 +19,14 @@ public: return NULL; } - Fluxmap& appendIntervals(std::vector& intervals); + Fluxmap& appendIntervals(const std::vector& intervals); Fluxmap& appendIntervals(const uint8_t* ptr, size_t len); nanoseconds_t guessClock() const; std::vector decodeToBits(nanoseconds_t clock_period) const; + Fluxmap& appendBits(const std::vector& bits, nanoseconds_t clock); + private: nanoseconds_t _duration = 0; int _ticks = 0; diff --git a/lib/writer.cc b/lib/writer.cc new file mode 100644 index 00000000..02cca2af --- /dev/null +++ b/lib/writer.cc @@ -0,0 +1,34 @@ +#include "globals.h" +#include "flags.h" +#include "fluxmap.h" +#include "writer.h" +#include + +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& bitmap, + unsigned& cursor, unsigned terminateAt, + const std::vector& pattern) +{ + while (cursor < terminateAt) + { + for (bool b : pattern) + { + if (cursor < bitmap.size()) + bitmap[cursor++] = b; + } + } +} + diff --git a/lib/writer.h b/lib/writer.h new file mode 100644 index 00000000..a0be51b6 --- /dev/null +++ b/lib/writer.h @@ -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& bitmap, + unsigned& cursor, unsigned terminateAt, + const std::vector& pattern); + +#endif diff --git a/meson.build b/meson.build index 3fa9af0d..e25f2633 100644 --- a/meson.build +++ b/meson.build @@ -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]) diff --git a/src/fe-writebrother.cc b/src/fe-writebrother.cc index ba1d6154..4907b9e9 100644 --- a/src/fe-writebrother.cc +++ b/src/fe-writebrother.cc @@ -7,8 +7,10 @@ #include "decoders.h" #include "brother.h" #include "image.h" +#include "writer.h" #include #include +#include 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 bits(bitsPerRevolution); + unsigned cursor = 0; + + std::cerr << "logical track " << track << std::endl; for (int sectorCount=0; sectorCount bits.size()) + Error() << "track data overrun"; } + Fluxmap fluxmap; + fluxmap.appendBits(bits, clockRateUs*1e3); } std::cerr << "Not implemented yet." << std::endl;