Update documentation for the new version.

This commit is contained in:
David Given
2021-05-20 22:41:03 +02:00
parent be97791428
commit 25656d81a1
17 changed files with 293 additions and 380 deletions

View File

@@ -16,8 +16,8 @@ Tested ones are:
I expect the others to work, but haven't tried them; [get in I expect the others to work, but haven't tried them; [get in
touch](https://github.com/davidgiven/fluxengine/issues/new) if you have any touch](https://github.com/davidgiven/fluxengine/issues/new) if you have any
news. For ADFS S (single sided 40 track) you'll want `-s :s=0:t=0-79x2`. For news. For ADFS S (single sided 40 track) you'll want `--heads 0 --cylinders
ADFS M (single sided 80 track) you'll want `-s :s=0`. 0-79x2`. For ADFS M (single sided 80 track) you'll want `--heads 0`.
Be aware that Acorn logical block numbering goes all the way up side 0 and Be aware that Acorn logical block numbering goes all the way up side 0 and
then all the way up side 1. However, FluxEngine uses traditional disk images then all the way up side 1. However, FluxEngine uses traditional disk images
@@ -31,9 +31,9 @@ Reading discs
Just do: Just do:
``` ```
fluxengine read adfs fluxengine read acornadfs
``` ```
You should end up with an `adfs.img` of the appropriate size for your disk You should end up with an `acornadfs.img` of the appropriate size for your disk
format. This is an alias for `fluxengine read ibm` with preconfigured format. This is an alias for `fluxengine read ibm` with preconfigured
parameters. parameters.

View File

@@ -7,11 +7,12 @@ special here.
DFS disks are all single sided, but allow the other side of the disk to be DFS disks are all single sided, but allow the other side of the disk to be
used as another drive. FluxEngine supports these; read one side at a time used as another drive. FluxEngine supports these; read one side at a time
with `-s :s=0` or `-s :s=1`. with `--heads 0` or `--heads 1`.
DFS comes in two varieties, 40 track and 80 track. These should both work. DFS comes in two varieties, 40 track and 80 track. These should both work. For
For 40 track you'll want `-s :t=0-79x2`. Some rare disks are both at the same 40 track you'll want `--cylinders 0-79x2`. Some rare disks are both at the same
time. FluxEngine can read these. time. FluxEngine can read these but it requires a bit of fiddling as they have
the same tracks on twice.
Reading discs Reading discs
------------- -------------
@@ -19,9 +20,9 @@ Reading discs
Just do: Just do:
``` ```
fluxengine read dfs fluxengine read acorndfs
``` ```
You should end up with an `dfs.img` of the appropriate size for your disk You should end up with an `acorndfs.img` of the appropriate size for your disk
format. This is an alias for `fluxengine read ibm` with preconfigured format. This is an alias for `fluxengine read ibm` with preconfigured
parameters. parameters.

View File

@@ -36,6 +36,8 @@ Just do:
fluxengine read aeslanier fluxengine read aeslanier
``` ```
You'll end up with an `aeslanier.img` file.
Useful references Useful references
----------------- -----------------

View File

@@ -27,7 +27,7 @@ If you want the metadata as well, specify a 528 byte sector size for the
output image: output image:
``` ```
fluxengine read amiga -o amiga.adf:b=528 fluxengine read amiga -o amiga.adf --output.image.img.trackdata.sector_size=528
``` ```
You will end up with a 929280 byte long image which you probably _can't_ use You will end up with a 929280 byte long image which you probably _can't_ use
@@ -43,7 +43,7 @@ Just do:
fluxengine write amiga -i amiga.adf fluxengine write amiga -i amiga.adf
``` ```
This will rake a normal 901120 byte long ADF file and write it to a DD disk. This will take a normal 901120 byte long ADF file and write it to a DD disk.
Note that writing to an HD disk will probably not work (this will depend on Note that writing to an HD disk will probably not work (this will depend on
your drive and disk and potential FluxEngine bugs I'm still working on --- your drive and disk and potential FluxEngine bugs I'm still working on ---
please [get in touch](https://github.com/davidgiven/fluxengine/issues/new) if please [get in touch](https://github.com/davidgiven/fluxengine/issues/new) if
@@ -53,7 +53,7 @@ If you want to write the metadata as well, specify a 528 byte sector size for
the output image and supply a 929280 byte long file as described above. the output image and supply a 929280 byte long file as described above.
``` ```
fluxengine write amiga -i amiga.adf:b=528 fluxengine write amiga -i amiga.adf --input.image.img.trackdata.sector_size=528
``` ```
Useful references Useful references

View File

@@ -24,28 +24,26 @@ FluxEngine can also write Atari ST scheme disks.
The syntax is: The syntax is:
fluxengine write ibm -i input.st <options> fluxengine write <format> -i input.st
The format of `input.st` will vary depending on the kind of disk you're `<format>` can be one of these:
writing, which is configured by the options. You will almost certainly need to
pass one of these:
- `--ibm-preset-atarist-360`: a 360kB 3.5" disk, with 80 cylinders, 1 side, - `atarist360`: a 360kB 3.5" disk, with 80 cylinders, 1 side, and 9 sectors
and 9 sectors per track. per track.
- `--ibm-preset-atarist-370`: a 370kB 3.5" disk, with 82 cylinders, 1 side, - `atarist370`: a 370kB 3.5" disk, with 82 cylinders, 1 side, and 9 sectors
and 9 sectors per track. per track.
- `--ibm-preset-atarist-400`: a 400kB 3.5" disk, with 80 cylinders, 1 side, - `atarist400`: a 400kB 3.5" disk, with 80 cylinders, 1 side, and 10 sectors
and 10 sectors per track. per track.
- `--ibm-preset-atarist-410`: a 410kB 3.5" disk, with 82 cylinders, 1 side, - `atarist410`: a 410kB 3.5" disk, with 82 cylinders, 1 side, and 10 sectors
and 10 sectors per track. per track.
- `--ibm-preset-atarist-720`: a 720kB 3.5" disk, with 80 cylinders, 2 sides, - `atarist720`: a 720kB 3.5" disk, with 80 cylinders, 2 sides, and 9 sectors
and 9 sectors per track. per track.
- `--ibm-preset-atarist-740`: a 740kB 3.5" disk, with 82 cylinders, 2 sides, - `atarist740`: a 740kB 3.5" disk, with 82 cylinders, 2 sides, and 9 sectors
and 9 sectors per track. per track.
- `--ibm-preset-atarist-800`: a 800kB 3.5" disk, with 80 cylinders, 2 sides, - `atarist800`: a 800kB 3.5" disk, with 80 cylinders, 2 sides, and 10 sectors
and 10 sectors per track. per track.
- `--ibm-preset-atarist-820`: a 820kB 3.5" disk, with 82 cylinders, 2 sides, - `atarist820`: a 820kB 3.5" disk, with 82 cylinders, 2 sides, and 10 sectors
and 10 sectors per track. per track.
See [the IBM format documentation](disk-ibm.md) for more information. See [the IBM format documentation](disk-ibm.md) for more information.

View File

@@ -41,23 +41,19 @@ Just do:
fluxengine read brother fluxengine read brother
``` ```
You should end up with a `brother.img` which is 239616 bytes long. You should end up with a `brother.img` which is either 119808 or 239616 bytes
long.
Writing disks 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: Just do:
``` ```
fluxengine write brother fluxengine write `<format>` -i brother.img
``` ```
...and it'll write a `brother.img` file which is 239616 bytes long to the ...where `<format>` can be `brother120` or `brother240`.
disk. (Use `-i` to specify a different input filename.)
Dealing with misaligned disks Dealing with misaligned disks
----------------------------- -----------------------------

View File

@@ -55,10 +55,10 @@ fluxengine read ibm
Writing 1581 disks Writing 1581 disks
------------------ ------------------
These are handled by the IBM writer. Just do: Just do:
``` ```
fluxengine write ibm --ibm-preset-cbm1581 -i file.img fluxengine write commodore1581 -i file.img
``` ```
Useful references Useful references

View File

@@ -41,27 +41,28 @@ of the disk image will vary depending on the format.
Configuration options you'll want include: Configuration options you'll want include:
- `--ibm-sector-id-base=N`: specifies the ID of the first sector; this defaults - `--decoder.ibm.sector_id_base=N`: specifies the ID of the first sector;
to 1. Some formats (like the Acorn ones) start at 0. This can't be this defaults to 1. Some formats (like the Acorn ones) start at 0. This
autodetected because FluxEngine can't distinguish between a disk which can't be autodetected because FluxEngine can't distinguish between a disk
starts at sector 1 and a disk which starts at sector 0 but all the sector which starts at sector 1 and a disk which starts at sector 0 but all the
0s are missing. sector 0s are missing.
- `--ibm-ignore-side-byte=true|false`: each sector header describes the location of the - `--decoder.ibm.ignore_side_byte=true|false`: each sector header describes
sector: sector ID, track and side. Some formats use the wrong side ID, so the location of the sector: sector ID, track and side. Some formats use the
the sectors on side 1 are labelled as belonging to side 0. This causes wrong side ID, so the sectors on side 1 are labelled as belonging to side
FluxEngine to see duplicate sectors (as it can't distinguish between the 0. This causes FluxEngine to see duplicate sectors (as it can't distinguish
two sides). This option tells FluxEngine to ignore the side byte completely between the two sides). This option tells FluxEngine to ignore the side
and use the physical side instead. byte completely and use the physical side instead.
- `--ibm-required-sectors=range`: if you know how many sectors to expect per - `--decoder.ibm.required_sectors=range`: if you know how many sectors to
track, you can improve reads by telling FluxEngine what to expect here. If expect per track, you can improve reads by telling FluxEngine what to
a track is read and a sector on this list is _not_ present, then FluxEngine expect here. If a track is read and a sector on this list is _not_ present,
assumes the read failed and will retry. This avoids the situation where then FluxEngine assumes the read failed and will retry. This avoids the
FluxEngine can't tell the difference between a sector missing because it's situation where FluxEngine can't tell the difference between a sector
bad or a sector missing because it was never written in the first place. If missing because it's bad or a sector missing because it was never written
sectors are seen outside the range here, it will still be read. You can use in the first place. If sectors are seen outside the range here, it will
the same syntax as for track specifiers: e.g. `0-9`, `0,1,2,3`, etc. still be read. You can use the same syntax as for track specifiers: e.g.
`0-9`, `0,1,2,3`, etc.
Writing disks Writing disks
@@ -69,54 +70,15 @@ Writing disks
FluxEngine can also write IBM scheme disks. Unfortunately the format is FluxEngine can also write IBM scheme disks. Unfortunately the format is
incredibly flexible and you need to specify every single parameter, which incredibly flexible and you need to specify every single parameter, which
makes things slightly awkward. makes things slightly awkward. Preconfigured profiles are available.
The syntax is: The syntax is:
fluxengine write ibm -i input.img <options> fluxengine write <format> -i input.img <options>
The format of `input.img` will vary depending on the kind of disk you're The common PC formats are `ibm720` and `ibm1440`, but there are _many_ others,
writing, which is configured by the options. There are some presets, which and there's too many configuration options to usefully list. Try `fluxengine
you will almost certainly want to use if possible: write ibm1440 --config` to see a sample configuration.
- `--ibm-preset-720`: a standard 720kB DS DD 3.5" disk, with 80 cylinders,
2 sides, and 9 sectors per track.
- `--ibm-preset-1440`: a standard 1440kB DS HD 3.5" disk, with 80
cylinders, 2 sides, and 18 sectors per track.
These options simply preset the following, lower-level options. Note that
options are processed left to right, so it's possible to use a preset and
then change some settings. To see the values for a preset, simply append
`--help`.
- `--ibm-track-length-ms=N`: one disk rotation, in milliseconds. This is used
to determine whether all the data will fit on a track or not. `fluxengine
rpm` will tell you this; it'll be 200 for a normal 3.5" drive and 166 for a
normal 5.25" drive.
- `--ibm-sector-size=N`: the size of a sector, in bytes. Must be a power of
two.
- `--ibm-emit-iam=true|false`: whether to emit the IAM record at the top of
the track. The standard format requires it, but it's ignored by absolutely
everyone and you can fit a bit more data on the disk without it.
- `--ibm-start-sector-id=N`: the sector ID of the first sector. Normally 1,
except for non-standard formats like Acorn's, which use 0.
- `--ibm-use-fm=true|false`: uses FM rather than MFM.
- `--ibm-idam-byte=N`: the sixteen-bit raw bit pattern used for the IDAM ID
byte. Big-endian, clock bit first.
- `--ibm-dam-byte-N`: the sixteen-bit raw bit pattern used for the DAM ID
byte. Big-endian, clock bit first.
- `--ibm-gap0-bytes=N`: the size of gap 0 in bytes (between the start of
the track and the IAM record).
- `--ibm-gap1-bytes=N`: the size of gap 1 in bytes (between the IAM record
and the first sector record).
- `--ibm-gap2-bytes=N`: the size of gap 2 in bytes (between each sector
record and the data record).
- `--ibm-gap3-bytes=N`: the size of gap 3 in bytes (between the data record
and the next sector record).
- `--ibm-sector-skew=0123...`: a string representing the order in which to
write sectors: each character represents on sector, with `0` being the
first (always, regardless of `--ibm-start-sector-id` above). Sectors 10 and
above are represented as letters from `A` up.
Mixed-format disks Mixed-format disks
------------------ ------------------
@@ -127,26 +89,12 @@ FM encoded and will be read by the machine's ROM; those tracks contain new
floppy drive handling code capable of coping with MFM data, and so the rest of floppy drive handling code capable of coping with MFM data, and so the rest of
the disk will use that, allowing them to store more data. the disk will use that, allowing them to store more data.
FluxEngine copes with these fine, but the disk images are a bit weird. If track FluxEngine can read these fine, but it tends to get a bit confused when it sees
0 is FM and contains five sectors, but track 1 is MFM with nine sectors (MFM is tracks with differing numbers of sectors --- if track 0 has 32 sectors but
more efficient and the sectors are physically smaller, allowing you to get more track 1 has 16, it will assume that sectors 16..31 are missing on track 1 and
on), then the resulting image will have nine sectors per track... but track 0 size the image file accordingly. This can be worked around by specifying the
will only contain data in the first five. size of each track; see the `eco1` read profile for an example.
This is typically what you want as it makes locating the sectors in the image Writing can be made to work too, but there is currently no example. Please [get
easier, but emulators will typically require a different format. Please [get
in touch](https://github.com/davidgiven/fluxengine/issues/new) if you have in touch](https://github.com/davidgiven/fluxengine/issues/new) if you have
specific requirements (nothing's come up yet). Alternatively, you can tell specific requirements (nothing's come up yet).
FluxEngine to write a [`.ldbs`
file](http://www.seasip.info/Unix/LibDsk/ldbs.html) and then use
[libdsk](http://www.seasip.info/Unix/LibDsk/) to convert it to something
useful.
One easy option when reading these is to simply read the two sections of the
disk into two different image files.
FluxEngine can write these too, but in two different passes with different
options. It's possible to assemble a flux file by judicious use of `-D
something.flux --merge`, which can then be written in a single pass with
`fluxengine writeflux`, but it's usually not worth the bother: just write the
boot tracks, then write the data tracks, possibly with a script for automation.

View File

@@ -55,10 +55,10 @@ You should end up with a `mac.diskcopy` file which is compatible with DiskCopy
different sizes and the odd sector size. If you use a normal `.img` file, then different sizes and the odd sector size. If you use a normal `.img` file, then
FluxEngine will store them in a simple 524 x 12 x 2 x 80 layout, with holes FluxEngine will store them in a simple 524 x 12 x 2 x 80 layout, with holes
where missing sectors should be; this was easiest, but is unlikely to work with where missing sectors should be; this was easiest, but is unlikely to work with
most Mac emulators and other software. In these files, the 12 bytes of most Mac emulators and other software. In these files, the 12 bytes of metadata
metadata _follow_ the 512 bytes of user payload in the sector image. If you _follow_ the 512 bytes of user payload in the sector image. If you don't want
don't want it, specify a geometry in the output file with a 512-byte sectore it, specify that you want 512-byte sectors with
size like `-o mac.img:c=80:h=1:s=12:b=512`. `--output.image.img.trackdata.sector_size=512`.
Writing discs Writing discs
------------- -------------

View File

@@ -28,8 +28,8 @@ fluxengine read micropolis
You should end up with a `micropolis.img` which is 630784 bytes long (for a You should end up with a `micropolis.img` which is 630784 bytes long (for a
normal DD disk). The image is written in CHS order, but HCS is generally used normal DD disk). The image is written in CHS order, but HCS is generally used
by CP/M tools so the image needs to be post-processed. For only half-full disks by CP/M tools so the image needs to be post-processed. For only half-full disks
or single-sided disks, you can use `-s :s=0` to read only one side of the disk or single-sided disks, you can use `--heads 0` to read only one side of the
which works around the problem. disk which works around the problem.
The [CP/M BIOS](https://www.seasip.info/Cpm/bios.html) defined SELDSK, SETTRK, The [CP/M BIOS](https://www.seasip.info/Cpm/bios.html) defined SELDSK, SETTRK,
and SETSEC, but no function to select the head/side. Double-sided floppies and SETSEC, but no function to select the head/side. Double-sided floppies

View File

@@ -47,10 +47,10 @@ fluxengine read mx
You should end up with an `mx.img` which will vary in length depending on the format. The default is double-sided 80-track. For the other formats, use: You should end up with an `mx.img` which will vary in length depending on the format. The default is double-sided 80-track. For the other formats, use:
* single-sided 40-track: `-s :s=0:t=0-79x2` * single-sided 40-track: `--cylinders 0-79x2 --heads 0`
* double-sided 40-track: `-s :s=0-1:t=0-79x2` * double-sided 40-track: `--cylinders 0-79x2 --heads 0-1`
* single-sided 40-track: `-s :s=0:t=0-79` * single-sided 80-track: `--cylinders 0-79 --heads 0`
* double-sided 40-track: `-s :s=0-1:t=0-79` * double-sided 80-track: `--cylinders 0-79 --heads 0-1`
Useful references Useful references

View File

@@ -22,16 +22,16 @@ Reading discs
Just do: Just do:
``` ```
fluxengine read ibm fluxengine read ibm -o trs80.jv3
``` ```
You should end up with an `ibm.img` of the appropriate size. It's a simple You should end up with an `trs80.jv3` of the appropriate size. It's a simple
array of sectors in JV1 format. array of sectors in JV3 format.
If you've got a 40-track disk, use `-s :t=0-79x2`. If you've got a 40-track disk, use `--cylinders=0-79x2`.
If you've got a single density disk, use `--read-fm=true`. (Double density is If you've got a single density disk, use
the default.) `--decoder.ibm.trackdata.read_fm=true`. (Double density is the default.)
Useful references Useful references

View File

@@ -20,7 +20,7 @@ fluxengine read victor9k
``` ```
You should end up with an `victor9k.img` which is 774656 bytes long. You should end up with an `victor9k.img` which is 774656 bytes long.
if you want the double-sided variety, use `-s :s=0-1`. if you want the double-sided variety, use `--heads 0-1`.
**Big warning!** The image may not work in an emulator. Victor disk images are **Big warning!** The image may not work in an emulator. Victor disk images are
complicated due to the way the tracks are different sizes and the odd sector complicated due to the way the tracks are different sizes and the odd sector

View File

@@ -26,7 +26,7 @@ by writing a sequence of timed pulses to the disk, then reading them back and
seeing what the drive actually reports. To use it, do: seeing what the drive actually reports. To use it, do:
``` ```
fluxengine analyse driveresponse -d :d=1:t=0 \ fluxengine analyse driveresponse --cylinder 0 \
--min-interval-us=0 --max-interval-us=30 --interval-step-us=.1 \ --min-interval-us=0 --max-interval-us=30 --interval-step-us=.1 \
--write-img=driveresponse.png --write-img=driveresponse.png
``` ```

View File

@@ -33,7 +33,9 @@ Driver'. Once done, the GreaseWeazle will be visible to the FluxEngine client.
**Important note!** Unfortunately, now, the original GreaseWeazle client won't **Important note!** Unfortunately, now, the original GreaseWeazle client won't
work --- you can't use both drivers at once. I'm working on this. To switch work --- you can't use both drivers at once. I'm working on this. To switch
back to the original driver, for using the GreaseWeazle client software back to the original driver, for using the GreaseWeazle client software
instead, open up Zadig again, go through the same process, but make sure the left Driver box says `WinUSB` and the right one says `USB Serial (CDC)`. Now, when you press 'Replace Driver' the original driver will be restored. instead, open up Zadig again, go through the same process, but make sure the
left Driver box says `WinUSB` and the right one says `USB Serial (CDC)`. Now,
when you press 'Replace Driver' the original driver will be restored.
What works What works
---------- ----------

View File

@@ -84,7 +84,14 @@ example:
Bits are then found by measuring the interval between pulses on the disk and Bits are then found by measuring the interval between pulses on the disk and
comparing to this clock rate. comparing to this clock rate.
However, floppy disk drives are extremely analogue devices and not necessarily calibrated very well, and the disk may be warped, or the rubber band which makes the drive work may have lost its bandiness, and so the bits are not necessarily precisely aligned. Because of this, FluxEngine can tolerate a certain amount of error. This is controlled by the `--bit-error-threshold` parameter. Varying this can have magical effects. For example, adding `--bit-error-threshold=0.4` turns the decode into this: However, floppy disk drives are extremely analogue devices and not necessarily
calibrated very well, and the disk may be warped, or the rubber band which
makes the drive work may have lost its bandiness, and so the bits are not
necessarily precisely aligned. Because of this, FluxEngine can tolerate a
certain amount of error. This is controlled by the
`--decoder.bit_error_threshold` parameter. Varying this can have magical
effects. For example, adding `--decoder.bit_error_threshold=0.4` turns the
decode into this:
``` ```
H.SS Tracks ---> H.SS Tracks --->
@@ -124,9 +131,9 @@ can actually _increase_ the error rate --- which is why 0.4 isn't the default
That's the most common tuning parameter, but others are available: That's the most common tuning parameter, but others are available:
`--pulse-debounce-threshold` controls whether FluxEngine ignores pairs of pulses in rapid succession. This is common on some disks (I've observed them on Brother word processor disks). `--decoder.pulse_debounce_threshold` controls whether FluxEngine ignores pairs of pulses in rapid succession. This is common on some disks (I've observed them on Brother word processor disks).
`--clock-interval-bias` adds a constant bias to the intervals between pulses `--decoder.clock_interval_bias` adds a constant bias to the intervals between pulses
before doing decodes. This is very occasionally necessary to get clean reads before doing decodes. This is very occasionally necessary to get clean reads
--- for example, if the machine which wrote the disk always writes pulses --- for example, if the machine which wrote the disk always writes pulses
late. If you try this, use very small numbers (e.g. 0.02). Negative values late. If you try this, use very small numbers (e.g. 0.02). Negative values
@@ -145,7 +152,7 @@ of the pulse intervals on the disk. (Note that the tool only works on one
track at a time.) track at a time.)
``` ```
$ fluxengine inspect -s good.flux:t=0:s=0 $ fluxengine inspect -s good.flux -c 0 -h 0
Clock detection histogram: Clock detection histogram:
3.58 737 ▉ 3.58 737 ▉
3.67 3838 ████▊ 3.67 3838 ████▊
@@ -197,7 +204,7 @@ So, what does my Victor 9000 histogram look like? Let's look at the
histogram for a single track: histogram for a single track:
``` ```
$ fluxengine inspect -s dubious.flux:t=0:s=0 $ fluxengine inspect -s dubious.flux -c 0 -h 0
Clock detection histogram: Clock detection histogram:
1.33 1904 █▉ 1.33 1904 █▉
1.42 21669 ██████████████████████▌ 1.42 21669 ██████████████████████▌

View File

@@ -13,21 +13,28 @@ described below.
### Core concepts ### Core concepts
FluxEngine fundamentally takes file system images and puts them on disk; or FluxEngine's job is to read magnetic data (called _flux_) off a disk, decode
reads the disk and produces a file system image. it, and emit a filesystem image (called, er, an _image_); or, the other way
round, where an image is read, converted to flux, and written to a disk.
A file system image typically has the extension `.img`. It contains a A file system image typically has the extension `.img`. It contains a
sector-by-sector record of the _decoded_ data on the disk. For example, on a sector-by-sector record of the _decoded_ data on the disk. For example, on a
disk with 512 byte sectors, one sector will occupy 512 bytes. These are disk with 512 byte sectors, one sector will occupy 512 bytes. These are
typically what you want in everyday life. typically what you want in everyday life. FluxEngine supports a variety of file
system image formats, including
[LDBS](http://www.seasip.info/Unix/LibDsk/ldbs.html), Macintosh's [DiskCopy
4.2](https://en.wikipedia.org/wiki/Disk_Copy) and some others, including
Amiga's `.adf`, Atari ST's `.st`, and so on.
FluxEngine can also record the raw magnetic data on the disk into a file, which Flux, however, is different. It represents the actual magnetic data on the
we call a _flux file_. This contains all the low-level data which the drive disk. This has to be decoded before anything useful can be done with it (like
produced as the disk rotated. These are continuous streams of samples from the turning it into a file system image). It's possible to read the flux data off
disk and are completely useless in day-to-day life. FluxEngine uses its own the disk and write it to a file, known as a _flux file_, which allows you to
format for this, `.flux`, although it's capable of limited interchange with fiddle with the decode parameters without having to touch the disk again, which
Kryoflux, Supercard Pro and Catweasel files. A flux file will typically contain might be fragile. FluxEngine supports several different kinds of flux file,
from 80 to 150 kilobytes of data per track. including its own, SuperCard Pro's `.scp` format, and the Kryoflux stream
format. A flux file will typically contain from 80 to 150 kilobytes of data
per track.
In general, FluxEngine can use either a real disk or a flux file In general, FluxEngine can use either a real disk or a flux file
interchangeably: you can specify either at (very nearly) any time. A very interchangeably: you can specify either at (very nearly) any time. A very
@@ -40,152 +47,190 @@ To use, simply plug your FluxEngine into your computer and run the client. If a
single device is plugged in, it will be automatically detected and used. single device is plugged in, it will be automatically detected and used.
If _more_ than one device is plugged in, you need to specify which one to use If _more_ than one device is plugged in, you need to specify which one to use
with the `--device` parameter, which takes the device serial number as a with the `--usb.device` parameter, which takes the device serial number as a
parameter. You can find out the serial numbers by running the command without parameter. You can find out the serial numbers by running the command without
the `--device` parameter, and if more than one device is attached they will be the `--usb.device` parameter, and if more than one device is attached they will
listed. The serial number is also shown whenever a connection is made. be listed. The serial number is also shown whenever a connection is made.
You _can_ work with more than one FluxEngine at the same time, using different 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 invocations of the client; but be careful of USB bandwidth. If the devices are
connected via the same hub, the bandwidth will be shared. connected via the same hub, the bandwidth will be shared.
### Logical and physical tracks ### Basic use
In general, FluxEngine will read one track off disk, and write it to one track The FluxEngine client is a command line program. As parameters it takes one or
in a file, or vice versa. Sometimes these don't match. Two important FluxEngine more words telling it what to do, and then a bunch of configuration options.
concepts are that of the _physical track_ and the _logical track_. Configurations can be specified either on the command line or in text files.
_Physical tracks_ are how FluxEngine locates tracks on the disk. The numbering Here are some sample invocations:
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
file), use the `--source` (`-s`) and `--dest` (`-d`) options to tell FluxEngine
which bits of the disk you want to access. These use a common syntax:
``` ```
fluxengine read ibm -s fakedisk.flux:t=0-79:s=0 # Read an PC disk, producing a disk image with the default name (ibm.img),
# autodetecting all parameters
$ fluxengine read ibm
# Write a PC 1440kB disk to drive 1
$ fluxengine write ibm -i image.img -d drive:1
# Read a Eco1 CP/M disk, making a copy of the flux into a file
$ fluxengine read eco1 --copy-flux-to copy.flux -o eco1.ldbs
# Rerun the decode from the flux file, tweaking the parameters
$ fluxengine read eco1 -s copy.flux -o eco1.ldbs --cylinders=1
``` ```
- To access a real disk, leave out the filename (so `:t=0-79:s=0`). ### Configuration
- To access only some tracks, use the `t=` modifier. To access only some Configuration options are reperesented as a hierarchical structure. You can
sides, use the `s=` modifier. either put them in a text file and load them from the command line:
- Inside a modifier, you can use a comma separated list of ranges. So ```
`:t=0-3` and `:t=0,1,2,3` are equivalent. $ cat config.textpb
encoder {
ibm {
trackdata {
emit_iam: false
}
}
}
$ fluxengine write ibm1440 config.textpb -i image.img
```
- When specifying a range, you can also specify the step. For example, ...or you can specify them on the command line:
`:t=0-79x2` would be used when accessing a 40-track disk with double
stepping.
- To read from drive 1 instead of drive 0, use `:d=1`. ```
$ fluxengine write ibm1440 -i image.img --encoder.ibm.trackdata.emit_iam=false
```
- To read from a set of KryoFlux stream files, specify the path to the Both the above invocations are equivalent. The text files use [Google's
directory containing the files _with a trailing slash_; so protobuf syntax](https://developers.google.com/protocol-buffers), which is
`some/files/:t=0-10`. There must be a files for a single disk only hierarchical, type-safe, and easy to read.
in the directory.
Source and destination specifiers work entirely in *physical units*. As The `ibm1440` string above is actually a reference to an internal configuration
described above, FluxEngine is intended to be connected to an 80 (or 82) track file containing all the settings for writing PC 1440kB disks. You can see all
double sided drive, and these are the units used. If the format you're trying these settings by doing:
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. $ fluxengine write ibm1440 --config
```
**Important note:** FluxEngine _always_ uses zero-based units (even if the The `--config` option will cause the current configuration to be dumped to the
disk format says otherwise). console, and then the program will halt.
### Input and output specifiers Going into the details of the configuration is complicated and mostly futile as
it's likely to change as things get modified. Brief but up-to-date information
about each configuration setting is available with the `--doc` option. Note
that not all combinations of settings make sense.
When reading or writing _file system images_, use the `--input` (`-i`) and ### The tools
`--output` (`-o`) options to specify the file and file format. These use a very
similar syntax to the source and destination specifiers (because they're based
on the same microformat library!) but with different specifiers. Also, the
exact format varies according to the extension:
- `.img` or `.adf`: raw sector images in CHS order. Append The FluxEngine program has got multiple sub-tools, each of which performs a
`:c=80:h=2:s=9:b=512` to set the geometry; that specifies 80 cylinders, 2 different task. Run each one with `--help` to get a full list of
heads, 9 sectors, 512 bytes per sector. For output files (`--output`) the (non-configuration-setting) options; this describes only basic usage of the
geometry will be autodetected if left unspecified. For input files you more common tools.
normally have to specify it.
If one logical track does not map directly onto on physical track, you can - `fluxengine read <profile> -s <flux source> -o <image output>``
change this with `:o=1:t=2`: `o` specifies the offset, and `t` specifies Reads flux (possibly from a disk) and decodes it into a file system
the step. So, with this format, cylinder 1 in the image will be written to image. `<profile>` is a reference to an internal input configuration file
track 3 on the disk. describing the format.
- `.ldbs`: John Elliott's [LDBS disk image - `fluxengine write <profile> -i <image input> -d <flux destination>`
format](http://www.seasip.info/Unix/LibDsk/ldbs.html), which is Reads a filesystem image and encodes it into flux (possibly writing to a
consumable by the [libdsk](http://www.seasip.info/Unix/LibDsk/) suite of disk). `<profile>` is a reference to an internal output configuration file
tools. This allows things like variable numbers of sectors per track describing the format.
(e.g. Macintosh or Commodore 64) and also provides information about
whether sectors were read correctly. You can use libdsk to convert this
to other formats, using a command like this:
``` - `fluxengine rawread -s <flux source> -d <flux destination>`
$ dsktrans out.ldbs -otype tele out.td0 Reads flux (possibly from a disk) and writes it to a flux file without
``` doing any decoding. You can specify a profile if you want to read a subset
of the disk.
...to convert to TeleDisk format. (Note you have to use dsktrans rather - `fluxengine rawwrite -s <flux source> -d <flux destination>`
than dskconv due to a minor bug in the geometry hadnling.) Reads flux from a file and writes it (possibly to a disk) without doing any
encoding. You can specify a profile if you want to write a subset of the
disk.
FluxEngine's LDBS support is currently limited to write only, and - `fluxengine rpm`
it doesn't store a lot of the more esoteric LDBS features like format Measures the rotation speed of a drive. For hard-sectored disks, you
types, timings, and data rates. probably want to add the name of a read profile to configure the number of
sectors.
- `.d64`: the venerable Commodore 64 disk image format as used by the 1540, - `fluxengine seek -c <cylinder>`
1541, etc. This is a special-purpose format due to the weird layout of Seeks a drive to a particular cylinder.
1540 disks and while you can use this for non-Commodore disks the result
will be gibberish. Use this to image Commodore 64 disks and load the
result into an emulator.
FluxEngine's D64 support is currently limited to write only. It will work There are other tools; try `fluxengine --help`.
with up to 40 logical tracks.
- `.diskcopy`: a Macintosh DiskCopy 4.2 file. This is a special-purpose **Important note on `rawread` and `rawwrite`:** You can't use these tools to
format due to the weird layout of Mac GCR disks, but it can also support copy disks, in most circumstances. See [the FAQ](faq.md) for more information.
720kB and 1440kB IBM disks (although there's no real benefit). Also, `rawread` is not guaranteed to read correctly. Floppy disks are
fundamentally unreliable, and random bit errors may occur at any time; these
can only be detected by performing a decode and verifying the checksums on the
sectors. To perform a correct read, it's recommended to do `fluxengine read`
with the `--copy-flux-to` option, to perform a decode to a filesystem image
while also writing to a flux file.
- `.jv3`: a disk image format mainly used by the TRS-80. These images can be ### Flux sources and destinations
read, but not yet written. You only get the data; the density and DAM bits
are ignored.
- `.imd`: a disk image format created by [David Dunfield](http://dunfield.classiccmp.org/img/index.htm). FluxEngine supports a number of ways to get or put flux. When using the `-s` or
These images can be read, but not yet written. The stored comment will also `-d` options (for source and destination), you can use any of these strings:
be shown on read. The geometry in the file will be used.
- `drive:<n>` Read from or write to a specific drive.
- `<filename.flux>` Read from or write to a native FluxEngine flux file.
- `<filename.scp>` Read from or write to a Supercard Pro `.scp` flux file.
- `<filename.cwf>` Read from a Catweasel flux file. **Read only.**
- `kryoflux:<directory>` Read from a Kryoflux stream, where `<path>` is the
directory containing the stream files. **Read only.**
- `erase:` Read nothing --- writing this to a disk will magnetically erase
a track. **Read only.**
- `testpattern:` Read a test pattern, which can be written to a disk to
help diagnosis. **Read only.**
- `au:<directory>` Write to a series of `.au` files, one file per track,
which can be loaded into an audio editor (such as Audacity) as a simple
logic analyser. **Write only.**
- `vcd:<directory>` Write to a series of `.vcd` files, one file per track,
which can be loaded into a logic analyser (such as Pulseview) for
analysis. **Write only.**
### Image sources and destinations
FluxEngine also supports a number of file system image formats. When using the
`-i` or `-o` options (for input and output), you can use any of these strings:
- `<filename.adf>`, `<filename.d81>`, `<filename.img>`, `<filename.st>`
Read from or write to a simple headerless image file (all these formats
are the same). This will probably want configuration via the
`input/output.image.img.*` configuration settings to specify all the
parameters.
- `<filename.diskcopy>` Read from or write to a [DiskCopy
4.2](https://en.wikipedia.org/wiki/Disk_Copy) image file, commonly used
by Apple Macintosh emulators.
- `<filename.jv3>` Read from a JV3 image file, commonly used by TRS-80
emulators. **Read only.**
- `<filename.ldbs>` Write to a [LDBS generic image
file](https://www.seasip.info/Unix/LibDsk/ldbs.html). **Write only.**
- `<filename.d64>` Write to a [D64 image
file](http://unusedino.de/ec64/technical/formats/d64.html), commonly used
by Commodore 64 emulators. **Write only.**
### High density disks ### High density disks
High density disks use a different magnetic medium to low and double density High density disks use a different magnetic medium to low and double density
disks, and have different magnetic properties. 3.5" drives can usually 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 autodetect what kind of medium is inserted into the drive based on the hole in
in the disk casing, but 5.25" drives can't. As a result, you need to the disk casing, but 5.25" drives can't. As a result, you need to explicitly
explicitly tell FluxEngine on the command line whether you're using a high tell FluxEngine on the command line whether you're using a high density disk or
density disk or not with the `-H` flag. not with the `--input/output.flux.drive.high_density` configuration setting.
**If you don't do this, your disks may not read correctly and will _certainly_ **If you don't do this, your disks may not read correctly and will _certainly_
fail to write correctly.** fail to write correctly.**
@@ -197,125 +242,38 @@ case, and reading the disk label is much more reliable.
[Lots more information on high density vs double density disks can be found [Lots more information on high density vs double density disks can be found
here.](http://www.retrotechnology.com/herbs_stuff/guzis.html) 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 ### Other important flags
These flags apply to many operations and are useful for modifying the overall These flags apply to many operations and are useful for modifying the overall
behaviour. behaviour.
- `--revolutions=X`: when reading, spin the disk X times. X can be a floating - `--input.flux.drive.revolutions=X`: when reading, spin the disk X times. X
point number. The default is usually 1.25. Some formats default to 1. can be a floating point number. The default is usually 1.2. Some formats
Increasing the number will sample more data, and can be useful on dubious default to 1. Increasing the number will sample more data, and can be
disks to try and get a better read. useful on dubious disks to try and get a better read.
- `--sync-with-index=true|false`: wait for an index pulse before starting to - `--input.flux.drive.sync_with_index=true|false`: wait for an index pulse
read the disk. (Ignored for write operations.) By default FluxEngine before starting to read the disk. (Ignored for write operations.) By
doesn't, as it makes reads faster, but when diagnosing disk problems it's default FluxEngine doesn't, as it makes reads faster, but when diagnosing
helpful to have all your data start at the same place each time. disk problems it's helpful to have all your data start at the same place
each time.
- `--index-source=X`, `--write-index-source=X`: set the source of index - `--input.flux.drive.index_source=X`, `--output.flux.drive.index_source=X`:
pulses when reading or writing respectively. This is for use with drives set the source of index pulses when reading or writing respectively. This
which don't produce index pulse data. Use 0 to get index pulses from the is for use with drives which don't produce index pulse data. `X` can be
drive, 1 to fake 300RPM pulses, or 2 to fake 360RPM pulses. Note this has `INDEXMODE_DRIVE` to get index pulses from the drive, `INDEXMODE_300` to
no effect on the _drive_, so it doesn't help with flippy disks, but is fake 300RPM pulses, or `INDEXMODE_360` to fake 360RPM pulses. Note this
has no effect on the _drive_, so it doesn't help with flippy disks, but is
useful for using very old drives with FluxEngine itself. If you use this useful for using very old drives with FluxEngine itself. If you use this
option, then any index marks in the sampled flux are, of course, garbage. option, then any index marks in the sampled flux are, of course, garbage.
### The commands
The FluxEngine client software is a largely undocumented set of small tools.
You'll have to play with them. They all support `--help`. They're not
installed anywhere and after building you'll find them in the `.obj`
directory.
- `fluxengine erase`: wipes (all or part of) a disk --- erases it without
writing a pulsetrain.
- `fluxengine inspect`: dumps the raw pulsetrain / bitstream to stdout.
Mainly useful for debugging.
- `fluxengine read *`: reads various formats of disk. See the per-format
documentation linked from the table [in the index page](../README.md).
These all take an optional `--write-flux` option which will cause the raw
flux to be written to the specified file as well as the normal decode.
There are various `--dump` options for showing raw data during the decode
process, and `--write-csv` will write a copious CSV report of the state of
every sector in the file in machine-readable format.
- `fluxengine write *`: writes various formats of disk. Again, see the
per-format documentation [in the index page](../README.md).
- `fluxengine writeflux`: writes raw flux files. This is much less useful
than you might think: you can't reliably write flux files read from a disk
to another disk. (See the [FAQ](faq.md) for more information.) It's mainly
useful for flux files synthesised by the other `fluxengine write` commands.
- `fluxengine writetestpattern`: writes regular pulses (at a configurable
interval) to the disk. Useful for testing drive jitter, erasing disks in a
more secure fashion, or simply debugging. Goes well with `fluxengine
inspect`.
- `fluxengine rpm`: measures the RPM of the drive (requires a disk in the
drive). Mainly useful for testing.
- `fluxengine seek`: moves the head. Mainly useful for finding out whether
your drive can seek to track 82. (Mine can't.)
- `fluxengine test bandwidth`: measures your USB throughput. You don't need
a disk in the drive for this one.
- `fluxengine test voltages`: measures your FDD bus signal voltages, which is
useful for testing for termination issues.
- `fluxengine upgradefluxfile`: occasionally I need to upgrade the flux file
format in a non-backwards-compatible way; this tool will upgrade flux files
to the new format.
- `fluxengine convert`: converts files from various formats to various other
formats. The main use of this is probably `fluxengine convert image`, which
will convert a disk image from one format to another.
There are also subcommands for converting Catweasel flux files to
FluxEngine's native format, FluxEngine flux files to various other formats
useful for debugging (including VCD which can be loaded into
[sigrok](http://sigrok.org)), and bidirectional conversion to and from
Supercard Pro `.scp` format.
Commands which normally take `--source` or `--dest` get a sensible default if
left unspecified. `fluxengine read ibm` on its own will read drive 0 and
write an `ibm.img` file.
## Visualisation ## Visualisation
When doing a read (either from a real disk or from a flux file) you can use When using `fluxengined read` (either from a real disk or from a flux file) you
`--write-csv=output.csv` to write out CSV file containing information about the can use `--decoder.write_csv_to=output.csv` to write out a CSV file containing
location of every sector on the disk. You can then use `fluxengine analyse information about the location of every sector on the disk. You can then use
layout` to produce a graphical visualisation of this. Here's a IBM PC 1232kB `fluxengine analyse layout` to produce a graphical visualisation of this.
disk: Here's a IBM PC 1232kB disk:
![A disk visualisation](./visualiser.jpg) ![A disk visualisation](./visualiser.jpg)
@@ -343,16 +301,17 @@ containing valuable historical data, and you want to read them.
Typically I do this: Typically I do this:
``` ```
$ fluxengine read brother -s :d=0 -o brother.img --write-flux=brother.flux --overwrite --write-csv=brother.csv $ fluxengine read brother -s drive:0 -o brother.img --copy-flux-to=brother.flux --decoder.write_csv_to=brother.csv
``` ```
This will read the disk in drive 0 and write out an information CSV file. It'll This will read the disk in drive 0 and write out an information CSV file. It'll
also copy the flux to `brother.flux` (replacing any old one) and write out an also copy the flux to `brother.flux` (replacing any old one) and write out a
SVG visualisation. If I then need to tweak the settings, I can rerun the decode CSV file for used when making a visualisation. If I then need to tweak the
without having to physically touch the disk like this: settings, I can rerun the decode without having to physically touch the disk
like this:
``` ```
$ fluxengine read brother -s brother.flux -o brother.img --write-svg=brother.svg $ fluxengine read brother -s brother.flux -o brother.img --decoder.write_csv_to=brother.csv
``` ```
Apart from being drastically faster, this avoids touching the (potentially Apart from being drastically faster, this avoids touching the (potentially