Add support for DMK directory streams.

This commit is contained in:
David Given
2023-11-02 01:17:44 +01:00
parent 5dc60db7b6
commit 29f5feb34d
10 changed files with 65 additions and 41 deletions

View File

@@ -41,7 +41,9 @@ cxxlibrary(
"./lib/fluxsink/scpfluxsink.cc",
"./lib/fluxsink/vcdfluxsink.cc",
"./lib/fluxsource/a2rfluxsource.cc",
"./lib/fluxsource/catweasel.cc",
"./lib/fluxsource/cwffluxsource.cc",
"./lib/fluxsource/dmkfluxsource.cc",
"./lib/fluxsource/erasefluxsource.cc",
"./lib/fluxsource/fl2fluxsource.cc",
"./lib/fluxsource/fluxsource.cc",
@@ -185,6 +187,7 @@ cxxlibrary(
"lib/flux.h": "./lib/flux.h",
"lib/fluxmap.h": "./lib/fluxmap.h",
"lib/fluxsink/fluxsink.h": "./lib/fluxsink/fluxsink.h",
"lib/fluxsource/catweasel.h": "lib/fluxsource/catweasel.h",
"lib/fluxsource/fluxsource.h": "lib/fluxsource/fluxsource.h",
"lib/fluxsource/flx.h": "lib/fluxsource/flx.h",
"lib/fluxsource/kryoflux.h": "lib/fluxsource/kryoflux.h",

View File

@@ -221,6 +221,10 @@ FluxEngine supports a number of ways to get or put flux. When using the `-s` or
Read from a Catweasel flux file. **Read only.**
- `dmk:<directory>`
Read from a Catweasel CMK directory. **Read only.**
- `<filename.a2r>`
Write to a AppleSauce flux file. **Write only.**

View File

@@ -71,6 +71,15 @@ Bytes::Bytes(
{
}
Bytes::Bytes(std::istream& istream, size_t len):
_data(createVector(0)),
_low(0),
_high(0)
{
ByteWriter bw(*this);
bw.append(istream, len);
}
Bytes* Bytes::operator=(const Bytes& other)
{
_data = other._data;
@@ -352,13 +361,24 @@ uint64_t ByteReader::read_be64()
return ((uint64_t)read_be32() << 32) | read_be32();
}
ByteWriter& ByteWriter::operator+=(std::istream& stream)
ByteWriter& ByteWriter::append(std::istream& stream, size_t length)
{
Bytes buffer(4096);
while (stream.read((char*)buffer.begin(), buffer.size()))
this->append(buffer);
this->append(buffer.slice(0, stream.gcount()));
while (length != 0)
{
size_t chunk = std::min((size_t)buffer.size(), length);
if (!stream.read((char*)buffer.begin(), chunk))
{
this->append(buffer.slice(0, stream.gcount()));
break;
}
else
this->append(buffer);
length -= chunk;
}
return *this;
}

View File

@@ -19,6 +19,7 @@ public:
Bytes(std::shared_ptr<std::vector<uint8_t>> data,
unsigned start,
unsigned end);
Bytes(std::istream& istream, size_t len = SIZE_MAX);
Bytes* operator=(const Bytes& other);
@@ -323,7 +324,10 @@ public:
return *this;
}
ByteWriter& operator+=(std::istream& stream);
ByteWriter& operator+=(std::istream& stream)
{
return this->append(stream);
}
ByteWriter& append(const char* data)
{
@@ -340,10 +344,7 @@ public:
return *this += data;
}
ByteWriter& append(std::istream& stream)
{
return *this += stream;
}
ByteWriter& append(std::istream& stream, size_t length = SIZE_MAX);
ByteWriter& pad(unsigned count, uint8_t byte = 0);

View File

@@ -32,6 +32,7 @@ enum FluxSourceSinkType {
FLUXTYPE_SCP = 9;
FLUXTYPE_TEST_PATTERN = 10;
FLUXTYPE_VCD = 11;
FLUXTYPE_DMK = 12;
}
enum ImageReaderWriterType {

View File

@@ -78,6 +78,14 @@ static const std::vector<FluxConstructor> fluxConstructors = {
proto->set_type(FLUXTYPE_CWF);
proto->mutable_cwf()->set_filename(s);
}},
{.name = "CatWeazle DMK directory",
.pattern = std::regex("^dmk:(.*)$"),
.source =
[](auto& s, auto* proto)
{
proto->set_type(FLUXTYPE_DMK);
proto->mutable_dmk()->set_directory(s);
}},
{.pattern = std::regex("^erase:$"),
.source =
[](auto& s, auto* proto)

View File

@@ -2,6 +2,7 @@
#include "lib/fluxmap.h"
#include "lib/fluxsource/fluxsource.pb.h"
#include "lib/fluxsource/fluxsource.h"
#include "lib/fluxsource/catweasel.h"
#include "lib/proto.h"
#include <fstream>
@@ -50,10 +51,10 @@ public:
switch (_header.clock_rate)
{
case 1:
_clockRate = 14161000.0;
_clockPeriod = 1e9 / 14161000.0;
break;
case 2:
_clockRate = 28322000.0;
_clockPeriod = 1e9 / 28322000.0;
break;
default:
error("unsupported clock rate");
@@ -65,7 +66,7 @@ public:
_header.tracks * _header.step,
_header.sides);
std::cout << fmt::format(
"CWF sample clock rate: {} MHz\n", _clockRate / 1e6);
"CWF sample clock rate: {} MHz\n", 1e3 / _clockPeriod);
int tracks = _header.tracks * _header.sides;
for (int i = 0; i < tracks; i++)
@@ -94,37 +95,12 @@ public:
return std::make_unique<const Fluxmap>();
off_t pos = p->second.first;
;
size_t length = p->second.second;
_if.seekg(pos);
std::unique_ptr<Fluxmap> fluxmap(new Fluxmap);
uint32_t pending = 0;
bool oldindex = true;
for (size_t cursor = 0; cursor < length; cursor++)
{
uint32_t b = _if.get();
bool index = !!(b & 0x80);
b &= 0x7f;
if (b == 0x7f)
{
pending += 0x7f;
continue;
}
b += pending;
pending = 0;
double interval_us = b * (1e6 / _clockRate);
fluxmap->appendInterval(interval_us / US_PER_TICK);
fluxmap->appendPulse();
if (index && !oldindex)
fluxmap->appendIndex();
oldindex = index;
}
Bytes fluxdata(_if, length);
check_for_error();
return fluxmap;
return decodeCatweaselData(fluxdata, _clockPeriod);
}
void recalibrate() {}
@@ -140,7 +116,7 @@ private:
const CwfFluxSourceProto& _config;
std::ifstream _if;
CwfHeader _header;
nanoseconds_t _clockRate;
nanoseconds_t _clockPeriod;
std::map<std::pair<int, int>, std::pair<off_t, size_t>> _trackOffsets;
};

View File

@@ -31,6 +31,9 @@ std::unique_ptr<FluxSource> FluxSource::create(const FluxSourceProto& config)
case FLUXTYPE_CWF:
return createCwfFluxSource(config.cwf());
case FLUXTYPE_DMK:
return createDmkFluxSource(config.dmk());
case FLUXTYPE_FLUX:
return createFl2FluxSource(config.fl2());

View File

@@ -37,6 +37,8 @@ private:
const A2rFluxSourceProto& config);
static std::unique_ptr<FluxSource> createCwfFluxSource(
const CwfFluxSourceProto& config);
static std::unique_ptr<FluxSource> createDmkFluxSource(
const DmkFluxSourceProto& config);
static std::unique_ptr<FluxSource> createEraseFluxSource(
const EraseFluxSourceProto& config);
static std::unique_ptr<FluxSource> createFl2FluxSource(

View File

@@ -30,6 +30,11 @@ message CwfFluxSourceProto {
(help) = ".cwf file to read flux from"];
}
message DmkFluxSourceProto {
optional string directory = 1 [
(help) = "path to DMK directory"];
}
message Fl2FluxSourceProto {
optional string filename = 1 [default = "flux.fl2",
(help) = ".fl2 file to read flux from"];
@@ -39,13 +44,14 @@ message FlxFluxSourceProto {
optional string directory = 1 [(help) = "path to FLX stream directory"];
}
// NEXT: 12
// NEXT: 13
message FluxSourceProto {
optional FluxSourceSinkType type = 9
[default = FLUXTYPE_NOT_SET, (help) = "flux source type"];
optional A2rFluxSourceProto a2r = 11;
optional CwfFluxSourceProto cwf = 7;
optional DmkFluxSourceProto dmk = 12;
optional EraseFluxSourceProto erase = 4;
optional Fl2FluxSourceProto fl2 = 8;
optional FlxFluxSourceProto flx = 10;