mirror of
https://github.com/davidgiven/fluxengine.git
synced 2025-10-31 11:17:01 -07:00
Merge from master.
This commit is contained in:
@@ -149,7 +149,10 @@ std::unique_ptr<Fluxmap> IbmEncoder::encode(
|
||||
|
||||
const auto& sectorData = allSectors.get(physicalTrack, physicalSide, sectorId);
|
||||
if (!sectorData)
|
||||
Error() << fmt::format("format tried to find sector {} which wasn't in the input file", sectorId);
|
||||
{
|
||||
/* If there are any missing sectors, this is an empty track. */
|
||||
return std::unique_ptr<Fluxmap>();
|
||||
}
|
||||
|
||||
/* Writing the sector and data records are fantastically annoying.
|
||||
* The CRC is calculated from the *very start* of the record, and
|
||||
|
||||
@@ -46,6 +46,10 @@ You should end up with a `brother.img` which is 239616 bytes long.
|
||||
Writing disks
|
||||
-------------
|
||||
|
||||
Only 240kB disks can be written, currently ( [get in
|
||||
touch](https://github.com/davidgiven/fluxengine/issues/new) if you want to
|
||||
write 120kB disks).
|
||||
|
||||
Just do:
|
||||
|
||||
```
|
||||
|
||||
70
doc/using.md
70
doc/using.md
@@ -49,6 +49,34 @@ You _can_ work with more than one FluxEngine at the same time, using different
|
||||
invocations of the client; but be careful of USB bandwidth. If the devices are
|
||||
connected via the same hub, the bandwidth will be shared.
|
||||
|
||||
### Logical and physical tracks
|
||||
|
||||
In general, FluxEngine will read one track off disk, and write it to one track
|
||||
in a file, or vice versa. Sometimes these don't match. Two important FluxEngine
|
||||
concepts are that of the _physical track_ and the _logical track_.
|
||||
|
||||
_Physical tracks_ are how FluxEngine locates tracks on the disk. The numbering
|
||||
used by 80-track drives is always used, even if you actually have a 40-track
|
||||
drive attached (this actually makes things simpler).
|
||||
|
||||
_Logical tracks_ are where the data is in the filesystem. This doesn't need to
|
||||
match the physical track. The logical track number is usually encoded on the
|
||||
disk itself in the sector header. FluxEngine uses this for placing the data in
|
||||
the output file.
|
||||
|
||||
The most common situation where these won't match is when you have a 40-track
|
||||
disk in an 80-track drive. Because each 40-track track is twice the width of an
|
||||
80-track track, you'll see logical track 0 on physical tracks 0 and 1, and
|
||||
logical track 1 on physical tracks 2 and 3, and logical track 2 on physical
|
||||
tracks 4 and 5, etc.
|
||||
|
||||
When reading from a disk, this will usually take care of itself as disks are
|
||||
mostly self-describing --- FluxEngine can tell which logical track data is
|
||||
located at from the sector header. However, when writing to a disk, this isn't
|
||||
the case, and you may to supply extra parameters to tell FluxEngine the mapping
|
||||
from data in the image to physical tracks. This is most likely to happen when
|
||||
using 40-track disks.
|
||||
|
||||
### Source and destination specifiers
|
||||
|
||||
When reading from or writing _flux_ (either from or to a real disk, or a flux
|
||||
@@ -78,11 +106,11 @@ fluxengine read ibm -s fakedisk.flux:t=0-79:s=0
|
||||
`some/files/:t=0-10`. There must be a files for a single disk only
|
||||
in the directory.
|
||||
|
||||
Source and destination specifiers work entirely in *physical units*.
|
||||
FluxEngine is intended to be connected to an 80 (or 82) track double sided
|
||||
drive, and these are the units used. If the format you're trying to access
|
||||
lays out its tracks differently, then you'll need a specifier which tells
|
||||
FluxEngine how to find those tracks. See the 40-track disk example above.
|
||||
Source and destination specifiers work entirely in *physical units*. As
|
||||
described above, FluxEngine is intended to be connected to an 80 (or 82) track
|
||||
double sided drive, and these are the units used. If the format you're trying
|
||||
to access lays out its tracks differently, then you'll need a specifier which
|
||||
tells FluxEngine how to find those tracks. See the 40-track disk example above.
|
||||
|
||||
If you _don't_ specify a modifier, you'll get the default, which should be
|
||||
sensible for the command you're using.
|
||||
@@ -104,6 +132,11 @@ exact format varies according to the extension:
|
||||
geometry will be autodetected if left unspecified. For input files you
|
||||
normally have to specify it.
|
||||
|
||||
If one logical track does not map directly onto on physical track, you can
|
||||
change this with `:o=1:t=2`: `o` specifies the offset, and `t` specifies
|
||||
the step. So, with this format, cylinder 1 in the image will be written to
|
||||
track 3 on the disk.
|
||||
|
||||
- `.ldbs`: John Elliott's [LDBS disk image
|
||||
format](http://www.seasip.info/Unix/LibDsk/ldbs.html), which is
|
||||
consumable by the [libdsk](http://www.seasip.info/Unix/LibDsk/) suite of
|
||||
@@ -152,7 +185,7 @@ disks, and have different magnetic properties. 3.5" drives can usually
|
||||
autodetect what kind of medium is inserted into the drive based on the hole
|
||||
in the disk casing, but 5.25" drives can't. As a result, you need to
|
||||
explicitly tell FluxEngine on the command line whether you're using a high
|
||||
density disk or not with the `--hd` flag.
|
||||
density disk or not with the `-H` flag.
|
||||
**If you don't do this, your disks may not read correctly and will _certainly_
|
||||
fail to write correctly.**
|
||||
|
||||
@@ -164,6 +197,31 @@ case, and reading the disk label is much more reliable.
|
||||
[Lots more information on high density vs double density disks can be found
|
||||
here.](http://www.retrotechnology.com/herbs_stuff/guzis.html)
|
||||
|
||||
### 40-track disks and drives
|
||||
|
||||
These require special handling.
|
||||
|
||||
- reading a 40-track disk from an 80-track drive: everything should just work
|
||||
via autodetection.
|
||||
|
||||
- writing a 40-track disk to an 80-track drive: you want to write _all
|
||||
physical tracks_, so `-d :t=0-79`. For `.img` files you will also need `-i
|
||||
:t=2` to set the mapping between logical tracks in the image and physical
|
||||
tracks on the disk.
|
||||
|
||||
- reading a 40-track disk from a 40-track drive: use `--40-track` to tell
|
||||
FluxEngine you have a 40-track drive; everything should just work via
|
||||
autodetection.
|
||||
|
||||
- writing a 40-track disk to a 40-track drive: you want to write _even tracks
|
||||
only_, so `-d :t=0-79x2`, and for `.img` files you will also need `-i
|
||||
:t=2`.
|
||||
|
||||
The `--40-track` or `-4` option tells FluxEngine that it's plugged into a
|
||||
40-track drive. It will assume that each step of the drive corresponds to two
|
||||
physical tracks. Only even tracks are accessible in this mode.
|
||||
|
||||
|
||||
### Other important flags
|
||||
|
||||
These flags apply to many operations and are useful for modifying the overall
|
||||
|
||||
@@ -162,6 +162,8 @@ ImageSpec::ImageSpec(const DataSpec& spec)
|
||||
if (!spec.has("c") && !spec.has("h") && !spec.has("s") && !spec.has("b"))
|
||||
{
|
||||
cylinders = heads = sectors = bytes = 0;
|
||||
physicalOffset = 0;
|
||||
physicalStep = 1;
|
||||
initialised = false;
|
||||
}
|
||||
else
|
||||
@@ -170,6 +172,8 @@ ImageSpec::ImageSpec(const DataSpec& spec)
|
||||
heads = spec.at("h").only();
|
||||
sectors = spec.at("s").only();
|
||||
bytes = spec.at("b").only();
|
||||
physicalOffset = spec.atOr("o", 0);
|
||||
physicalStep = spec.atOr("t", 1);
|
||||
initialised = true;
|
||||
}
|
||||
}
|
||||
@@ -181,18 +185,22 @@ ImageSpec::ImageSpec(const DataSpec& spec)
|
||||
for (const auto& e : spec.modifiers)
|
||||
{
|
||||
const auto name = e.second.name;
|
||||
if ((name != "c") && (name != "h") && (name != "s") && (name != "b"))
|
||||
Error() << fmt::format("unknown fluxspec modifier '{}'", name);
|
||||
static const std::set<std::string> modifiers { "c", "h", "s", "b", "o", "t" };
|
||||
if (modifiers.find(name) == modifiers.end())
|
||||
Error() << fmt::format("unknown imagespec modifier '{}'", name);
|
||||
}
|
||||
}
|
||||
|
||||
ImageSpec::ImageSpec(const std::string filename,
|
||||
unsigned cylinders, unsigned heads, unsigned sectors, unsigned bytes):
|
||||
unsigned cylinders, unsigned heads, unsigned sectors, unsigned bytes,
|
||||
int physicalOffset, int physicalStep):
|
||||
filename(filename),
|
||||
cylinders(cylinders),
|
||||
heads(heads),
|
||||
sectors(sectors),
|
||||
bytes(bytes),
|
||||
physicalOffset(physicalOffset),
|
||||
physicalStep(physicalStep),
|
||||
initialised(true)
|
||||
{}
|
||||
|
||||
|
||||
@@ -48,6 +48,9 @@ public:
|
||||
const Modifier& at(const std::string& mod) const;
|
||||
bool has(const std::string& mod) const;
|
||||
|
||||
unsigned atOr(const std::string& mod, unsigned value) const
|
||||
{ return has(mod) ? at(mod).only() : value; }
|
||||
|
||||
std::string filename;
|
||||
std::map<std::string, Modifier> modifiers;
|
||||
};
|
||||
@@ -82,7 +85,8 @@ class ImageSpec
|
||||
public:
|
||||
ImageSpec(const DataSpec& dataspec);
|
||||
ImageSpec(const std::string filename,
|
||||
unsigned cylinders, unsigned heads, unsigned sectors, unsigned bytes);
|
||||
unsigned cylinders, unsigned heads, unsigned sectors, unsigned bytes,
|
||||
int physicalOffset=0, int physicalStep=1);
|
||||
|
||||
public:
|
||||
std::string filename;
|
||||
@@ -90,6 +94,8 @@ public:
|
||||
unsigned heads;
|
||||
unsigned sectors;
|
||||
unsigned bytes;
|
||||
int physicalOffset;
|
||||
int physicalStep;
|
||||
bool initialised : 1;
|
||||
};
|
||||
|
||||
|
||||
15
lib/flaggroups/fluxsourcesink.cc
Normal file
15
lib/flaggroups/fluxsourcesink.cc
Normal file
@@ -0,0 +1,15 @@
|
||||
#include "globals.h"
|
||||
#include "flags.h"
|
||||
#include "flaggroups/fluxsourcesink.h"
|
||||
|
||||
FlagGroup fluxSourceSinkFlags;
|
||||
|
||||
SettableFlag fluxSourceSinkFortyTrack(
|
||||
{ "--40-track", "-4" },
|
||||
"indicates a 40 track drive");
|
||||
|
||||
SettableFlag fluxSourceSinkHighDensity(
|
||||
{ "--high-density", "-H" },
|
||||
"set the drive to high density mode");
|
||||
|
||||
|
||||
13
lib/flaggroups/fluxsourcesink.h
Normal file
13
lib/flaggroups/fluxsourcesink.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#ifndef FLUXSOURCESINK_H
|
||||
#define FLUXSOURCESINK_H
|
||||
|
||||
#include "flags.h"
|
||||
|
||||
extern FlagGroup fluxSourceSinkFlags;
|
||||
|
||||
extern SettableFlag fluxSourceSinkFortyTrack;
|
||||
extern SettableFlag fluxSourceSinkHighDensity;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@ public:
|
||||
virtual void writeFlux(int track, int side, Fluxmap& fluxmap) = 0;
|
||||
};
|
||||
|
||||
extern void setHardwareFluxSinkDensity(bool high_density);
|
||||
extern void setHardwareFluxSinkHardSectorCount(int sectorCount);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3,14 +3,14 @@
|
||||
#include "fluxmap.h"
|
||||
#include "usb/usb.h"
|
||||
#include "fluxsink/fluxsink.h"
|
||||
#include "flaggroups/fluxsourcesink.h"
|
||||
#include "fmt/format.h"
|
||||
|
||||
FlagGroup hardwareFluxSinkFlags = {
|
||||
&fluxSourceSinkFlags,
|
||||
&usbFlags,
|
||||
};
|
||||
|
||||
static bool high_density = false;
|
||||
|
||||
static IntFlag indexMode(
|
||||
{ "--write-index-mode" },
|
||||
"index pulse source (0=drive, 1=300 RPM fake source, 2=360 RPM fake source",
|
||||
@@ -21,11 +21,6 @@ static IntFlag hardSectorCount(
|
||||
"number of hard sectors on the disk (0=soft sectors)",
|
||||
0);
|
||||
|
||||
void setHardwareFluxSinkDensity(bool high_density)
|
||||
{
|
||||
::high_density = high_density;
|
||||
}
|
||||
|
||||
void setHardwareFluxSinkHardSectorCount(int sectorCount)
|
||||
{
|
||||
::hardSectorCount.setDefaultValue(sectorCount);
|
||||
@@ -39,7 +34,7 @@ public:
|
||||
{
|
||||
if (hardSectorCount != 0)
|
||||
{
|
||||
usbSetDrive(_drive, high_density, indexMode);
|
||||
usbSetDrive(_drive, fluxSourceSinkHighDensity, indexMode);
|
||||
std::cerr << "Measuring rotational speed... " << std::flush;
|
||||
nanoseconds_t oneRevolution = usbGetRotationalPeriod(hardSectorCount);
|
||||
_hardSectorThreshold = oneRevolution * 3 / (4 * hardSectorCount);
|
||||
@@ -56,8 +51,15 @@ public:
|
||||
public:
|
||||
void writeFlux(int track, int side, Fluxmap& fluxmap)
|
||||
{
|
||||
usbSetDrive(_drive, high_density, indexMode);
|
||||
usbSeek(track);
|
||||
usbSetDrive(_drive, fluxSourceSinkHighDensity, indexMode);
|
||||
if (fluxSourceSinkFortyTrack)
|
||||
{
|
||||
if (track & 1)
|
||||
Error() << "cannot write to odd physical tracks in 40-track mode";
|
||||
usbSeek(track / 2);
|
||||
}
|
||||
else
|
||||
usbSeek(track);
|
||||
|
||||
return usbWrite(side, fluxmap.rawBytes(), _hardSectorThreshold);
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@ public:
|
||||
};
|
||||
|
||||
extern void setHardwareFluxSourceRevolutions(double revolutions);
|
||||
extern void setHardwareFluxSourceDensity(bool high_density);
|
||||
extern void setHardwareFluxSourceSynced(bool synced);
|
||||
extern void setHardwareFluxSourceHardSectorCount(int sectorCount);
|
||||
|
||||
|
||||
@@ -3,9 +3,11 @@
|
||||
#include "fluxmap.h"
|
||||
#include "usb/usb.h"
|
||||
#include "fluxsource/fluxsource.h"
|
||||
#include "flaggroups/fluxsourcesink.h"
|
||||
#include "fmt/format.h"
|
||||
|
||||
FlagGroup hardwareFluxSourceFlags = {
|
||||
&fluxSourceSinkFlags,
|
||||
&usbFlags
|
||||
};
|
||||
|
||||
@@ -29,20 +31,13 @@ static IntFlag hardSectorCount(
|
||||
"number of hard sectors on the disk (0=soft sectors)",
|
||||
0);
|
||||
|
||||
static bool high_density = false;
|
||||
|
||||
void setHardwareFluxSourceDensity(bool high_density)
|
||||
{
|
||||
::high_density = high_density;
|
||||
}
|
||||
|
||||
class HardwareFluxSource : public FluxSource
|
||||
{
|
||||
public:
|
||||
HardwareFluxSource(unsigned drive):
|
||||
_drive(drive)
|
||||
{
|
||||
usbSetDrive(_drive, high_density, indexMode);
|
||||
usbSetDrive(_drive, fluxSourceSinkHighDensity, indexMode);
|
||||
std::cerr << "Measuring rotational speed... " << std::flush;
|
||||
_oneRevolution = usbGetRotationalPeriod(hardSectorCount);
|
||||
if (hardSectorCount != 0)
|
||||
@@ -59,8 +54,16 @@ public:
|
||||
public:
|
||||
std::unique_ptr<Fluxmap> readFlux(int track, int side)
|
||||
{
|
||||
usbSetDrive(_drive, high_density, indexMode);
|
||||
usbSeek(track);
|
||||
usbSetDrive(_drive, fluxSourceSinkHighDensity, indexMode);
|
||||
if (fluxSourceSinkFortyTrack)
|
||||
{
|
||||
if (track & 1)
|
||||
Error() << "cannot read from odd physical tracks in 40-track mode";
|
||||
usbSeek(track / 2);
|
||||
}
|
||||
else
|
||||
usbSeek(track);
|
||||
|
||||
Bytes data = usbRead(
|
||||
side, synced, revolutions * _oneRevolution, _hardSectorThreshold);
|
||||
auto fluxmap = std::make_unique<Fluxmap>();
|
||||
|
||||
@@ -30,6 +30,9 @@ public:
|
||||
spec.sectors, spec.bytes,
|
||||
spec.cylinders * trackSize / 1024)
|
||||
<< std::endl;
|
||||
if ((spec.physicalOffset != 0) || (spec.physicalStep != 1))
|
||||
std::cout << fmt::format("logical to physical track mapping: physical = logical*{} + {}\n",
|
||||
spec.physicalStep, spec.physicalOffset);
|
||||
|
||||
SectorSet sectors;
|
||||
for (int track = 0; track < spec.cylinders; track++)
|
||||
@@ -43,10 +46,12 @@ public:
|
||||
Bytes data(spec.bytes);
|
||||
inputFile.read((char*) data.begin(), spec.bytes);
|
||||
|
||||
std::unique_ptr<Sector>& sector = sectors.get(track, head, sectorId);
|
||||
int physicalTrack = track*spec.physicalStep + spec.physicalOffset;
|
||||
std::unique_ptr<Sector>& sector = sectors.get(physicalTrack, head, sectorId);
|
||||
sector.reset(new Sector);
|
||||
sector->status = Sector::OK;
|
||||
sector->logicalTrack = sector->physicalTrack = track;
|
||||
sector->logicalTrack = track;
|
||||
sector->physicalTrack = physicalTrack;
|
||||
sector->logicalSide = sector->physicalSide = head;
|
||||
sector->logicalSector = sectorId;
|
||||
sector->data = data;
|
||||
|
||||
@@ -58,10 +58,6 @@ static IntFlag retries(
|
||||
"How many times to retry each track in the event of a read failure.",
|
||||
5);
|
||||
|
||||
static SettableFlag highDensityFlag(
|
||||
{ "--high-density", "--hd" },
|
||||
"set the drive to high density mode");
|
||||
|
||||
static StringFlag csvFile(
|
||||
{ "--write-csv" },
|
||||
"write a CSV report of the disk state",
|
||||
@@ -117,8 +113,6 @@ std::vector<std::unique_ptr<Track>> readTracks()
|
||||
|
||||
std::cout << "Reading from: " << source << std::endl;
|
||||
|
||||
setHardwareFluxSourceDensity(highDensityFlag);
|
||||
|
||||
if (!destination.get().empty())
|
||||
{
|
||||
std::cout << "Writing a copy of the flux to " << destination.get() << std::endl;
|
||||
|
||||
@@ -27,10 +27,6 @@ static DataSpecFlag input(
|
||||
"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)
|
||||
@@ -60,9 +56,6 @@ void writeTracks(
|
||||
|
||||
std::cout << "Writing to: " << dest << std::endl;
|
||||
|
||||
setHardwareFluxSourceDensity(highDensityFlag);
|
||||
setHardwareFluxSinkDensity(highDensityFlag);
|
||||
|
||||
std::shared_ptr<FluxSink> fluxSink = FluxSink::create(spec);
|
||||
|
||||
for (const auto& location : spec.locations)
|
||||
@@ -71,16 +64,21 @@ void writeTracks(
|
||||
std::unique_ptr<Fluxmap> fluxmap = producer(location.track, location.side);
|
||||
if (!fluxmap)
|
||||
{
|
||||
/* Create an empty fluxmap for writing. */
|
||||
fluxmap.reset(new Fluxmap());
|
||||
}
|
||||
/* Erase this track rather than writing. */
|
||||
|
||||
/* 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;
|
||||
fluxmap.reset(new Fluxmap());
|
||||
fluxSink->writeFlux(location.track, location.side, *fluxmap);
|
||||
std::cout << "erased\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -233,6 +233,7 @@ buildlibrary libbackend.a \
|
||||
lib/decoders/fluxmapreader.cc \
|
||||
lib/decoders/fmmfm.cc \
|
||||
lib/encoders/encoders.cc \
|
||||
lib/flaggroups/fluxsourcesink.cc \
|
||||
lib/flags.cc \
|
||||
lib/fluxmap.cc \
|
||||
lib/fluxsink/fluxsink.cc \
|
||||
|
||||
@@ -7,11 +7,13 @@
|
||||
#include "writer.h"
|
||||
#include "protocol.h"
|
||||
#include "fmt/format.h"
|
||||
#include "flaggroups/fluxsourcesink.h"
|
||||
#include "dep/agg/include/agg2d.h"
|
||||
#include "dep/stb/stb_image_write.h"
|
||||
#include <fstream>
|
||||
|
||||
static FlagGroup flags = {
|
||||
&fluxSourceSinkFlags,
|
||||
&usbFlags,
|
||||
};
|
||||
|
||||
@@ -186,8 +188,15 @@ int mainAnalyseDriveResponse(int argc, const char* argv[])
|
||||
if (spec.locations.size() != 1)
|
||||
Error() << "the destination dataspec must contain exactly one track (two sides count as two tracks)";
|
||||
|
||||
usbSetDrive(spec.drive, false, F_INDEX_REAL);
|
||||
usbSeek(spec.locations[0].track);
|
||||
usbSetDrive(spec.drive, fluxSourceSinkHighDensity, F_INDEX_REAL);
|
||||
int track = spec.locations[0].track;
|
||||
if (fluxSourceSinkFortyTrack)
|
||||
{
|
||||
if (track & 1)
|
||||
Error() << "you can only seek to even tracks on a 40-track disk";
|
||||
track /= 2;
|
||||
}
|
||||
usbSeek(track);
|
||||
|
||||
std::cout << "Measuring rotational speed...\n";
|
||||
nanoseconds_t period = usbGetRotationalPeriod(0);
|
||||
|
||||
@@ -22,10 +22,6 @@ static StringFlag output(
|
||||
"output AU file to write",
|
||||
"output.au");
|
||||
|
||||
static SettableFlag highDensityFlag(
|
||||
{ "--high-density", "--hd" },
|
||||
"set the drive to high density mode");
|
||||
|
||||
static SettableFlag withIndex(
|
||||
{ "--with-index" },
|
||||
"place index markers in the right hand channel");
|
||||
@@ -41,7 +37,6 @@ int mainConvertFluxToAu(int argc, const char* argv[])
|
||||
const auto& location = *(locations.begin());
|
||||
|
||||
std::cerr << "Reading source flux...\n";
|
||||
setHardwareFluxSourceDensity(highDensityFlag);
|
||||
std::shared_ptr<FluxSource> fluxsource = FluxSource::create(spec);
|
||||
const auto& fluxmap = fluxsource->readFlux(location.track, location.side);
|
||||
unsigned totalTicks = fluxmap->ticks() + 2;
|
||||
|
||||
@@ -22,10 +22,6 @@ static StringFlag output(
|
||||
"output VCD file to write",
|
||||
"output.vcd");
|
||||
|
||||
static SettableFlag highDensityFlag(
|
||||
{ "--high-density", "--hd" },
|
||||
"set the drive to high density mode");
|
||||
|
||||
int mainConvertFluxToVcd(int argc, const char* argv[])
|
||||
{
|
||||
flags.parseFlags(argc, argv);
|
||||
@@ -37,7 +33,6 @@ int mainConvertFluxToVcd(int argc, const char* argv[])
|
||||
const auto& location = *(locations.begin());
|
||||
|
||||
std::cerr << "Reading source flux...\n";
|
||||
setHardwareFluxSourceDensity(highDensityFlag);
|
||||
std::shared_ptr<FluxSource> fluxsource = FluxSource::create(spec);
|
||||
const auto& fluxmap = fluxsource->readFlux(location.track, location.side);
|
||||
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
#include "globals.h"
|
||||
#include "flags.h"
|
||||
#include "usb/usb.h"
|
||||
#include "flaggroups/fluxsourcesink.h"
|
||||
#include "protocol.h"
|
||||
|
||||
static FlagGroup flags = {
|
||||
&fluxSourceSinkFlags,
|
||||
&usbFlags,
|
||||
};
|
||||
|
||||
@@ -22,6 +24,13 @@ int mainSeek(int argc, const char* argv[])
|
||||
flags.parseFlags(argc, argv);
|
||||
|
||||
usbSetDrive(drive, false, F_INDEX_REAL);
|
||||
usbSeek(track);
|
||||
if (fluxSourceSinkFortyTrack)
|
||||
{
|
||||
if (track & 1)
|
||||
Error() << "you can only seek to even tracks on a 40-track drive";
|
||||
usbSeek(track / 2);
|
||||
}
|
||||
else
|
||||
usbSeek(track);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -111,15 +111,28 @@ static void test_fluxspec(void)
|
||||
|
||||
static void test_imagespec(void)
|
||||
{
|
||||
DataSpec spec("foo:c=9:h=2:s=99:b=256");
|
||||
|
||||
{
|
||||
DataSpec spec("foo:c=9:h=2:s=99:b=256");
|
||||
ImageSpec ispec(spec);
|
||||
assert(ispec.filename == "foo");
|
||||
assert(ispec.cylinders == 9);
|
||||
assert(ispec.heads == 2);
|
||||
assert(ispec.sectors == 99);
|
||||
assert(ispec.bytes = 256);
|
||||
assert(ispec.bytes == 256);
|
||||
assert(ispec.physicalOffset == 0);
|
||||
assert(ispec.physicalStep == 1);
|
||||
}
|
||||
|
||||
{
|
||||
DataSpec spec("foo:c=9:h=2:s=99:b=256:o=2:t=9");
|
||||
ImageSpec ispec(spec);
|
||||
assert(ispec.filename == "foo");
|
||||
assert(ispec.cylinders == 9);
|
||||
assert(ispec.heads == 2);
|
||||
assert(ispec.sectors == 99);
|
||||
assert(ispec.bytes == 256);
|
||||
assert(ispec.physicalOffset == 2);
|
||||
assert(ispec.physicalStep == 9);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user