diff --git a/lib/fluxsink/fl2fluxsink.cc b/lib/fluxsink/fl2fluxsink.cc index 69bde688..d34052c0 100644 --- a/lib/fluxsink/fl2fluxsink.cc +++ b/lib/fluxsink/fl2fluxsink.cc @@ -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, Bytes> _data; }; std::unique_ptr FluxSink::createFl2FluxSink(const Fl2FluxSinkProto& config) diff --git a/lib/fluxsource/cwffluxsource.cc b/lib/fluxsource/cwffluxsource.cc index bf383e0e..033e4364 100644 --- a/lib/fluxsource/cwffluxsource.cc +++ b/lib/fluxsource/cwffluxsource.cc @@ -139,77 +139,3 @@ std::unique_ptr FluxSource::createCwfFluxSource(const CwfFluxSourceP { return std::unique_ptr(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 \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 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 diff --git a/lib/fluxsource/fl2fluxsource.cc b/lib/fluxsource/fl2fluxsource.cc new file mode 100644 index 00000000..05fa4392 --- /dev/null +++ b/lib/fluxsource/fl2fluxsource.cc @@ -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 + +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 readFlux(int cylinder, int head) + { + for (const auto& track : _proto.track()) + { + if ((track.cylinder() == cylinder) && (track.head() == head)) + return std::make_unique(track.flux()); + } + + return std::unique_ptr(); + } + + 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::createFl2FluxSource(const Fl2FluxSourceProto& config) +{ + return std::unique_ptr(new Fl2FluxSource(config)); +} + diff --git a/lib/fluxsource/fluxsource.cc b/lib/fluxsource/fluxsource.cc index 67658ff6..768eeeea 100644 --- a/lib/fluxsource/fluxsource.cc +++ b/lib/fluxsource/fluxsource.cc @@ -39,6 +39,9 @@ std::unique_ptr 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(); @@ -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(); }}, diff --git a/lib/fluxsource/fluxsource.h b/lib/fluxsource/fluxsource.h index 38cb4a14..9ea0f7b1 100644 --- a/lib/fluxsource/fluxsource.h +++ b/lib/fluxsource/fluxsource.h @@ -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 createCwfFluxSource(const CwfFluxSourceProto& config); static std::unique_ptr createEraseFluxSource(const EraseFluxSourceProto& config); + static std::unique_ptr createFl2FluxSource(const Fl2FluxSourceProto& config); static std::unique_ptr createHardwareFluxSource(const HardwareFluxSourceProto& config); static std::unique_ptr createKryofluxFluxSource(const KryofluxFluxSourceProto& config); static std::unique_ptr createScpFluxSource(const ScpFluxSourceProto& config); diff --git a/lib/fluxsource/fluxsource.proto b/lib/fluxsource/fluxsource.proto index 1cf49008..c5ce6243 100644 --- a/lib/fluxsource/fluxsource.proto +++ b/lib/fluxsource/fluxsource.proto @@ -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; } } diff --git a/lib/globals.h b/lib/globals.h index ab10a54b..3aaab4c2 100644 --- a/lib/globals.h +++ b/lib/globals.h @@ -18,6 +18,10 @@ #define mkdir(A, B) _mkdir(A) #endif +template +static inline std::vector vector_of(T item) +{ return std::vector { item }; } + typedef double nanoseconds_t; class Bytes; diff --git a/mkninja.sh b/mkninja.sh index 10956e5e..0517d992 100644 --- a/mkninja.sh +++ b/mkninja.sh @@ -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 \ diff --git a/protocol.h b/protocol.h index 2d04c718..6def92f0 100644 --- a/protocol.h +++ b/protocol.h @@ -88,7 +88,8 @@ enum enum { F_BIT_PULSE = 0x80, - F_BIT_INDEX = 0x40 + F_BIT_INDEX = 0x40, + F_DESYNC = 0xc0 }; struct frame_header diff --git a/src/fe-seek.cc b/src/fe-seek.cc index 6c11fbb5..68c6b512 100644 --- a/src/fe-seek.cc +++ b/src/fe-seek.cc @@ -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"