#include "globals.h" #include "flags.h" #include "fluxmap.h" #include "writer.h" #include "sql.h" #include "protocol.h" #include "usb/usb.h" #include "dataspec.h" #include "encoders/encoders.h" #include "fluxsource/fluxsource.h" #include "fluxsink/fluxsink.h" #include "imagereader/imagereader.h" #include "fmt/format.h" #include "record.h" #include "sector.h" #include "sectorset.h" FlagGroup writerFlags { &hardwareFluxSourceFlags, &sqliteFluxSinkFlags, &hardwareFluxSinkFlags }; static DataSpecFlag dest( { "--dest", "-d" }, "destination for data", ":d=0:t=0-79:s=0-1"); static DataSpecFlag input( { "--input", "-i" }, "input image file to read from", ""); static SettableFlag highDensityFlag( { "--high-density", "-H" }, "set the drive to high density mode"); static sqlite3* outdb; void setWriterDefaultDest(const std::string& dest) { ::dest.set(dest); } void setWriterDefaultInput(const std::string& input) { ::input.set(input); } void setWriterHardSectorCount(int sectorCount) { setHardwareFluxSinkHardSectorCount(sectorCount); } static SectorSet readSectorsFromFile(const ImageSpec& spec) { return ImageReader::create(spec)->readImage(); } void writeTracks( const std::function(int track, int side)> producer) { const FluxSpec spec(dest); std::cout << "Writing to: " << dest << std::endl; setHardwareFluxSourceDensity(highDensityFlag); setHardwareFluxSinkDensity(highDensityFlag); std::shared_ptr fluxSink = FluxSink::create(spec); for (const auto& location : spec.locations) { std::cout << fmt::format("{0:>3}.{1}: ", location.track, location.side) << std::flush; std::unique_ptr fluxmap = producer(location.track, location.side); if (!fluxmap) { /* Create an empty fluxmap for writing. */ fluxmap.reset(new Fluxmap()); } /* Precompensation actually seems to make things worse, so let's leave * it disabled for now. */ //fluxmap->precompensate(PRECOMPENSATION_THRESHOLD_TICKS, 2); fluxSink->writeFlux(location.track, location.side, *fluxmap); std::cout << fmt::format( "{0} ms in {1} bytes", int(fluxmap->duration()/1e6), fluxmap->bytes()) << std::endl; } } 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; } } } void writeDiskCommand(AbstractEncoder& encoder) { const ImageSpec spec(input); SectorSet allSectors = readSectorsFromFile(spec); writeTracks( [&](int track, int side) -> std::unique_ptr { return encoder.encode(track, side, allSectors); } ); }