Add the FL2 reader.

This commit is contained in:
dg
2021-12-05 11:33:19 +00:00
parent d36a18c17a
commit 298f77f52e
10 changed files with 96 additions and 86 deletions

View File

@@ -19,28 +19,35 @@ class Fl2FluxSink : public FluxSink
public:
Fl2FluxSink(const Fl2FluxSinkProto& lconfig):
_config(lconfig),
_of(lconfig.filename())
_of(lconfig.filename(), std::ios::out | std::ios::binary)
{
if (!_of.is_open())
Error() << "cannot open output file";
_proto.set_version(FluxFileVersion::VERSION_1);
}
~Fl2FluxSink()
{
std::cerr << "FL2: writing output file\n";
if (!_proto.SerializeToOstream(&_of))
FluxFileProto proto;
proto.set_version(FluxFileVersion::VERSION_1);
for (const auto& e : _data)
{
auto track = proto.add_track();
track->set_cylinder(e.first.first);
track->set_head(e.first.second);
track->set_flux(e.second);
}
if (!proto.SerializeToOstream(&_of))
Error() << "unable to write output file";
_of.close();
if (_of.fail())
Error() << "FL2 write I/O error: " << strerror(errno);
}
public:
void writeFlux(int cylinder, int head, Fluxmap& fluxmap)
{
auto track = _proto.add_track();
track->set_cylinder(cylinder);
track->set_head(head);
track->set_flux(fluxmap.rawBytes());
_data[std::make_pair(cylinder, head)] = fluxmap.rawBytes();
}
operator std::string () const
@@ -51,7 +58,7 @@ public:
private:
const Fl2FluxSinkProto& _config;
std::ofstream _of;
FluxFileProto _proto;
std::map<std::pair<unsigned, unsigned>, Bytes> _data;
};
std::unique_ptr<FluxSink> FluxSink::createFl2FluxSink(const Fl2FluxSinkProto& config)

View File

@@ -139,77 +139,3 @@ std::unique_ptr<FluxSource> FluxSource::createCwfFluxSource(const CwfFluxSourceP
{
return std::unique_ptr<FluxSource>(new CwfFluxSource(config));
}
#if 0
#include "globals.h"
#include "fluxmap.h"
#include "sql.h"
#include "bytes.h"
#include "protocol.h"
static std::ifstream inputFile;
static sqlite3* outputDb;
static CwfHeader header;
static double clockRate;
static void syntax()
{
std::cout << "Syntax: fluxengine convert cwftoflux <cwffile> <fluxfile>\n";
exit(0);
}
static void check_for_error()
{
if (inputFile.fail())
Error() << fmt::format("I/O error: {}", strerror(errno));
}
static void read_header()
{
}
static void read_track()
{
CwfTrack trackheader;
inputFile.read((char*) &trackheader, sizeof(trackheader));
check_for_error();
uint32_t length = Bytes(trackheader.length, 4).reader().read_le32() - sizeof(CwfTrack);
unsigned track_number = trackheader.track * header.step;
std::cout << fmt::format("{}.{}: {} input bytes; ", track_number, trackheader.side, length)
<< std::flush;
std::vector<uint8_t> inputdata(length);
inputFile.read((char*) &inputdata[0], length);
check_for_error();
std::cout << fmt::format(" {} ms in {} output bytes\n",
fluxmap.duration() / 1e6, fluxmap.bytes());
sqlWriteFlux(outputDb, track_number, trackheader.side, fluxmap);
}
int mainConvertCwfToFlux(int argc, const char* argv[])
{
if (argc != 3)
syntax();
inputFile.open(argv[1], std::ios::in | std::ios::binary);
if (!inputFile.is_open())
Error() << fmt::format("cannot open input file '{}'", argv[1]);
outputDb = sqlOpen(argv[2], SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
sqlPrepareFlux(outputDb);
sqlWriteIntProperty(outputDb, "version", FLUX_VERSION_CURRENT);
sqlStmt(outputDb, "BEGIN;");
read_header();
inputFile.seekg(sizeof(header), std::ios::beg);
for (unsigned i=0; i<(header.cylinders*header.sides); i++)
read_track();
sqlStmt(outputDb, "COMMIT;");
sqlClose(outputDb);
return 0;
}
#endif

View File

@@ -0,0 +1,55 @@
#include "globals.h"
#include "fluxmap.h"
#include "lib/fluxsource/fluxsource.pb.h"
#include "lib/fl2.pb.h"
#include "fluxsource/fluxsource.h"
#include "proto.h"
#include "fmt/format.h"
#include <fstream>
class Fl2FluxSource : public FluxSource
{
public:
Fl2FluxSource(const Fl2FluxSourceProto& config):
_config(config)
{
std::ifstream ifs(_config.filename(), std::ios::in | std::ios::binary);
if (!ifs.is_open())
Error() << fmt::format("cannot open input file '{}': {}",
_config.filename(), strerror(errno));
if (!_proto.ParseFromIstream(&ifs))
Error() << "unable to read input file";
}
public:
std::unique_ptr<Fluxmap> readFlux(int cylinder, int head)
{
for (const auto& track : _proto.track())
{
if ((track.cylinder() == cylinder) && (track.head() == head))
return std::make_unique<Fluxmap>(track.flux());
}
return std::unique_ptr<Fluxmap>();
}
void recalibrate() {}
private:
void check_for_error(std::ifstream& ifs)
{
if (ifs.fail())
Error() << fmt::format("FL2 read I/O error: {}", strerror(errno));
}
private:
const Fl2FluxSourceProto& _config;
FluxFileProto _proto;
};
std::unique_ptr<FluxSource> FluxSource::createFl2FluxSource(const Fl2FluxSourceProto& config)
{
return std::unique_ptr<FluxSource>(new Fl2FluxSource(config));
}

View File

@@ -39,6 +39,9 @@ std::unique_ptr<FluxSource> FluxSource::create(const FluxSourceProto& config)
case FluxSourceProto::kCwf:
return createCwfFluxSource(config.cwf());
case FluxSourceProto::kFl2:
return createFl2FluxSource(config.fl2());
default:
Error() << "bad input disk configuration";
return std::unique_ptr<FluxSource>();
@@ -52,6 +55,7 @@ void FluxSource::updateConfigForFilename(FluxSourceProto* proto, const std::stri
{ std::regex("^(.*\\.flux)$"), [&](const auto& s) { proto->set_fluxfile(s); }},
{ std::regex("^(.*\\.scp)$"), [&](const auto& s) { proto->mutable_scp()->set_filename(s); }},
{ std::regex("^(.*\\.cwf)$"), [&](const auto& s) { proto->mutable_cwf()->set_filename(s); }},
{ std::regex("^(.*\\.fl2)$"), [&](const auto& s) { proto->mutable_fl2()->set_filename(s); }},
{ std::regex("^erase:$"), [&](const auto& s) { proto->mutable_erase(); }},
{ std::regex("^kryoflux:(.*)$"), [&](const auto& s) { proto->mutable_kryoflux()->set_directory(s); }},
{ std::regex("^testpattern:(.*)"), [&](const auto& s) { proto->mutable_test_pattern(); }},

View File

@@ -5,6 +5,7 @@
class CwfFluxSourceProto;
class EraseFluxSourceProto;
class Fl2FluxSourceProto;
class FluxSourceProto;
class FluxSpec;
class Fluxmap;
@@ -21,6 +22,7 @@ public:
private:
static std::unique_ptr<FluxSource> createCwfFluxSource(const CwfFluxSourceProto& config);
static std::unique_ptr<FluxSource> createEraseFluxSource(const EraseFluxSourceProto& config);
static std::unique_ptr<FluxSource> createFl2FluxSource(const Fl2FluxSourceProto& config);
static std::unique_ptr<FluxSource> createHardwareFluxSource(const HardwareFluxSourceProto& config);
static std::unique_ptr<FluxSource> createKryofluxFluxSource(const KryofluxFluxSourceProto& config);
static std::unique_ptr<FluxSource> createScpFluxSource(const ScpFluxSourceProto& config);

View File

@@ -29,10 +29,15 @@ message ScpFluxSourceProto {
}
message CwfFluxSourceProto {
optional string filename = 1 [default = "flux.xwf",
optional string filename = 1 [default = "flux.cwf",
(help) = ".cwf file to read flux from"];
}
message Fl2FluxSourceProto {
optional string filename = 1 [default = "flux.fl2",
(help) = ".fl2 file to read flux from"];
}
message FluxSourceProto {
oneof source {
string fluxfile = 1 [default = "name of source flux file"];
@@ -42,6 +47,7 @@ message FluxSourceProto {
KryofluxFluxSourceProto kryoflux = 5;
ScpFluxSourceProto scp = 6;
CwfFluxSourceProto cwf = 7;
Fl2FluxSourceProto fl2 = 8;
}
}

View File

@@ -18,6 +18,10 @@
#define mkdir(A, B) _mkdir(A)
#endif
template <class T>
static inline std::vector<T> vector_of(T item)
{ return std::vector<T> { item }; }
typedef double nanoseconds_t;
class Bytes;

View File

@@ -270,6 +270,10 @@ encodedecodetest() {
echo " format=$format"
echo " configs=$*"
echo " fluxx=scp"
echo "build $OBJDIR/$format.encodedecode.fl2.stamp : encodedecode | fluxengine$EXTENSION scripts/encodedecodetest.sh $*"
echo " format=$format"
echo " configs=$*"
echo " fluxx=fl2"
}
buildlibrary libagg.a \
@@ -359,6 +363,7 @@ buildlibrary libbackend.a \
lib/fluxsink/vcdfluxsink.cc \
lib/fluxsource/cwffluxsource.cc \
lib/fluxsource/erasefluxsource.cc \
lib/fluxsource/fl2fluxsource.cc \
lib/fluxsource/fluxsource.cc \
lib/fluxsource/hardwarefluxsource.cc \
lib/fluxsource/kryoflux.cc \

View File

@@ -88,7 +88,8 @@ enum
enum
{
F_BIT_PULSE = 0x80,
F_BIT_INDEX = 0x40
F_BIT_INDEX = 0x40,
F_DESYNC = 0xc0
};
struct frame_header

View File

@@ -1,7 +1,7 @@
#include "globals.h"
#include "flags.h"
#include "usb/usb.h"
#include "fluxsource/fluxsource.cc"
#include "fluxsource/fluxsource.h"
#include "proto.h"
#include "protocol.h"