mirror of
https://github.com/davidgiven/fluxengine.git
synced 2025-10-31 11:17:01 -07:00
Merge pull request #667 from davidgiven/options
Overhaul the options system.
This commit is contained in:
54
Makefile
54
Makefile
@@ -177,38 +177,40 @@ endef
|
||||
|
||||
$(call do-encodedecodetest,agat840)
|
||||
$(call do-encodedecodetest,amiga)
|
||||
$(call do-encodedecodetest,appleii140)
|
||||
$(call do-encodedecodetest,atarist360)
|
||||
$(call do-encodedecodetest,atarist370)
|
||||
$(call do-encodedecodetest,atarist400)
|
||||
$(call do-encodedecodetest,atarist410)
|
||||
$(call do-encodedecodetest,atarist720)
|
||||
$(call do-encodedecodetest,atarist740)
|
||||
$(call do-encodedecodetest,atarist800)
|
||||
$(call do-encodedecodetest,atarist820)
|
||||
$(call do-encodedecodetest,apple2,,--140)
|
||||
$(call do-encodedecodetest,atarist,,--360)
|
||||
$(call do-encodedecodetest,atarist,,--370)
|
||||
$(call do-encodedecodetest,atarist,,--400)
|
||||
$(call do-encodedecodetest,atarist,,--410)
|
||||
$(call do-encodedecodetest,atarist,,--720)
|
||||
$(call do-encodedecodetest,atarist,,--740)
|
||||
$(call do-encodedecodetest,atarist,,--800)
|
||||
$(call do-encodedecodetest,atarist,,--820)
|
||||
$(call do-encodedecodetest,bk800)
|
||||
$(call do-encodedecodetest,brother120)
|
||||
$(call do-encodedecodetest,brother240)
|
||||
$(call do-encodedecodetest,commodore1541,scripts/commodore1541_test.textpb,--35)
|
||||
$(call do-encodedecodetest,commodore1541,scripts/commodore1541_test.textpb,--40)
|
||||
$(call do-encodedecodetest,brother,,--120)
|
||||
$(call do-encodedecodetest,brother,,--240)
|
||||
$(call do-encodedecodetest,commodore1541,scripts/commodore1541_test.textpb,--171)
|
||||
$(call do-encodedecodetest,commodore1541,scripts/commodore1541_test.textpb,--192)
|
||||
$(call do-encodedecodetest,commodore1581)
|
||||
$(call do-encodedecodetest,cmd_fd2000)
|
||||
$(call do-encodedecodetest,hp9121)
|
||||
$(call do-encodedecodetest,ibm1200)
|
||||
$(call do-encodedecodetest,ibm1232)
|
||||
$(call do-encodedecodetest,ibm1440)
|
||||
$(call do-encodedecodetest,ibm180)
|
||||
$(call do-encodedecodetest,ibm160)
|
||||
$(call do-encodedecodetest,ibm320)
|
||||
$(call do-encodedecodetest,ibm360)
|
||||
$(call do-encodedecodetest,ibm720)
|
||||
$(call do-encodedecodetest,mac400,scripts/mac400_test.textpb)
|
||||
$(call do-encodedecodetest,mac800,scripts/mac800_test.textpb)
|
||||
$(call do-encodedecodetest,hplif,,--264)
|
||||
$(call do-encodedecodetest,hplif,,--616)
|
||||
$(call do-encodedecodetest,hplif,,--770)
|
||||
$(call do-encodedecodetest,ibm,,--1200)
|
||||
$(call do-encodedecodetest,ibm,,--1232)
|
||||
$(call do-encodedecodetest,ibm,,--1440)
|
||||
$(call do-encodedecodetest,ibm,,--180)
|
||||
$(call do-encodedecodetest,ibm,,--160)
|
||||
$(call do-encodedecodetest,ibm,,--320)
|
||||
$(call do-encodedecodetest,ibm,,--360)
|
||||
$(call do-encodedecodetest,ibm,,--720)
|
||||
$(call do-encodedecodetest,mac,scripts/mac400_test.textpb,--400)
|
||||
$(call do-encodedecodetest,mac,scripts/mac800_test.textpb,--800)
|
||||
$(call do-encodedecodetest,n88basic)
|
||||
$(call do-encodedecodetest,rx50)
|
||||
$(call do-encodedecodetest,tids990)
|
||||
$(call do-encodedecodetest,victor9k_ss)
|
||||
$(call do-encodedecodetest,victor9k_ds)
|
||||
$(call do-encodedecodetest,victor9k,,--612)
|
||||
$(call do-encodedecodetest,victor9k,,--1224)
|
||||
|
||||
$(OBJDIR)/%.a:
|
||||
@mkdir -p $(dir $@)
|
||||
|
||||
@@ -19,13 +19,15 @@ Reading discs
|
||||
Just do:
|
||||
|
||||
```
|
||||
fluxengine read ampro400
|
||||
fluxengine read ampro <format>
|
||||
```
|
||||
|
||||
You should end up with an `ampro.img` which is 409600. If you have a
|
||||
double-sided disk, use `ampro800`, which will give you a file819200 bytes long.
|
||||
These is an alias for `fluxengine read ibm` with preconfigured parameters. You
|
||||
can pass this straight into [cpmtools](http://www.moria.de/~michael/cpmtools/):
|
||||
...where `<format>` is one of `--400` for a 40-track disk or `--800` for an
|
||||
80-track disk. These are an alias for `fluxengine read ibm` with preconfigured
|
||||
parameters.
|
||||
|
||||
FluxEngine has direct filesystem support for these disks, or you can pass the
|
||||
disk images into [cpmtools](http://www.moria.de/~michael/cpmtools/):
|
||||
|
||||
```
|
||||
$ cpmls -f ampdsdd ampro.img
|
||||
|
||||
@@ -30,7 +30,8 @@ FluxEngine can remap the sectors from physical to logical using modifiers. If
|
||||
you don't specify a remapping modifier, you get the sectors in the order they
|
||||
appear on the disk.
|
||||
|
||||
If you don't want an image in physical sector order, specify one of these options:
|
||||
If you don't want an image in physical sector order, specify one of these
|
||||
options:
|
||||
|
||||
- `--appledos` Selects AppleDOS sector translation
|
||||
- `--prodos` Selects ProDOS sector translation
|
||||
@@ -40,15 +41,21 @@ These options also select the appropriate file system; FluxEngine has read-only
|
||||
support for all of these. For example:
|
||||
|
||||
```
|
||||
fluxengine ls appleii140 --appledos -f image.flux
|
||||
fluxengine ls apple2 --appledos -f image.flux
|
||||
```
|
||||
|
||||
In addition, some third-party systems use 80-track double sides drives, with
|
||||
the same underlying disk format. These are supported with the `appleii640`
|
||||
profile. The complication here is that the AppleDOS filesystem only supports up
|
||||
the same underlying disk format. The full list of formats supported is:
|
||||
|
||||
- `--140` 35-track single-sided (the normal Apple II format)
|
||||
- `--640` 80-track double-sided
|
||||
|
||||
`--140` is the default.
|
||||
|
||||
The complication here is that the AppleDOS filesystem only supports up
|
||||
to 50 tracks, so it needs tweaking to support larger disks. It treats the
|
||||
second side of the disk as a completely different volume. To access these
|
||||
files, use `--appledos --side1`.
|
||||
files, use `--640 --appledos --side1`.
|
||||
|
||||
[^1]: CP/M disks use the ProDOS translation for the first three tracks and a
|
||||
different translation for all the tracks thereafter.
|
||||
@@ -65,12 +72,12 @@ Reading discs
|
||||
Just do:
|
||||
|
||||
```
|
||||
fluxengine read appleii140
|
||||
fluxengine read apple2
|
||||
```
|
||||
|
||||
(or `appleii640`)
|
||||
(or `apple2 --640`)
|
||||
|
||||
You should end up with an `appleii140.img` which is 143360 bytes long. It will
|
||||
You should end up with an `apple2.img` which is 143360 bytes long. It will
|
||||
be in physical sector ordering if you don't specify a file system format as
|
||||
described above.
|
||||
|
||||
@@ -79,7 +86,7 @@ Writing discs
|
||||
|
||||
Just do:
|
||||
```
|
||||
fluxengine write appleii140 -i appleii140.img
|
||||
fluxengine write apple2 -i apple2.img
|
||||
```
|
||||
|
||||
The image will be expected to be in physical sector ordering if you don't
|
||||
|
||||
@@ -33,29 +33,29 @@ FluxEngine can also write Atari ST scheme disks.
|
||||
|
||||
The syntax is:
|
||||
|
||||
fluxengine write <format> -i input.st
|
||||
fluxengine write atarist -i input.st <format>
|
||||
|
||||
Available formats
|
||||
-----------------
|
||||
|
||||
`<format>` can be one of these:
|
||||
|
||||
- `atarist360`: a 360kB 3.5" disk, with 80 cylinders, 1 side, and 9 sectors
|
||||
per track.
|
||||
- `atarist370`: a 370kB 3.5" disk, with 82 cylinders, 1 side, and 9 sectors
|
||||
per track.
|
||||
- `atarist400`: a 400kB 3.5" disk, with 80 cylinders, 1 side, and 10 sectors
|
||||
per track.
|
||||
- `atarist410`: a 410kB 3.5" disk, with 82 cylinders, 1 side, and 10 sectors
|
||||
per track.
|
||||
- `atarist720`: a 720kB 3.5" disk, with 80 cylinders, 2 sides, and 9 sectors
|
||||
per track.
|
||||
- `atarist740`: a 740kB 3.5" disk, with 82 cylinders, 2 sides, and 9 sectors
|
||||
per track.
|
||||
- `atarist800`: a 800kB 3.5" disk, with 80 cylinders, 2 sides, and 10 sectors
|
||||
per track.
|
||||
- `atarist820`: a 820kB 3.5" disk, with 82 cylinders, 2 sides, and 10 sectors
|
||||
per track.
|
||||
- `--360`: a 360kB 3.5" disk, with 80 cylinders, 1 side, and 9 sectors per
|
||||
track.
|
||||
- `--370`: a 370kB 3.5" disk, with 82 cylinders, 1 side, and 9 sectors per
|
||||
track.
|
||||
- `--400`: a 400kB 3.5" disk, with 80 cylinders, 1 side, and 10 sectors per
|
||||
track.
|
||||
- `--410`: a 410kB 3.5" disk, with 82 cylinders, 1 side, and 10 sectors per
|
||||
track.
|
||||
- `--720`: a 720kB 3.5" disk, with 80 cylinders, 2 sides, and 9 sectors per
|
||||
track.
|
||||
- `--740`: a 740kB 3.5" disk, with 82 cylinders, 2 sides, and 9 sectors per
|
||||
track.
|
||||
- `--800`: a 800kB 3.5" disk, with 80 cylinders, 2 sides, and 10 sectors per
|
||||
track.
|
||||
- `--820`: a 820kB 3.5" disk, with 82 cylinders, 2 sides, and 10 sectors per
|
||||
track.
|
||||
|
||||
See [the IBM format documentation](disk-ibm.md) for more information. Note that
|
||||
only some PC 3.5" floppy disk drives are capable of seeking to the 82nd track.
|
||||
|
||||
@@ -38,10 +38,10 @@ Reading disks
|
||||
Just do:
|
||||
|
||||
```
|
||||
fluxengine read `<format>`
|
||||
fluxengine read brother `<format>`
|
||||
```
|
||||
|
||||
... where `<format>` can be `brother120` or `brother240`. You should end up
|
||||
... where `<format>` can be `--120` or `--240`. You should end up
|
||||
with a `brother.img` which is either 119808 or 239616 bytes long.
|
||||
|
||||
Writing disks
|
||||
@@ -53,7 +53,7 @@ Just do:
|
||||
fluxengine write `<format>` -i brother.img
|
||||
```
|
||||
|
||||
...where `<format>` can be `brother120` or `brother240`.
|
||||
...where `<format>` can be `--120` or `--240`.
|
||||
|
||||
Dealing with misaligned disks
|
||||
-----------------------------
|
||||
@@ -102,7 +102,8 @@ record.) The sector order is 05a3816b4927, which gives a sector skew of 5.
|
||||
High level format
|
||||
-----------------
|
||||
|
||||
Once decoded, you end up with a file system image.
|
||||
Once decoded, you end up with a file system image. FluxEngine supports direct
|
||||
filesystem access for both kinds of disks.
|
||||
|
||||
### 120kB disks
|
||||
|
||||
|
||||
@@ -33,29 +33,28 @@ Reading 1541 disks
|
||||
Just do:
|
||||
|
||||
```
|
||||
fluxengine read commodore1541 -o commodore1541.d64
|
||||
fluxengine read commodore -o commodore.d64
|
||||
```
|
||||
|
||||
You should end up with an `commodore1541.d64` file which is 174848 bytes long.
|
||||
You should end up with an `commodore.d64` file which is 174848 bytes long.
|
||||
You can load this straight into a Commodore 64 emulator such as
|
||||
[VICE](http://vice-emu.sourceforge.net/).
|
||||
|
||||
If you have a 40-track disk, add `--40`.
|
||||
If you have a 40-track disk, add `--196`.
|
||||
|
||||
**Big warning!** Commodore 64 disk images are complicated due to the way the
|
||||
tracks are different sizes and the odd sector size, so you need the special D64
|
||||
or LDBS output formats to represent them sensibly. Don't use IMG unless you
|
||||
know what you're doing.
|
||||
or LDBS output formats to represent them sensibly.
|
||||
|
||||
Writing 1541 disks
|
||||
------------------
|
||||
|
||||
Just do:
|
||||
```
|
||||
fluxengine write commodore1541 -i file.d64
|
||||
fluxengine write commodore -i file.d64
|
||||
```
|
||||
|
||||
If you have a 40-track disk, add `--40`.
|
||||
If you have a 40-track disk, add `--196`.
|
||||
|
||||
Note that only standard Commodore 64 BAM file systems can be written this way,
|
||||
as the disk ID in the BAM has to be copied to every sector on the disk.
|
||||
|
||||
@@ -38,15 +38,16 @@ Reading disks
|
||||
|
||||
Just do:
|
||||
|
||||
fluxengine read `<format>`
|
||||
fluxengine read ibm `<format>`
|
||||
|
||||
...and you'll end up with a `<format>.img` file. This should work on most PC
|
||||
disks (including FM 360kB disks, 3.5" 1440kB disks, 5.25" 1200kB disks, etc.)
|
||||
The size of the disk image will vary depending on the format.
|
||||
...and you'll end up with an `ibm.img` file. You'll need to specify which
|
||||
format to use; this can be one of `--160`, `--180`, `--320`, `--360`, `--720`,
|
||||
`--1200`, `--1232` or `--1400` depending. The size of the disk image will vary
|
||||
depending on the format.
|
||||
|
||||
The common PC formats are `ibm720` and `ibm1440`, but there are _many_ others,
|
||||
The common PC formats are `--720` and `--1440`, but there are _many_ others,
|
||||
and there's too many configuration options to usefully list. Use `fluxengine
|
||||
write` to list all formats, and try `fluxengine write ibm1440 --config` to see
|
||||
write` to list all formats, and try `fluxengine write ibm --1440 --config` to see
|
||||
a sample configuration.
|
||||
|
||||
Configuration options you'll want include:
|
||||
@@ -84,16 +85,13 @@ makes things slightly awkward. Preconfigured profiles are available.
|
||||
|
||||
The syntax is:
|
||||
|
||||
fluxengine write <format> -i input.img <options>
|
||||
fluxengine write ibm <format> -i input.img <options>
|
||||
|
||||
The common PC formats are `ibm720` and `ibm1440`, but there are _many_ others,
|
||||
and there's too many configuration options to usefully list. Use `fluxengine
|
||||
write` to list all formats, and try `fluxengine write ibm1440 --config` to see
|
||||
a sample configuration.
|
||||
See above for the formats.
|
||||
|
||||
Some image formats, such as DIM, specify the image format, For these you can
|
||||
specify the `ibm` format and FluxEngine will automatically determine the
|
||||
correct format to use.
|
||||
specify the `--auto` format (which is the default) and FluxEngine will
|
||||
automatically determine the correct format to use.
|
||||
|
||||
Mixed-format disks
|
||||
------------------
|
||||
@@ -131,11 +129,7 @@ drives, feature "tri-mode" support which in addition to normal 300rpm modes,
|
||||
can change their speed to read and write 360rpm DD and HD disks.
|
||||
|
||||
Neither the FluxEngine or Greaseweazle hardware can currently command a
|
||||
tri-mode drive to spin at 360rpm, however an older 360rpm-only drive will work
|
||||
to read these formats.
|
||||
tri-mode drive to spin at 360rpm. However on both devices the FluxEngine
|
||||
software is capable of both reading and writing 300rpm disks at 360rpm and vice
|
||||
versa, so it shouldn't matter.
|
||||
|
||||
Alternately, the FluxEngine software can rescale the flux pulses to enable
|
||||
reading and writing these formats with a plain 300rpm drive. To do this,
|
||||
specify the following two additional options:
|
||||
|
||||
--flux_source.rescale=1.2 --flux_sink.rescale=1.2
|
||||
|
||||
@@ -37,20 +37,19 @@ Reading discs
|
||||
Just do:
|
||||
|
||||
```
|
||||
fluxengine read <format> -o mac.dsk
|
||||
fluxengine read mac <format> -o mac.dsk
|
||||
```
|
||||
|
||||
...where `<format>` can be `mac400` or `mac800`.
|
||||
...where `<format>` can be `--400` or `--800`.
|
||||
|
||||
You should end up with a `mac.dsk` file containing a raw sector image
|
||||
(equivalent to `.img`).
|
||||
|
||||
**Big warning!** Mac disk images are complicated due to the way the tracks are
|
||||
different sizes and the odd sector size. What you get above is a triangular
|
||||
disk image, which contains all the 512-byte user data areas concatenated
|
||||
together in filesystem order. It does not contain the twelve bytes of metadata.
|
||||
If you want these as well, specify that you want 524 byte sectors with
|
||||
`--output.image.img.trackdata.sector_size=512`. The metadata will follow the
|
||||
The Mac disk format contains an extra twelve bytes of data per sector which can
|
||||
be used for filesystem metadata. In practice, this was never used by anyone,
|
||||
and so the default is to omit these. If you want them, specify that you want
|
||||
524 byte sectors with `--layout.layoutdata.sector_size=524`. The metadata will
|
||||
follow the
|
||||
512 bytes of user data.
|
||||
|
||||
FluxEngine also supports DiskCopy 4.2 disk images, which may be a better option
|
||||
@@ -64,16 +63,13 @@ Writing discs
|
||||
Just do:
|
||||
|
||||
```
|
||||
fluxengine write <format> -i mac.dsk
|
||||
fluxengine write mac <format> -i mac.dsk
|
||||
```
|
||||
|
||||
...where `<format>` can be `mac400` or `mac800`.
|
||||
...where `<format>` can be `400` or `800`.
|
||||
|
||||
It'll read the image file and write it out.
|
||||
|
||||
The same warning as above applies --- you can use normal `.dsk` files but it's
|
||||
problematic. Consider using DiskCopy 4.2 files instead.
|
||||
|
||||
Useful references
|
||||
-----------------
|
||||
|
||||
|
||||
@@ -23,10 +23,10 @@ Reading disks
|
||||
Based on your floppy drive, just do one of:
|
||||
|
||||
```
|
||||
fluxengine read micropolis143 # single-sided Mod I
|
||||
fluxengine read micropolis287 # double-sided Mod I
|
||||
fluxengine read micropolis315 # single-sided Mod II
|
||||
fluxengine read micropolis630 # double-sided Mod II
|
||||
fluxengine read micropolis --143 # single-sided Mod I
|
||||
fluxengine read micropolis --287 # double-sided Mod I
|
||||
fluxengine read micropolis --315 # single-sided Mod II
|
||||
fluxengine read micropolis --630 # double-sided Mod II
|
||||
```
|
||||
|
||||
You should end up with a `micropolis.img` of the corresponding size. The image
|
||||
@@ -45,10 +45,10 @@ It's also possible to output to VGI, which retains OS-specific "user data" and
|
||||
machine-specific ECC. Add `--vgi` to the command line after the chosen
|
||||
Micropolis profile:
|
||||
```
|
||||
fluxengine read micropolis143 --vgi # single-sided Mod I
|
||||
fluxengine read micropolis287 --vgi # double-sided Mod I
|
||||
fluxengine read micropolis315 --vgi # single-sided Mod II
|
||||
fluxengine read micropolis630 --vgi # double-sided Mod II
|
||||
fluxengine read micropolis --143 --vgi # single-sided Mod I
|
||||
fluxengine read micropolis --287 --vgi # double-sided Mod I
|
||||
fluxengine read micropolis --315 --vgi # single-sided Mod II
|
||||
fluxengine read micropolis --630 --vgi # double-sided Mod II
|
||||
```
|
||||
|
||||
You should end up with a `micropolis.vgi` instead. The format is well-defined
|
||||
@@ -72,15 +72,15 @@ Writing disks
|
||||
Just do one of:
|
||||
|
||||
```
|
||||
fluxengine write micropolis143 # single-sided Mod I
|
||||
fluxengine write micropolis287 # double-sided Mod I
|
||||
fluxengine write micropolis315 # single-sided Mod II
|
||||
fluxengine write micropolis630 # double-sided Mod II
|
||||
fluxengine write micropolis --143 # single-sided Mod I
|
||||
fluxengine write micropolis --287 # double-sided Mod I
|
||||
fluxengine write micropolis --315 # single-sided Mod II
|
||||
fluxengine write micropolis --630 # double-sided Mod II
|
||||
|
||||
fluxengine write micropolis143 --vgi # single-sided Mod I
|
||||
fluxengine write micropolis287 --vgi # double-sided Mod I
|
||||
fluxengine write micropolis315 --vgi # single-sided Mod II
|
||||
fluxengine write micropolis630 --vgi # double-sided Mod II
|
||||
fluxengine write micropolis --143 --vgi # single-sided Mod I
|
||||
fluxengine write micropolis --287 --vgi # double-sided Mod I
|
||||
fluxengine write micropolis --315 --vgi # single-sided Mod II
|
||||
fluxengine write micropolis --630 --vgi # double-sided Mod II
|
||||
```
|
||||
|
||||
Useful references
|
||||
|
||||
@@ -9,7 +9,7 @@ clone of the PDP-11. The MX board was an early floppy drive controller board
|
||||
for it.
|
||||
|
||||
<div style="text-align: center">
|
||||
<a href="http://www.leningrad.su/museum/show_big.php?n=1006"><img src="dvk3m.jpg" style="max-width: 60%" alt="A Durango F85, held precariously"></a>
|
||||
<a href="http://www.leningrad.su/museum/show_big.php?n=1006"><img src="dvk3m.jpg" style="max-width: 60%" alt="A DVK computer"></a>
|
||||
</div>
|
||||
|
||||
The MX format is interesting in that it has to be read a track at a time. The
|
||||
@@ -42,15 +42,17 @@ Reading discs
|
||||
-------------
|
||||
|
||||
```
|
||||
fluxengine read mx440
|
||||
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, add one of
|
||||
the following options:
|
||||
|
||||
* single-sided 40-track: `mx110`
|
||||
* double-sided 40-track: `mx220_ds`
|
||||
* single-sided 80-track: `mx220_ss`
|
||||
* double-sided 80-track: `mx440`
|
||||
* single-sided 40-track: `--110`
|
||||
* double-sided 40-track: `--220ds`
|
||||
* single-sided 80-track: `--220ss`
|
||||
* double-sided 80-track: `--440`
|
||||
|
||||
|
||||
Useful references
|
||||
|
||||
@@ -21,12 +21,10 @@ equivalent to .img images.
|
||||
Reading disks
|
||||
-------------
|
||||
|
||||
You must use a 48-TPI (40-track) 300RPM 5.25" floppy drive.
|
||||
|
||||
To read a double-sided North Star floppy, run:
|
||||
|
||||
```
|
||||
fluxengine read <format>
|
||||
fluxengine read northstar <format>
|
||||
```
|
||||
|
||||
...where `<format>` is one of the formats listed below.
|
||||
@@ -37,13 +35,10 @@ disk type.
|
||||
Writing disks
|
||||
-------------
|
||||
|
||||
You must use a 48-TPI (40-track) 300RPM 5.25" floppy drive and make
|
||||
sure that the drive's spindle speed is adjusted to exactly 300RPM.
|
||||
|
||||
To write a double-sided North Star floppy, run:
|
||||
|
||||
```
|
||||
fluxengine write <format> -i image_to_write.nsi
|
||||
fluxengine write northstar <format> -i image_to_write.nsi
|
||||
```
|
||||
|
||||
...where `<format>` is one of the formats listed below.
|
||||
@@ -55,9 +50,9 @@ The following formats are supported:
|
||||
|
||||
| Format name | Disk Type | File Size (bytes) |
|
||||
| -------------- | ----------------------------------- | ----------------- |
|
||||
| `northstar87` | Single-Sided, Single-Density (SSSD) | 89,600 |
|
||||
| `northstar175` | Single-Sided, Double-Density (SSDD) | 179,200 |
|
||||
| `northstar350` | Double-Sided, Double-Density (DSDD) | 358,400 |
|
||||
| `--87` | Single-Sided, Single-Density (SSSD) | 89,600 |
|
||||
| `--175` | Single-Sided, Double-Density (SSDD) | 179,200 |
|
||||
| `--350` | Double-Sided, Double-Density (DSDD) | 358,400 |
|
||||
|
||||
Useful references
|
||||
-----------------
|
||||
|
||||
@@ -8,7 +8,7 @@ sector GCR disks, with a variable-speed drive and a varying number of sectors
|
||||
per track --- from 19 to 12. Disks can be double-sided, meaning that they can
|
||||
store 1224kB per disk, which was almost unheard of back then. Because the way
|
||||
that the tracks on head 1 are offset from head 0 (this happens with all disks),
|
||||
the speed zone allocation on head 1 differ from head 0...
|
||||
the speed zone allocation on head 1 differs from head 0...
|
||||
|
||||
| Zone | Head 0 tracks | Head 1 tracks | Sectors | Original period (ms) |
|
||||
|:----:|:-------------:|:-------------:|:-------:|:--------------------:|
|
||||
@@ -40,18 +40,12 @@ Reading discs
|
||||
Just do:
|
||||
|
||||
```
|
||||
fluxengine read <format>
|
||||
fluxengine read victor9k <format>
|
||||
|
||||
```
|
||||
|
||||
...where `<format>` can be `victor9k_ss` or `victor9k_ds`.
|
||||
|
||||
For `victor9k_ss` you should end up with an `victor9k.img` which is 627200 bytes long.
|
||||
For `victor9k_ds` you should end up with an `victor9k.img` which is 1224192 bytes long.
|
||||
|
||||
**Big warning!** The image is triangular, where each track occupies a different
|
||||
amount of space. Victor disk images are complicated due to the way the tracks
|
||||
are different sizes and the odd sector size.
|
||||
...where `<format>` can be `--612` for a single-sided disk or `--1224` for a
|
||||
double-sided disk.
|
||||
|
||||
Writing discs
|
||||
-------------
|
||||
@@ -59,11 +53,10 @@ Writing discs
|
||||
Just do:
|
||||
|
||||
```
|
||||
fluxengine read victor9k_ss -i victor9k.img
|
||||
fluxengine write victor9k <format> -i victor9k.img
|
||||
```
|
||||
|
||||
**Big warning!** This uses the same triangular disk image that reading uses.
|
||||
|
||||
`<format>` is as above.
|
||||
|
||||
Useful references
|
||||
-----------------
|
||||
|
||||
@@ -77,6 +77,7 @@ LIBFLUXENGINE_SRCS = \
|
||||
lib/vfs/cbmfs.cc \
|
||||
lib/vfs/cpmfs.cc \
|
||||
lib/vfs/fatfs.cc \
|
||||
lib/vfs/lif.cc \
|
||||
lib/vfs/machfs.cc \
|
||||
lib/vfs/prodos.cc \
|
||||
lib/vfs/smaky6fs.cc \
|
||||
|
||||
@@ -12,7 +12,7 @@ import "lib/drive.proto";
|
||||
import "lib/common.proto";
|
||||
import "lib/layout.proto";
|
||||
|
||||
// NEXT_TAG: 21
|
||||
// NEXT_TAG: 23
|
||||
message ConfigProto
|
||||
{
|
||||
optional string comment = 8;
|
||||
@@ -39,18 +39,27 @@ message ConfigProto
|
||||
optional FilesystemProto filesystem = 17;
|
||||
|
||||
repeated OptionProto option = 20;
|
||||
repeated OptionGroupProto option_group = 22;
|
||||
}
|
||||
|
||||
// NEXT_TAG: 7
|
||||
message OptionProto
|
||||
{
|
||||
optional string name = 1 [ (help) = "option name" ];
|
||||
optional string comment = 2 [ (help) = "help text for option" ];
|
||||
optional string message = 3
|
||||
[ (help) = "message to display when option is in use" ];
|
||||
optional string exclusivity_group = 5 [
|
||||
(help) =
|
||||
"options with the same group cannot be selected at the same time"
|
||||
optional bool set_by_default = 6 [
|
||||
(help) = "this option is applied by default",
|
||||
default = false
|
||||
];
|
||||
optional ConfigProto config = 4
|
||||
[ (help) = "option data", (recurse) = false ];
|
||||
}
|
||||
|
||||
message OptionGroupProto
|
||||
{
|
||||
optional string comment = 1 [ (help) = "help text for option group" ];
|
||||
repeated OptionProto option = 2;
|
||||
}
|
||||
|
||||
|
||||
128
lib/flags.cc
128
lib/flags.cc
@@ -41,49 +41,53 @@ void FlagGroup::addFlag(Flag* flag)
|
||||
_flags.push_back(flag);
|
||||
}
|
||||
|
||||
static bool setFallbackFlag(
|
||||
const std::string& key, const std::string& value, bool uses_that)
|
||||
void FlagGroup::applyOption(const OptionProto& option)
|
||||
{
|
||||
if (beginsWith(key, "--"))
|
||||
{
|
||||
std::string path = key.substr(2);
|
||||
if (key.find('.') != std::string::npos)
|
||||
{
|
||||
ProtoField protoField = resolveProtoPath(&config, path);
|
||||
setProtoFieldFromString(protoField, value);
|
||||
return uses_that;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (FlagGroup::applyOption(path))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Error() << "unrecognised flag; try --help";
|
||||
}
|
||||
|
||||
bool FlagGroup::applyOption(const std::string& option)
|
||||
{
|
||||
for (const auto& configs : config.option())
|
||||
{
|
||||
if (option == configs.name())
|
||||
{
|
||||
if (configs.config().option_size() > 0)
|
||||
if (option.config().option_size() > 0)
|
||||
Error() << fmt::format(
|
||||
"option '{}' has an option inside it, which isn't "
|
||||
"allowed",
|
||||
option);
|
||||
if (configs.config().include_size() > 0)
|
||||
option.name());
|
||||
if (option.config().option_group_size() > 0)
|
||||
Error() << fmt::format(
|
||||
"option '{}' has an option group inside it, which isn't "
|
||||
"allowed",
|
||||
option.name());
|
||||
if (option.config().include_size() > 0)
|
||||
Error() << fmt::format(
|
||||
"option '{}' is trying to include something, which "
|
||||
"isn't allowed",
|
||||
option);
|
||||
option.name());
|
||||
|
||||
Logger() << fmt::format("OPTION: {}", configs.message());
|
||||
config.MergeFrom(configs.config());
|
||||
Logger() << fmt::format("OPTION: {}",
|
||||
option.has_message() ? option.message() : option.comment());
|
||||
|
||||
config.MergeFrom(option.config());
|
||||
}
|
||||
|
||||
bool FlagGroup::applyOption(const std::string& optionName)
|
||||
{
|
||||
auto searchOptionList = [&](auto& optionList)
|
||||
{
|
||||
for (const auto& option : optionList)
|
||||
{
|
||||
if (optionName == option.name())
|
||||
{
|
||||
applyOption(option);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
if (searchOptionList(config.option()))
|
||||
return true;
|
||||
|
||||
for (const auto& optionGroup : config.option_group())
|
||||
{
|
||||
if (searchOptionList(optionGroup.option()))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -127,6 +131,8 @@ std::vector<std::string> FlagGroup::parseFlagsWithFilenames(int argc,
|
||||
|
||||
/* Now actually parse them. */
|
||||
|
||||
std::set<std::string> options;
|
||||
std::vector<std::pair<std::string, std::string>> overrides;
|
||||
std::vector<std::string> filenames;
|
||||
int index = 1;
|
||||
while (index < argc)
|
||||
@@ -190,8 +196,19 @@ std::vector<std::string> FlagGroup::parseFlagsWithFilenames(int argc,
|
||||
auto flag = flags_by_name.find(key);
|
||||
if (flag == flags_by_name.end())
|
||||
{
|
||||
if (setFallbackFlag(key, value, usesthat))
|
||||
index++;
|
||||
if (beginsWith(key, "--"))
|
||||
{
|
||||
std::string path = key.substr(2);
|
||||
if (key.find('.') != std::string::npos)
|
||||
{
|
||||
overrides.push_back(std::make_pair(path, value));
|
||||
index += usesthat;
|
||||
}
|
||||
else
|
||||
options.insert(path);
|
||||
}
|
||||
else
|
||||
Error() << "unrecognised flag; try --help";
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -204,6 +221,49 @@ std::vector<std::string> FlagGroup::parseFlagsWithFilenames(int argc,
|
||||
index++;
|
||||
}
|
||||
|
||||
/* Apply any default options in groups. */
|
||||
|
||||
for (auto& group : config.option_group())
|
||||
{
|
||||
const OptionProto* defaultOption = &*group.option().begin();
|
||||
bool isSet = false;
|
||||
|
||||
for (auto& option : group.option())
|
||||
{
|
||||
if (options.find(option.name()) != options.end())
|
||||
{
|
||||
defaultOption = &option;
|
||||
options.erase(option.name());
|
||||
}
|
||||
}
|
||||
|
||||
FlagGroup::applyOption(*defaultOption);
|
||||
}
|
||||
|
||||
/* Next, any standalone options. */
|
||||
|
||||
for (auto& option : config.option())
|
||||
{
|
||||
if (options.find(option.name()) != options.end())
|
||||
{
|
||||
FlagGroup::applyOption(option);
|
||||
options.erase(option.name());
|
||||
}
|
||||
}
|
||||
|
||||
if (!options.empty())
|
||||
Error() << fmt::format(
|
||||
"--{} is not a known flag or format option; try --help",
|
||||
*options.begin());
|
||||
|
||||
/* Now apply any value overrides (in order). */
|
||||
|
||||
for (auto [k, v] : overrides)
|
||||
{
|
||||
ProtoField protoField = resolveProtoPath(&config, k);
|
||||
setProtoFieldFromString(protoField, v);
|
||||
}
|
||||
|
||||
return filenames;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
class DataSpec;
|
||||
class Flag;
|
||||
class ConfigProto;
|
||||
class OptionProto;
|
||||
|
||||
class FlagGroup
|
||||
{
|
||||
@@ -46,6 +47,7 @@ public:
|
||||
|
||||
/* Modify the current config to engage the named option. */
|
||||
|
||||
static void applyOption(const OptionProto& option);
|
||||
static bool applyOption(const std::string& option);
|
||||
|
||||
void addFlag(Flag* flag);
|
||||
|
||||
200
lib/vfs/lif.cc
Normal file
200
lib/vfs/lif.cc
Normal file
@@ -0,0 +1,200 @@
|
||||
#include "lib/globals.h"
|
||||
#include "lib/vfs/vfs.h"
|
||||
#include "lib/config.pb.h"
|
||||
#include "lib/utils.h"
|
||||
#include <fmt/format.h>
|
||||
|
||||
/* See https://www.hp9845.net/9845/projects/hpdir/#lif_filesystem for
|
||||
* a description. */
|
||||
|
||||
static void trimZeros(std::string s)
|
||||
{
|
||||
s.erase(std::remove(s.begin(), s.end(), 0), s.end());
|
||||
}
|
||||
|
||||
class LifFilesystem : public Filesystem
|
||||
{
|
||||
class LifDirent : public Dirent
|
||||
{
|
||||
public:
|
||||
LifDirent(const LifProto& config, Bytes& bytes)
|
||||
{
|
||||
file_type = TYPE_FILE;
|
||||
|
||||
ByteReader br(bytes);
|
||||
filename = trimWhitespace(br.read(10));
|
||||
uint16_t type = br.read_be16();
|
||||
location = br.read_be32();
|
||||
length = br.read_be32() * config.block_size();
|
||||
|
||||
mode = fmt::format("{:04x}", type);
|
||||
path = {filename};
|
||||
|
||||
attributes[Filesystem::FILENAME] = filename;
|
||||
attributes[Filesystem::LENGTH] = std::to_string(length);
|
||||
attributes[Filesystem::FILE_TYPE] = "file";
|
||||
attributes[Filesystem::MODE] = mode;
|
||||
}
|
||||
|
||||
public:
|
||||
uint32_t location;
|
||||
};
|
||||
|
||||
public:
|
||||
LifFilesystem(
|
||||
const LifProto& config, std::shared_ptr<SectorInterface> sectors):
|
||||
Filesystem(sectors),
|
||||
_config(config)
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t capabilities() const
|
||||
{
|
||||
return OP_GETFSDATA | OP_LIST | OP_GETFILE | OP_GETDIRENT;
|
||||
}
|
||||
|
||||
FilesystemStatus check() override
|
||||
{
|
||||
return FS_OK;
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> getMetadata() override
|
||||
{
|
||||
mount();
|
||||
|
||||
std::map<std::string, std::string> attributes;
|
||||
|
||||
attributes[VOLUME_NAME] = _volumeLabel;
|
||||
attributes[TOTAL_BLOCKS] = std::to_string(_totalBlocks);
|
||||
attributes[USED_BLOCKS] = std::to_string(_usedBlocks);
|
||||
attributes[BLOCK_SIZE] = std::to_string(_config.block_size());
|
||||
attributes["lif.directory_block"] = std::to_string(_directoryBlock);
|
||||
attributes["lif.directory_size"] = std::to_string(_directorySize);
|
||||
return attributes;
|
||||
}
|
||||
|
||||
std::shared_ptr<Dirent> getDirent(const Path& path) override
|
||||
{
|
||||
mount();
|
||||
if (path.size() != 1)
|
||||
throw BadPathException();
|
||||
|
||||
return findFile(path.front());
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<Dirent>> list(const Path& path) override
|
||||
{
|
||||
mount();
|
||||
if (!path.empty())
|
||||
throw FileNotFoundException();
|
||||
|
||||
std::vector<std::shared_ptr<Dirent>> result;
|
||||
for (auto& de : _dirents)
|
||||
result.push_back(de);
|
||||
return result;
|
||||
}
|
||||
|
||||
Bytes getFile(const Path& path) override
|
||||
{
|
||||
mount();
|
||||
if (path.size() != 1)
|
||||
throw BadPathException();
|
||||
|
||||
auto dirent = findFile(path.front());
|
||||
|
||||
return getLifBlock(
|
||||
dirent->location, dirent->length / _config.block_size());
|
||||
}
|
||||
|
||||
private:
|
||||
void mount()
|
||||
{
|
||||
_sectorSize = getLogicalSectorSize();
|
||||
_sectorsPerBlock = _sectorSize / _config.block_size();
|
||||
|
||||
_rootBlock = getLifBlock(0);
|
||||
|
||||
ByteReader rbr(_rootBlock);
|
||||
if (rbr.read_be16() != 0x8000)
|
||||
throw BadFilesystemException();
|
||||
_volumeLabel = trimWhitespace(rbr.read(6));
|
||||
_directoryBlock = rbr.read_be32();
|
||||
rbr.skip(4);
|
||||
_directorySize = rbr.read_be32();
|
||||
unsigned tracks = rbr.read_be32();
|
||||
unsigned heads = rbr.read_be32();
|
||||
unsigned sectors = rbr.read_be32();
|
||||
_usedBlocks = 1 + _directorySize;
|
||||
|
||||
Bytes directory = getLifBlock(_directoryBlock, _directorySize);
|
||||
|
||||
_dirents.clear();
|
||||
ByteReader br(directory);
|
||||
while (!br.eof())
|
||||
{
|
||||
Bytes direntBytes = br.read(32);
|
||||
if (direntBytes[0] != 0xff)
|
||||
{
|
||||
auto dirent = std::make_unique<LifDirent>(_config, direntBytes);
|
||||
_usedBlocks += dirent->length / _config.block_size();
|
||||
_dirents.push_back(std::move(dirent));
|
||||
}
|
||||
}
|
||||
_totalBlocks = std::max(tracks * heads * sectors, _usedBlocks);
|
||||
}
|
||||
|
||||
std::shared_ptr<LifDirent> findFile(const std::string filename)
|
||||
{
|
||||
for (const auto& dirent : _dirents)
|
||||
{
|
||||
if (dirent->filename == filename)
|
||||
return dirent;
|
||||
}
|
||||
|
||||
throw FileNotFoundException();
|
||||
}
|
||||
|
||||
Bytes getLifBlock(uint32_t number, uint32_t count)
|
||||
{
|
||||
Bytes b;
|
||||
ByteWriter bw(b);
|
||||
|
||||
while (count)
|
||||
{
|
||||
bw += getLifBlock(number);
|
||||
number++;
|
||||
count--;
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
Bytes getLifBlock(uint32_t number)
|
||||
{
|
||||
/* LIF uses 256-byte blocks, but the underlying format can have much
|
||||
* bigger sectors. */
|
||||
|
||||
Bytes sector = getLogicalSector(number / _sectorsPerBlock);
|
||||
unsigned offset = number % _sectorsPerBlock;
|
||||
return sector.slice(
|
||||
offset * _config.block_size(), _config.block_size());
|
||||
}
|
||||
|
||||
private:
|
||||
const LifProto& _config;
|
||||
int _sectorSize;
|
||||
int _sectorsPerBlock;
|
||||
Bytes _rootBlock;
|
||||
std::string _volumeLabel;
|
||||
unsigned _directoryBlock;
|
||||
unsigned _directorySize;
|
||||
unsigned _totalBlocks;
|
||||
unsigned _usedBlocks;
|
||||
std::vector<std::shared_ptr<LifDirent>> _dirents;
|
||||
};
|
||||
|
||||
std::unique_ptr<Filesystem> Filesystem::createLifFilesystem(
|
||||
const FilesystemProto& config, std::shared_ptr<SectorInterface> sectors)
|
||||
{
|
||||
return std::make_unique<LifFilesystem>(config.lif(), sectors);
|
||||
}
|
||||
@@ -233,8 +233,8 @@ private:
|
||||
_rootBlock = getPsosBlock(2, 1);
|
||||
_bitmapBlockNumber = _rootBlock.reader().seek(0x1c).read_be16();
|
||||
_filedesBlockNumber = _rootBlock.reader().seek(0x1e).read_be16();
|
||||
_filedesLength =
|
||||
_rootBlock.reader().seek(0x20).read_be16() - _filedesBlockNumber + 1;
|
||||
_filedesLength = _rootBlock.reader().seek(0x20).read_be16() -
|
||||
_filedesBlockNumber + 1;
|
||||
_totalBlocks = _rootBlock.reader().seek(0x18).read_be16();
|
||||
|
||||
Bytes directoryBlock = getPsosBlock(3, 1);
|
||||
|
||||
@@ -212,6 +212,9 @@ std::unique_ptr<Filesystem> Filesystem::createFilesystem(
|
||||
case FilesystemProto::PHILE:
|
||||
return Filesystem::createPhileFilesystem(config, image);
|
||||
|
||||
case FilesystemProto::LIF:
|
||||
return Filesystem::createLifFilesystem(config, image);
|
||||
|
||||
default:
|
||||
Error() << "no filesystem configured";
|
||||
return std::unique_ptr<Filesystem>();
|
||||
|
||||
@@ -254,6 +254,8 @@ public:
|
||||
const FilesystemProto& config, std::shared_ptr<SectorInterface> image);
|
||||
static std::unique_ptr<Filesystem> createPhileFilesystem(
|
||||
const FilesystemProto& config, std::shared_ptr<SectorInterface> image);
|
||||
static std::unique_ptr<Filesystem> createLifFilesystem(
|
||||
const FilesystemProto& config, std::shared_ptr<SectorInterface> image);
|
||||
|
||||
static std::unique_ptr<Filesystem> createFilesystem(
|
||||
const FilesystemProto& config, std::shared_ptr<SectorInterface> image);
|
||||
|
||||
@@ -59,7 +59,8 @@ message CbmfsProto
|
||||
|
||||
message ProdosProto {}
|
||||
|
||||
message AppledosProto {
|
||||
message AppledosProto
|
||||
{
|
||||
optional uint32 filesystem_offset_sectors = 1 [
|
||||
default = 0,
|
||||
(help) = "offset the entire offset up the disk this many sectors"
|
||||
@@ -68,17 +69,23 @@ message AppledosProto {
|
||||
|
||||
message Smaky6FsProto {}
|
||||
|
||||
message PhileProto {
|
||||
optional uint32 block_size = 1 [
|
||||
default = 1024,
|
||||
(help) = "Phile filesystem block size"
|
||||
];
|
||||
message PhileProto
|
||||
{
|
||||
optional uint32 block_size = 1
|
||||
[ default = 1024, (help) = "Phile filesystem block size" ];
|
||||
}
|
||||
|
||||
// NEXT_TAG: 14
|
||||
message LifProto
|
||||
{
|
||||
optional uint32 block_size = 1
|
||||
[ default = 256, (help) = "LIF filesystem block size" ];
|
||||
}
|
||||
|
||||
// NEXT_TAG: 15
|
||||
message FilesystemProto
|
||||
{
|
||||
enum FilesystemType {
|
||||
enum FilesystemType
|
||||
{
|
||||
NOT_SET = 0;
|
||||
ACORNDFS = 1;
|
||||
BROTHER120 = 2;
|
||||
@@ -91,9 +98,11 @@ message FilesystemProto
|
||||
SMAKY6 = 9;
|
||||
APPLEDOS = 10;
|
||||
PHILE = 11;
|
||||
LIF = 12;
|
||||
}
|
||||
|
||||
optional FilesystemType type = 10 [default = NOT_SET, (help) = "filesystem type"];
|
||||
optional FilesystemType type = 10
|
||||
[ default = NOT_SET, (help) = "filesystem type" ];
|
||||
|
||||
optional AcornDfsProto acorndfs = 1;
|
||||
optional Brother120FsProto brother120 = 2;
|
||||
@@ -106,6 +115,8 @@ message FilesystemProto
|
||||
optional AppledosProto appledos = 12;
|
||||
optional Smaky6FsProto smaky6 = 11;
|
||||
optional PhileProto phile = 13;
|
||||
optional LifProto lif = 14;
|
||||
|
||||
optional SectorListProto sector_order = 9 [(help) = "specify the filesystem order of sectors"];
|
||||
optional SectorListProto sector_order = 9
|
||||
[ (help) = "specify the filesystem order of sectors" ];
|
||||
}
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
comment: 'Acorn ADFS generic settings (32-bit formats)'
|
||||
is_extension: true
|
||||
|
||||
image_writer {
|
||||
filename: "acornadfs.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
layout {
|
||||
tracks: 80
|
||||
sides: 2
|
||||
layoutdata {
|
||||
sector_size: 1024
|
||||
physical {
|
||||
start_sector: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
decoder {
|
||||
ibm {
|
||||
trackdata {
|
||||
ignore_side_byte: true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
comment: 'Acorn ADFS generic settings (8-bit formats)'
|
||||
is_extension: true
|
||||
|
||||
image_writer {
|
||||
filename: "acornadfs.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
layout {
|
||||
layoutdata {
|
||||
sector_size: 256
|
||||
physical {
|
||||
start_sector: 0
|
||||
count: 16
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
decoder {
|
||||
ibm {
|
||||
trackdata {
|
||||
ignore_side_byte: true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,202 +0,0 @@
|
||||
comment: 'Apple II generic settings'
|
||||
is_extension: true
|
||||
|
||||
drive {
|
||||
high_density: false
|
||||
}
|
||||
|
||||
decoder {
|
||||
apple2 {}
|
||||
}
|
||||
|
||||
encoder {
|
||||
apple2 {}
|
||||
}
|
||||
|
||||
option {
|
||||
name: "nofs"
|
||||
comment: "use physical CHS sector order and no file system"
|
||||
exclusivity_group: "format"
|
||||
}
|
||||
|
||||
option {
|
||||
name: "appledos"
|
||||
comment: "use AppleDOS soft sector skew and file system"
|
||||
message: "compensating for AppleDOS soft sector skew"
|
||||
exclusivity_group: "format"
|
||||
|
||||
config {
|
||||
image_reader {
|
||||
filesystem_sector_order: true
|
||||
}
|
||||
|
||||
image_writer {
|
||||
filesystem_sector_order: true
|
||||
}
|
||||
|
||||
filesystem {
|
||||
type: APPLEDOS
|
||||
}
|
||||
|
||||
layout {
|
||||
layoutdata {
|
||||
filesystem {
|
||||
sector: 0
|
||||
sector: 13
|
||||
sector: 11
|
||||
sector: 9
|
||||
sector: 7
|
||||
sector: 5
|
||||
sector: 3
|
||||
sector: 1
|
||||
sector: 14
|
||||
sector: 12
|
||||
sector: 10
|
||||
sector: 8
|
||||
sector: 6
|
||||
sector: 4
|
||||
sector: 2
|
||||
sector: 15
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
option {
|
||||
name: "prodos"
|
||||
comment: "use ProDOS soft sector skew and filesystem"
|
||||
message: "compensating for ProDOS soft sector skew"
|
||||
exclusivity_group: "format"
|
||||
|
||||
config {
|
||||
image_reader {
|
||||
filesystem_sector_order: true
|
||||
}
|
||||
|
||||
image_writer {
|
||||
filesystem_sector_order: true
|
||||
}
|
||||
|
||||
filesystem {
|
||||
type: PRODOS
|
||||
}
|
||||
|
||||
layout {
|
||||
layoutdata {
|
||||
filesystem {
|
||||
sector: 0
|
||||
sector: 2
|
||||
sector: 4
|
||||
sector: 6
|
||||
sector: 8
|
||||
sector: 10
|
||||
sector: 12
|
||||
sector: 14
|
||||
sector: 1
|
||||
sector: 3
|
||||
sector: 5
|
||||
sector: 7
|
||||
sector: 9
|
||||
sector: 11
|
||||
sector: 13
|
||||
sector: 15
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
option {
|
||||
name: "cpm"
|
||||
comment: "use CP/M soft sector skew and filesystem"
|
||||
message: "compensating for CP/M soft sector skew"
|
||||
exclusivity_group: "format"
|
||||
|
||||
config {
|
||||
image_reader {
|
||||
filesystem_sector_order: true
|
||||
}
|
||||
|
||||
image_writer {
|
||||
filesystem_sector_order: true
|
||||
}
|
||||
|
||||
filesystem {
|
||||
type: CPMFS
|
||||
cpmfs {
|
||||
filesystem_start {
|
||||
track: 3
|
||||
}
|
||||
block_size: 4096
|
||||
dir_entries: 128
|
||||
}
|
||||
}
|
||||
|
||||
decoder {
|
||||
apple2 {
|
||||
side_one_track_offset: 80
|
||||
}
|
||||
}
|
||||
|
||||
encoder {
|
||||
apple2 {
|
||||
side_one_track_offset: 80
|
||||
}
|
||||
}
|
||||
|
||||
layout {
|
||||
layoutdata {
|
||||
# The boot tracks use ProDOS translation.
|
||||
|
||||
track: 0
|
||||
up_to_track: 2
|
||||
filesystem {
|
||||
sector: 0
|
||||
sector: 2
|
||||
sector: 4
|
||||
sector: 6
|
||||
sector: 8
|
||||
sector: 10
|
||||
sector: 12
|
||||
sector: 14
|
||||
sector: 1
|
||||
sector: 3
|
||||
sector: 5
|
||||
sector: 7
|
||||
sector: 9
|
||||
sector: 11
|
||||
sector: 13
|
||||
sector: 15
|
||||
}
|
||||
}
|
||||
|
||||
layoutdata {
|
||||
# The data tracks use their own, special translation.
|
||||
|
||||
track: 3
|
||||
up_to_track: 79
|
||||
filesystem {
|
||||
sector: 0
|
||||
sector: 3
|
||||
sector: 6
|
||||
sector: 9
|
||||
sector: 12
|
||||
sector: 15
|
||||
sector: 2
|
||||
sector: 5
|
||||
sector: 8
|
||||
sector: 11
|
||||
sector: 14
|
||||
sector: 1
|
||||
sector: 4
|
||||
sector: 7
|
||||
sector: 10
|
||||
sector: 13
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
comment: 'Common Atari definitions'
|
||||
is_extension: true
|
||||
|
||||
encoder {
|
||||
ibm {
|
||||
trackdata {
|
||||
target_rotational_period_ms: 200
|
||||
target_clock_period_us: 4
|
||||
emit_iam: false
|
||||
gap0: 80
|
||||
gap2: 22
|
||||
gap3: 34
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
decoder {
|
||||
ibm {
|
||||
trackdata {
|
||||
ignore_sector: 66
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
comment: 'Common Micropolis definitions'
|
||||
is_extension: true
|
||||
|
||||
drive {
|
||||
hard_sector_count: 16
|
||||
}
|
||||
|
||||
image_reader {
|
||||
filename: "micropolis.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
image_writer {
|
||||
filename: "micropolis.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
layout {
|
||||
layoutdata {
|
||||
sector_size: 256
|
||||
physical {
|
||||
start_sector: 0
|
||||
count: 16
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
encoder {
|
||||
micropolis {}
|
||||
}
|
||||
|
||||
decoder {
|
||||
micropolis {}
|
||||
}
|
||||
|
||||
option {
|
||||
name: "vgi"
|
||||
comment: "Read/write VGI format images"
|
||||
message: "using VGI format"
|
||||
|
||||
config {
|
||||
image_reader {
|
||||
filename: "micropolis.vgi"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
image_writer {
|
||||
filename: "micropolis.vgi"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
layout {
|
||||
layoutdata {
|
||||
sector_size: 275
|
||||
}
|
||||
}
|
||||
|
||||
decoder {
|
||||
micropolis {
|
||||
sector_output_size: 275
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
comment: 'DVK MX common settings'
|
||||
is_extension: true
|
||||
|
||||
image_writer {
|
||||
filename: "mx.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
layout {
|
||||
layoutdata {
|
||||
sector_size: 256
|
||||
physical {
|
||||
start_sector: 0
|
||||
count: 11
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
decoder {
|
||||
mx {}
|
||||
}
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
comment: 'Northstar generic settings'
|
||||
is_extension: true
|
||||
|
||||
image_reader {
|
||||
filename: "northstar.nsi"
|
||||
type: NSI
|
||||
}
|
||||
|
||||
image_writer {
|
||||
filename: "northstar.nsi"
|
||||
type: NSI
|
||||
}
|
||||
|
||||
layout {
|
||||
layoutdata {
|
||||
physical {
|
||||
start_sector: 0
|
||||
count: 10
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
drive {
|
||||
hard_sector_count: 10
|
||||
sync_with_index: true
|
||||
}
|
||||
|
||||
encoder {
|
||||
northstar {}
|
||||
}
|
||||
|
||||
decoder {
|
||||
northstar {}
|
||||
}
|
||||
|
||||
121
src/formats/acornadfs.textpb
Normal file
121
src/formats/acornadfs.textpb
Normal file
@@ -0,0 +1,121 @@
|
||||
comment: 'Acorn ADFS family (ro)'
|
||||
|
||||
image_writer {
|
||||
filename: "acornadfs.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
decoder {
|
||||
ibm {
|
||||
trackdata {
|
||||
ignore_side_byte: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
option_group {
|
||||
comment: "Format variant"
|
||||
|
||||
option {
|
||||
name: "160"
|
||||
comment: '160kB 3.5" or 5.25" 40-track SSDD; S format'
|
||||
|
||||
config {
|
||||
tpi: 48
|
||||
layout {
|
||||
tracks: 40
|
||||
sides: 1
|
||||
layoutdata {
|
||||
sector_size: 256
|
||||
physical {
|
||||
start_sector: 0
|
||||
count: 16
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
option {
|
||||
name: "320"
|
||||
comment: '320kB 3.5" or 5.25" 80-track SSDD; M format'
|
||||
|
||||
config {
|
||||
tpi: 96
|
||||
layout {
|
||||
tracks: 80
|
||||
sides: 1
|
||||
layoutdata {
|
||||
sector_size: 256
|
||||
physical {
|
||||
start_sector: 0
|
||||
count: 16
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
option {
|
||||
name: "640"
|
||||
comment: '640kB 3.5" or 5.25" 80-track DSDD; L format'
|
||||
|
||||
config {
|
||||
tpi: 96
|
||||
layout {
|
||||
tracks: 80
|
||||
sides: 2
|
||||
layoutdata {
|
||||
sector_size: 256
|
||||
physical {
|
||||
start_sector: 0
|
||||
count: 16
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
option {
|
||||
name: "800"
|
||||
comment: '800kB 3.5" 80-track DSDD; D and E formats'
|
||||
|
||||
config {
|
||||
tpi: 96
|
||||
layout {
|
||||
tracks: 80
|
||||
sides: 2
|
||||
layoutdata {
|
||||
sector_size: 1024
|
||||
physical {
|
||||
start_sector: 0
|
||||
count: 5
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
option {
|
||||
name: "1600"
|
||||
comment: '1600kB 3.5" 80-track DSHD; F formats'
|
||||
set_by_default: true
|
||||
|
||||
config {
|
||||
tpi: 96
|
||||
layout {
|
||||
tracks: 80
|
||||
sides: 2
|
||||
layoutdata {
|
||||
sector_size: 1024
|
||||
physical {
|
||||
start_sector: 0
|
||||
count: 10
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
comment: 'Acorn ADFS S-format 160kB 3.5" or 5.25" 40-track SS'
|
||||
include: '_acornadfs8'
|
||||
|
||||
layout {
|
||||
tracks: 40
|
||||
sides: 1
|
||||
}
|
||||
|
||||
tpi: 48
|
||||
@@ -1,10 +0,0 @@
|
||||
comment: 'Acorn ADFS F-format 1600kB 3.5" 80-track DS'
|
||||
include: '_acornadfs32'
|
||||
|
||||
layout {
|
||||
layoutdata {
|
||||
physical {
|
||||
count: 10
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
comment: 'Acorn ADFS M-format 320kB 3.5" or 5.25" 80-track SS'
|
||||
include: '_acornadfs8'
|
||||
|
||||
layout {
|
||||
tracks: 80
|
||||
sides: 1
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
comment: 'Acorn ADFS L-format 640kB 3.5" or 5.25" 80-track DS'
|
||||
include: '_acornadfs8'
|
||||
|
||||
layout {
|
||||
tracks: 80
|
||||
sides: 2
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
comment: 'Acorn ADFS D and E-format 800kB 3.5" 80-track DS'
|
||||
include: '_acornadfs32'
|
||||
|
||||
layout {
|
||||
layoutdata {
|
||||
physical {
|
||||
count: 5
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
comment: 'Acorn DFS 100kB/200kB 3.5" or 5.25" 40- or 80-track SS (ro)'
|
||||
comment: 'Acorn DFS fmaily'
|
||||
|
||||
image_reader {
|
||||
filename: "acorndfs.img"
|
||||
@@ -11,7 +11,6 @@ image_writer {
|
||||
}
|
||||
|
||||
layout {
|
||||
tracks: 80
|
||||
sides: 1
|
||||
layoutdata {
|
||||
sector_size: 256
|
||||
@@ -47,3 +46,30 @@ filesystem {
|
||||
type: ACORNDFS
|
||||
}
|
||||
|
||||
option_group {
|
||||
comment: "Format variant"
|
||||
|
||||
option {
|
||||
name: "100"
|
||||
comment: '100kB 40-track SSSD'
|
||||
|
||||
config {
|
||||
layout {
|
||||
tracks: 40
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
option {
|
||||
name: "200"
|
||||
comment: '200kB 80-track SSSD'
|
||||
set_by_default: true
|
||||
|
||||
config {
|
||||
layout {
|
||||
tracks: 80
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
58
src/formats/ampro.textpb
Normal file
58
src/formats/ampro.textpb
Normal file
@@ -0,0 +1,58 @@
|
||||
comment: 'Ampro 5.25" family'
|
||||
|
||||
image_writer {
|
||||
filename: "ampro.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
layout {
|
||||
sides: 2
|
||||
layoutdata {
|
||||
sector_size: 1024
|
||||
physical {
|
||||
start_sector: 17
|
||||
count: 5
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
decoder {
|
||||
ibm {}
|
||||
}
|
||||
|
||||
filesystem {
|
||||
type: CPMFS
|
||||
cpmfs {
|
||||
filesystem_start {
|
||||
track: 1
|
||||
}
|
||||
block_size: 2048
|
||||
dir_entries: 128
|
||||
}
|
||||
}
|
||||
|
||||
option_group {
|
||||
comment: "Format variant"
|
||||
|
||||
option {
|
||||
name: "400"
|
||||
comment: "400kB 40-track DSDD"
|
||||
|
||||
config {
|
||||
layout {
|
||||
tracks: 40
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
option {
|
||||
name: "800"
|
||||
comment: "800kB 80-track DSDD"
|
||||
|
||||
config {
|
||||
layout {
|
||||
tracks: 80
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
comment: 'Ampro 400kB/800kB 5.25" 40/80 track SSDD/DSDD (ro)'
|
||||
|
||||
image_writer {
|
||||
filename: "ampro.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
layout {
|
||||
tracks: 80
|
||||
sides: 1
|
||||
layoutdata {
|
||||
sector_size: 1024
|
||||
physical {
|
||||
start_sector: 17
|
||||
count: 5
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
decoder {
|
||||
ibm {}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
comment: 'Ampro 400kB/800kB 5.25" 40/80 track SSDD/DSDD (ro)'
|
||||
|
||||
image_writer {
|
||||
filename: "ampro.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
layout {
|
||||
tracks: 80
|
||||
sides: 2
|
||||
layoutdata {
|
||||
sector_size: 1024
|
||||
physical {
|
||||
start_sector: 17
|
||||
count: 5
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
decoder {
|
||||
ibm {}
|
||||
}
|
||||
254
src/formats/apple2.textpb
Normal file
254
src/formats/apple2.textpb
Normal file
@@ -0,0 +1,254 @@
|
||||
comment: 'Apple II family'
|
||||
|
||||
decoder {
|
||||
apple2 {}
|
||||
}
|
||||
|
||||
encoder {
|
||||
apple2 {}
|
||||
}
|
||||
|
||||
|
||||
option_group {
|
||||
comment: "Format variant"
|
||||
|
||||
option {
|
||||
name: "140"
|
||||
comment: '140kB 5.25" 35-track SS'
|
||||
set_by_default: true
|
||||
|
||||
config {
|
||||
layout {
|
||||
tracks: 35
|
||||
sides: 1
|
||||
layoutdata {
|
||||
sector_size: 256
|
||||
physical {
|
||||
start_sector: 0
|
||||
count: 16
|
||||
}
|
||||
}
|
||||
}
|
||||
tpi: 48
|
||||
}
|
||||
}
|
||||
|
||||
option {
|
||||
name: "640"
|
||||
comment: '640kB 5.25" 80-track DS'
|
||||
|
||||
config {
|
||||
layout {
|
||||
tracks: 80
|
||||
sides: 2
|
||||
order: HCS
|
||||
layoutdata {
|
||||
sector_size: 256
|
||||
physical {
|
||||
start_sector: 0
|
||||
count: 16
|
||||
}
|
||||
}
|
||||
}
|
||||
tpi: 96
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
option {
|
||||
name: "side1"
|
||||
comment: "for AppleDOS file system access, read the volume on side 1 of a disk"
|
||||
|
||||
config {
|
||||
filesystem {
|
||||
appledos {
|
||||
filesystem_offset_sectors: 0x500
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
option_group {
|
||||
comment: "Filesystem and sector skew"
|
||||
|
||||
option {
|
||||
name: "nofs"
|
||||
comment: "use physical CHS sector order and no file system"
|
||||
}
|
||||
|
||||
option {
|
||||
name: "appledos"
|
||||
comment: "use AppleDOS soft sector skew and file system"
|
||||
|
||||
config {
|
||||
image_reader {
|
||||
filesystem_sector_order: true
|
||||
}
|
||||
|
||||
image_writer {
|
||||
filesystem_sector_order: true
|
||||
}
|
||||
|
||||
filesystem {
|
||||
type: APPLEDOS
|
||||
}
|
||||
|
||||
layout {
|
||||
layoutdata {
|
||||
filesystem {
|
||||
sector: 0
|
||||
sector: 13
|
||||
sector: 11
|
||||
sector: 9
|
||||
sector: 7
|
||||
sector: 5
|
||||
sector: 3
|
||||
sector: 1
|
||||
sector: 14
|
||||
sector: 12
|
||||
sector: 10
|
||||
sector: 8
|
||||
sector: 6
|
||||
sector: 4
|
||||
sector: 2
|
||||
sector: 15
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
option {
|
||||
name: "prodos"
|
||||
comment: "use ProDOS soft sector skew and filesystem"
|
||||
set_by_default: true
|
||||
|
||||
config {
|
||||
image_reader {
|
||||
filesystem_sector_order: true
|
||||
}
|
||||
|
||||
image_writer {
|
||||
filesystem_sector_order: true
|
||||
}
|
||||
|
||||
filesystem {
|
||||
type: PRODOS
|
||||
}
|
||||
|
||||
layout {
|
||||
layoutdata {
|
||||
filesystem {
|
||||
sector: 0
|
||||
sector: 2
|
||||
sector: 4
|
||||
sector: 6
|
||||
sector: 8
|
||||
sector: 10
|
||||
sector: 12
|
||||
sector: 14
|
||||
sector: 1
|
||||
sector: 3
|
||||
sector: 5
|
||||
sector: 7
|
||||
sector: 9
|
||||
sector: 11
|
||||
sector: 13
|
||||
sector: 15
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
option {
|
||||
name: "cpm"
|
||||
comment: "use CP/M soft sector skew and filesystem"
|
||||
|
||||
config {
|
||||
image_reader {
|
||||
filesystem_sector_order: true
|
||||
}
|
||||
|
||||
image_writer {
|
||||
filesystem_sector_order: true
|
||||
}
|
||||
|
||||
filesystem {
|
||||
type: CPMFS
|
||||
cpmfs {
|
||||
filesystem_start {
|
||||
track: 3
|
||||
}
|
||||
block_size: 4096
|
||||
dir_entries: 128
|
||||
}
|
||||
}
|
||||
|
||||
decoder {
|
||||
apple2 {
|
||||
side_one_track_offset: 80
|
||||
}
|
||||
}
|
||||
|
||||
encoder {
|
||||
apple2 {
|
||||
side_one_track_offset: 80
|
||||
}
|
||||
}
|
||||
|
||||
layout {
|
||||
layoutdata {
|
||||
# The boot tracks use ProDOS translation.
|
||||
|
||||
track: 0
|
||||
up_to_track: 2
|
||||
filesystem {
|
||||
sector: 0
|
||||
sector: 2
|
||||
sector: 4
|
||||
sector: 6
|
||||
sector: 8
|
||||
sector: 10
|
||||
sector: 12
|
||||
sector: 14
|
||||
sector: 1
|
||||
sector: 3
|
||||
sector: 5
|
||||
sector: 7
|
||||
sector: 9
|
||||
sector: 11
|
||||
sector: 13
|
||||
sector: 15
|
||||
}
|
||||
}
|
||||
|
||||
layoutdata {
|
||||
# The data tracks use their own, special translation.
|
||||
|
||||
track: 3
|
||||
up_to_track: 79
|
||||
filesystem {
|
||||
sector: 0
|
||||
sector: 3
|
||||
sector: 6
|
||||
sector: 9
|
||||
sector: 12
|
||||
sector: 15
|
||||
sector: 2
|
||||
sector: 5
|
||||
sector: 8
|
||||
sector: 11
|
||||
sector: 14
|
||||
sector: 1
|
||||
sector: 4
|
||||
sector: 7
|
||||
sector: 10
|
||||
sector: 13
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
comment: 'Apple II 140kB 5.25" 35 track SSDD'
|
||||
include: '_apple2'
|
||||
|
||||
image_reader {
|
||||
filename: "appleii140.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
image_writer {
|
||||
filename: "appleii140.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
layout {
|
||||
tracks: 35
|
||||
sides: 1
|
||||
layoutdata {
|
||||
sector_size: 256
|
||||
physical {
|
||||
start_sector: 0
|
||||
count: 16
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tpi: 48
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
comment: 'Apple II 640kB 5.25" 80 track DSDD'
|
||||
include: '_apple2'
|
||||
|
||||
image_reader {
|
||||
filename: "appleii640.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
image_writer {
|
||||
filename: "appleii640.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
layout {
|
||||
tracks: 80
|
||||
sides: 2
|
||||
order: HCS
|
||||
layoutdata {
|
||||
sector_size: 256
|
||||
physical {
|
||||
start_sector: 0
|
||||
count: 16
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tpi: 96
|
||||
|
||||
option {
|
||||
name: "side1"
|
||||
comment: "read the volume on side 1 of a disk (AppleDOS only)"
|
||||
message: "accessing volume on side 1"
|
||||
|
||||
config {
|
||||
filesystem {
|
||||
appledos {
|
||||
filesystem_offset_sectors: 0x500
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
180
src/formats/atarist.textpb
Normal file
180
src/formats/atarist.textpb
Normal file
@@ -0,0 +1,180 @@
|
||||
comment: 'Atari ST family'
|
||||
|
||||
encoder {
|
||||
ibm {
|
||||
trackdata {
|
||||
target_rotational_period_ms: 200
|
||||
target_clock_period_us: 4
|
||||
emit_iam: false
|
||||
gap0: 80
|
||||
gap2: 22
|
||||
gap3: 34
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
decoder {
|
||||
ibm {
|
||||
trackdata {
|
||||
ignore_sector: 66
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
option_group {
|
||||
comment: "Format variant"
|
||||
|
||||
option {
|
||||
name: "360"
|
||||
comment: '360kB 3.5" 80-track 9-sector SSDD'
|
||||
|
||||
config {
|
||||
layout {
|
||||
tracks: 80
|
||||
sides: 1
|
||||
layoutdata {
|
||||
sector_size: 512
|
||||
physical {
|
||||
start_sector: 1
|
||||
count: 9
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
option {
|
||||
name: "370"
|
||||
comment: '370kB 3.5" 82-track 9-sector SSDD'
|
||||
|
||||
config {
|
||||
layout {
|
||||
tracks: 82
|
||||
sides: 1
|
||||
layoutdata {
|
||||
sector_size: 512
|
||||
physical {
|
||||
start_sector: 1
|
||||
count: 9
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
option {
|
||||
name: "400"
|
||||
comment: '400kB 3.5" 80-track 10-sector SSDD'
|
||||
|
||||
config {
|
||||
layout {
|
||||
tracks: 80
|
||||
sides: 1
|
||||
layoutdata {
|
||||
sector_size: 512
|
||||
physical {
|
||||
start_sector: 1
|
||||
count: 10
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
option {
|
||||
name: "410"
|
||||
comment: '410kB 3.5" 82-track 10-sector SSDD'
|
||||
|
||||
config {
|
||||
layout {
|
||||
tracks: 82
|
||||
sides: 1
|
||||
layoutdata {
|
||||
sector_size: 512
|
||||
physical {
|
||||
start_sector: 1
|
||||
count: 10
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
option {
|
||||
name: "720"
|
||||
comment: '720kB 3.5" 80-track 9-sector DSDD'
|
||||
set_by_default: true
|
||||
|
||||
config {
|
||||
layout {
|
||||
tracks: 80
|
||||
sides: 2
|
||||
layoutdata {
|
||||
sector_size: 512
|
||||
physical {
|
||||
start_sector: 1
|
||||
count: 9
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
option {
|
||||
name: "740"
|
||||
comment: '740kB 3.5" 82-track 9-sector DSDD'
|
||||
|
||||
config {
|
||||
layout {
|
||||
tracks: 82
|
||||
sides: 2
|
||||
layoutdata {
|
||||
sector_size: 512
|
||||
physical {
|
||||
start_sector: 1
|
||||
count: 9
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
option {
|
||||
name: "800"
|
||||
comment: '800kB 3.5" 80-track 10-sector DSDD'
|
||||
|
||||
config {
|
||||
layout {
|
||||
tracks: 80
|
||||
sides: 2
|
||||
layoutdata {
|
||||
sector_size: 512
|
||||
physical {
|
||||
start_sector: 1
|
||||
count: 10
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
option {
|
||||
name: "820"
|
||||
comment: '820kB 3.5" 82-track 10-sector DSDD'
|
||||
|
||||
config {
|
||||
layout {
|
||||
tracks: 82
|
||||
sides: 2
|
||||
layoutdata {
|
||||
sector_size: 512
|
||||
physical {
|
||||
start_sector: 1
|
||||
count: 10
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
comment: 'Atari ST 360kB 3.5" 80-track 9-sector SSDD'
|
||||
|
||||
include: '_atari'
|
||||
|
||||
image_reader {
|
||||
filename: "atarist360.st"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
image_writer {
|
||||
filename: "atarist360.st"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
layout {
|
||||
tracks: 80
|
||||
sides: 1
|
||||
layoutdata {
|
||||
sector_size: 512
|
||||
physical {
|
||||
start_sector: 1
|
||||
count: 9
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
comment: 'Atari ST 370kB 3.5" 82-track 9-sector SSDD'
|
||||
|
||||
include: '_atari'
|
||||
|
||||
image_reader {
|
||||
filename: "atarist370.st"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
image_writer {
|
||||
filename: "atarist370.st"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
layout {
|
||||
tracks: 82
|
||||
sides: 1
|
||||
layoutdata {
|
||||
sector_size: 512
|
||||
physical {
|
||||
start_sector: 1
|
||||
count: 9
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
comment: 'Atari ST 400kB 3.5" 80-track 10-sector SSDD'
|
||||
|
||||
include: '_atari'
|
||||
|
||||
image_reader {
|
||||
filename: "atarist400.st"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
image_writer {
|
||||
filename: "atarist400.st"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
layout {
|
||||
tracks: 80
|
||||
sides: 1
|
||||
layoutdata {
|
||||
sector_size: 512
|
||||
physical {
|
||||
start_sector: 1
|
||||
count: 10
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
comment: 'Atari ST 410kB 3.5" 82-track 10-sector SSDD'
|
||||
|
||||
include: '_atari'
|
||||
|
||||
image_reader {
|
||||
filename: "atarist410.st"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
image_writer {
|
||||
filename: "atarist410.st"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
layout {
|
||||
tracks: 82
|
||||
sides: 1
|
||||
layoutdata {
|
||||
sector_size: 512
|
||||
physical {
|
||||
start_sector: 1
|
||||
count: 10
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
comment: 'Atari ST 720kB 3.5" 80-track 9-sector DSDD'
|
||||
|
||||
include: '_atari'
|
||||
|
||||
image_reader {
|
||||
filename: "atarist720.st"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
image_writer {
|
||||
filename: "atarist720.st"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
layout {
|
||||
tracks: 80
|
||||
sides: 2
|
||||
layoutdata {
|
||||
sector_size: 512
|
||||
physical {
|
||||
start_sector: 1
|
||||
count: 9
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
comment: 'Atari ST 740kB 3.5" 82-track 9-sector DSDD'
|
||||
|
||||
include: '_atari'
|
||||
|
||||
image_reader {
|
||||
filename: "atarist740.st"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
image_writer {
|
||||
filename: "atarist740.st"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
layout {
|
||||
tracks: 82
|
||||
sides: 2
|
||||
layoutdata {
|
||||
sector_size: 512
|
||||
physical {
|
||||
start_sector: 1
|
||||
count: 9
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
comment: 'Atari ST 800kB 3.5" 80-track 10-sector DSDD'
|
||||
|
||||
include: '_atari'
|
||||
|
||||
image_reader {
|
||||
filename: "atarist800.st"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
image_writer {
|
||||
filename: "atarist800.st"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
layout {
|
||||
tracks: 80
|
||||
sides: 2
|
||||
layoutdata {
|
||||
sector_size: 512
|
||||
physical {
|
||||
start_sector: 1
|
||||
count: 10
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
comment: 'Atari ST 820kB 3.5" 82-track 10-sector DSDD'
|
||||
|
||||
include: '_atari'
|
||||
|
||||
image_reader {
|
||||
filename: "atarist820.st"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
image_writer {
|
||||
filename: "atarist820.st"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
layout {
|
||||
tracks: 82
|
||||
sides: 2
|
||||
layoutdata {
|
||||
sector_size: 512
|
||||
physical {
|
||||
start_sector: 1
|
||||
count: 10
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
91
src/formats/brother.textpb
Normal file
91
src/formats/brother.textpb
Normal file
@@ -0,0 +1,91 @@
|
||||
comment: 'Brother GCR family'
|
||||
|
||||
image_reader {
|
||||
filename: "brother.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
image_writer {
|
||||
filename: "brother.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
encoder {
|
||||
brother {}
|
||||
}
|
||||
|
||||
decoder {
|
||||
brother {}
|
||||
}
|
||||
|
||||
option_group {
|
||||
comment: "Format variant"
|
||||
|
||||
option {
|
||||
name: "120"
|
||||
comment: '120kB 3.5" 39-track SS GCR'
|
||||
|
||||
config {
|
||||
layout {
|
||||
tracks: 39
|
||||
sides: 1
|
||||
layoutdata {
|
||||
sector_size: 256
|
||||
physical {
|
||||
start_sector: 0
|
||||
count: 12
|
||||
skew: 5
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
encoder {
|
||||
brother {
|
||||
format: BROTHER120
|
||||
}
|
||||
}
|
||||
|
||||
drive {
|
||||
head_bias: 0
|
||||
group_offset: 1
|
||||
}
|
||||
|
||||
filesystem {
|
||||
type: BROTHER120
|
||||
}
|
||||
|
||||
tpi: 48
|
||||
}
|
||||
}
|
||||
|
||||
option {
|
||||
name: "240"
|
||||
comment: '240kB 3.5" 78-track SS GCR'
|
||||
|
||||
config {
|
||||
layout {
|
||||
tracks: 78
|
||||
sides: 1
|
||||
layoutdata {
|
||||
sector_size: 256
|
||||
physical {
|
||||
start_sector: 0
|
||||
count: 12
|
||||
skew: 5
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
drive {
|
||||
head_bias: 3
|
||||
}
|
||||
|
||||
filesystem {
|
||||
type: FATFS
|
||||
}
|
||||
|
||||
tpi: 96
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
comment: 'Brother 120kB 3.5" 39-track SS GCR'
|
||||
|
||||
image_reader {
|
||||
filename: "brother120.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
image_writer {
|
||||
filename: "brother120.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
layout {
|
||||
tracks: 39
|
||||
sides: 1
|
||||
layoutdata {
|
||||
sector_size: 256
|
||||
physical {
|
||||
start_sector: 0
|
||||
count: 12
|
||||
skew: 5
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
encoder {
|
||||
brother {
|
||||
format: BROTHER120
|
||||
}
|
||||
}
|
||||
|
||||
decoder {
|
||||
brother {}
|
||||
}
|
||||
|
||||
drive {
|
||||
head_bias: 0
|
||||
group_offset: 1
|
||||
}
|
||||
|
||||
tpi: 48
|
||||
|
||||
filesystem {
|
||||
type: BROTHER120
|
||||
}
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
comment: 'Brother 240kB 3.5" 78-track SS GCR'
|
||||
|
||||
image_reader {
|
||||
filename: "brother240.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
image_writer {
|
||||
filename: "brother240.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
layout {
|
||||
tracks: 78
|
||||
sides: 1
|
||||
layoutdata {
|
||||
sector_size: 256
|
||||
physical {
|
||||
start_sector: 0
|
||||
count: 12
|
||||
skew: 5
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
encoder {
|
||||
brother {}
|
||||
}
|
||||
|
||||
decoder {
|
||||
brother {}
|
||||
}
|
||||
|
||||
drive {
|
||||
head_bias: 3
|
||||
}
|
||||
|
||||
filesystem {
|
||||
type: FATFS
|
||||
}
|
||||
|
||||
@@ -1,37 +1,16 @@
|
||||
FORMATS = \
|
||||
_acornadfs8 \
|
||||
_acornadfs32 \
|
||||
_apple2 \
|
||||
_atari \
|
||||
_micropolis \
|
||||
_northstar \
|
||||
_mx \
|
||||
40track_drive \
|
||||
acornadfs160 \
|
||||
acornadfs320 \
|
||||
acornadfs640 \
|
||||
acornadfs800 \
|
||||
acornadfs1600 \
|
||||
acornadfs \
|
||||
acorndfs \
|
||||
aeslanier \
|
||||
agat840 \
|
||||
amiga \
|
||||
ampro400 \
|
||||
ampro800 \
|
||||
ampro \
|
||||
apple2_drive \
|
||||
appleii140 \
|
||||
appleii640 \
|
||||
atarist360 \
|
||||
atarist370 \
|
||||
atarist400 \
|
||||
atarist410 \
|
||||
atarist720 \
|
||||
atarist740 \
|
||||
atarist800 \
|
||||
atarist820 \
|
||||
apple2 \
|
||||
atarist \
|
||||
bk800 \
|
||||
brother120 \
|
||||
brother240 \
|
||||
brother \
|
||||
commodore1541 \
|
||||
commodore1581 \
|
||||
cmd_fd2000 \
|
||||
@@ -39,44 +18,22 @@ FORMATS = \
|
||||
epsonpf10 \
|
||||
f85 \
|
||||
fb100 \
|
||||
hp9121 \
|
||||
hplif770 \
|
||||
hplif \
|
||||
ibm \
|
||||
ibm1200 \
|
||||
ibm1232 \
|
||||
ibm1440 \
|
||||
ibm180 \
|
||||
ibm160 \
|
||||
ibm360 \
|
||||
ibm320 \
|
||||
ibm720 \
|
||||
icl30 \
|
||||
mac400 \
|
||||
mac800 \
|
||||
micropolis143 \
|
||||
micropolis287 \
|
||||
micropolis315 \
|
||||
micropolis630 \
|
||||
mx110 \
|
||||
mx220_ds \
|
||||
mx220_ss \
|
||||
mx440 \
|
||||
mac \
|
||||
micropolis \
|
||||
mx \
|
||||
n88basic \
|
||||
northstar175 \
|
||||
northstar350 \
|
||||
northstar87 \
|
||||
northstar \
|
||||
psos800 \
|
||||
rolandd20 \
|
||||
rx50 \
|
||||
shugart_drive \
|
||||
smaky6 \
|
||||
tids990 \
|
||||
tiki90 \
|
||||
tiki200 \
|
||||
tiki400 \
|
||||
tiki800 \
|
||||
victor9k_ds \
|
||||
victor9k_ss \
|
||||
tiki \
|
||||
victor9k \
|
||||
zilogmcz \
|
||||
|
||||
$(OBJDIR)/src/formats/format_%.o: $(OBJDIR)/src/formats/format_%.cc
|
||||
|
||||
@@ -64,27 +64,30 @@ filesystem {
|
||||
type: CBMFS
|
||||
}
|
||||
|
||||
option {
|
||||
name: "35"
|
||||
comment: "35-track variant (default)"
|
||||
message: "using 35-track variant"
|
||||
option_group {
|
||||
comment: "Format family"
|
||||
|
||||
option {
|
||||
name: "171"
|
||||
comment: "35-track variant"
|
||||
set_by_default: true
|
||||
|
||||
config {
|
||||
layout {
|
||||
tracks: 35
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
option {
|
||||
name: "40"
|
||||
option {
|
||||
name: "192"
|
||||
comment: "40-track variant"
|
||||
message: "using 40-track variant"
|
||||
|
||||
config {
|
||||
layout {
|
||||
tracks: 40
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
comment: 'Hewlett-Packard 9121 264kB 3.5" SSDD'
|
||||
|
||||
image_reader {
|
||||
filename: "hp9121.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
layout {
|
||||
tracks: 66
|
||||
sides: 1
|
||||
layoutdata {
|
||||
sector_size: 256
|
||||
physical {
|
||||
sector: 0
|
||||
sector: 4
|
||||
sector: 8
|
||||
sector: 12
|
||||
sector: 1
|
||||
sector: 5
|
||||
sector: 9
|
||||
sector: 13
|
||||
sector: 2
|
||||
sector: 6
|
||||
sector: 10
|
||||
sector: 14
|
||||
sector: 3
|
||||
sector: 7
|
||||
sector: 11
|
||||
sector: 15
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
encoder {
|
||||
ibm {
|
||||
trackdata {
|
||||
emit_iam: false
|
||||
target_rotational_period_ms: 200
|
||||
target_clock_period_us: 4
|
||||
gap0: 80
|
||||
gap2: 22
|
||||
gap3: 44
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
decoder {
|
||||
ibm {}
|
||||
}
|
||||
143
src/formats/hplif.textpb
Normal file
143
src/formats/hplif.textpb
Normal file
@@ -0,0 +1,143 @@
|
||||
comment: 'Hewlett-Packard LIF family'
|
||||
|
||||
drive {
|
||||
high_density: false
|
||||
}
|
||||
|
||||
image_reader {
|
||||
filename: "hplif.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
image_writer {
|
||||
filename: "hplif.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
decoder {
|
||||
ibm {
|
||||
}
|
||||
}
|
||||
|
||||
filesystem {
|
||||
type: LIF
|
||||
}
|
||||
|
||||
tpi: 96
|
||||
|
||||
option_group {
|
||||
comment: "Format family"
|
||||
|
||||
option {
|
||||
name: "264"
|
||||
comment: '264kB 3.5" 66-track SSDD; HP9121 format'
|
||||
|
||||
config {
|
||||
layout {
|
||||
tracks: 66
|
||||
sides: 1
|
||||
layoutdata {
|
||||
sector_size: 256
|
||||
physical {
|
||||
sector: 0
|
||||
sector: 4
|
||||
sector: 8
|
||||
sector: 12
|
||||
sector: 1
|
||||
sector: 5
|
||||
sector: 9
|
||||
sector: 13
|
||||
sector: 2
|
||||
sector: 6
|
||||
sector: 10
|
||||
sector: 14
|
||||
sector: 3
|
||||
sector: 7
|
||||
sector: 11
|
||||
sector: 15
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
encoder {
|
||||
ibm {
|
||||
trackdata {
|
||||
emit_iam: false
|
||||
target_rotational_period_ms: 200
|
||||
target_clock_period_us: 4
|
||||
gap0: 80
|
||||
gap2: 22
|
||||
gap3: 44
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
option {
|
||||
name: "616"
|
||||
comment: '616kB 3.5" 77-track DSDD'
|
||||
|
||||
config {
|
||||
layout {
|
||||
tracks: 77
|
||||
sides: 2
|
||||
layoutdata {
|
||||
sector_size: 256
|
||||
physical {
|
||||
start_sector: 1
|
||||
count: 16
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
encoder {
|
||||
ibm {
|
||||
trackdata {
|
||||
target_rotational_period_ms: 200
|
||||
target_clock_period_us: 4
|
||||
emit_iam: false
|
||||
gap0: 80
|
||||
gap2: 22
|
||||
gap3: 40
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
option {
|
||||
name: "770"
|
||||
comment: '770kB 3.5" 77-track DSDD'
|
||||
|
||||
config {
|
||||
layout {
|
||||
tracks: 77
|
||||
sides: 2
|
||||
layoutdata {
|
||||
sector_size: 1024
|
||||
physical {
|
||||
sector: 1
|
||||
sector: 2
|
||||
sector: 3
|
||||
sector: 4
|
||||
sector: 5
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
encoder {
|
||||
ibm {
|
||||
trackdata {
|
||||
target_rotational_period_ms: 200
|
||||
target_clock_period_us: 4
|
||||
gap0: 80
|
||||
gap2: 22
|
||||
gap3: 80
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
comment: 'Hewlett-Packard LIF 770kB 3.5" DSDD'
|
||||
|
||||
drive {
|
||||
high_density: false
|
||||
rotational_period_ms: 200
|
||||
}
|
||||
|
||||
image_reader {
|
||||
filename: "hplif770.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
image_writer {
|
||||
filename: "hplif770.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
layout {
|
||||
tracks: 77
|
||||
sides: 2
|
||||
layoutdata {
|
||||
sector_size: 1024
|
||||
physical {
|
||||
sector: 1
|
||||
sector: 2
|
||||
sector: 3
|
||||
sector: 4
|
||||
sector: 5
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
encoder {
|
||||
ibm {
|
||||
trackdata {
|
||||
target_rotational_period_ms: 200
|
||||
target_clock_period_us: 4
|
||||
gap0: 80
|
||||
gap2: 22
|
||||
gap3: 80
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
decoder {
|
||||
ibm {
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,9 @@
|
||||
comment: 'PC 3.5"/5.25" autodetect double sided format'
|
||||
comment: 'Generic PC 3.5"/5.25" family'
|
||||
|
||||
image_reader {
|
||||
filename: "ibm.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
image_writer {
|
||||
filename: "ibm.img"
|
||||
@@ -9,9 +14,255 @@ decoder {
|
||||
ibm {}
|
||||
}
|
||||
|
||||
heads {
|
||||
start: 0
|
||||
end: 1
|
||||
filesystem {
|
||||
type: FATFS
|
||||
}
|
||||
|
||||
tpi: 96
|
||||
|
||||
option_group {
|
||||
comment: "Format variant"
|
||||
|
||||
option {
|
||||
name: "auto"
|
||||
comment: 'try to autodetect the format (unreliable)'
|
||||
set_by_default: true
|
||||
|
||||
config {}
|
||||
}
|
||||
|
||||
option {
|
||||
name: "160"
|
||||
comment: '160kB 5.25" 40-track 8-sector SSDD'
|
||||
|
||||
config {
|
||||
layout {
|
||||
tracks: 40
|
||||
sides: 1
|
||||
layoutdata {
|
||||
sector_size: 512
|
||||
physical {
|
||||
start_sector: 1
|
||||
count: 8
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
encoder {
|
||||
ibm {
|
||||
trackdata {
|
||||
target_rotational_period_ms: 167
|
||||
target_clock_period_us: 3.333
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tpi: 48
|
||||
}
|
||||
}
|
||||
|
||||
option {
|
||||
name: "180"
|
||||
comment: '180kB 5.25" 40-track 9-sector SSDD'
|
||||
|
||||
config {
|
||||
layout {
|
||||
tracks: 40
|
||||
sides: 1
|
||||
layoutdata {
|
||||
sector_size: 512
|
||||
physical {
|
||||
start_sector: 1
|
||||
count: 9
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
encoder {
|
||||
ibm {
|
||||
trackdata {
|
||||
target_rotational_period_ms: 167
|
||||
target_clock_period_us: 3.333
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tpi: 48
|
||||
}
|
||||
}
|
||||
|
||||
option {
|
||||
name: "320"
|
||||
comment: '320kB 5.25" 40-track 8-sector DSDD'
|
||||
|
||||
config {
|
||||
layout {
|
||||
tracks: 40
|
||||
sides: 2
|
||||
layoutdata {
|
||||
sector_size: 512
|
||||
physical {
|
||||
start_sector: 1
|
||||
count: 8
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
encoder {
|
||||
ibm {
|
||||
trackdata {
|
||||
target_rotational_period_ms: 167
|
||||
target_clock_period_us: 3.333
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tpi: 48
|
||||
}
|
||||
}
|
||||
|
||||
option {
|
||||
name: "360"
|
||||
comment: '360kB 5.25" 40-track 9-sector DSDD'
|
||||
|
||||
config {
|
||||
layout {
|
||||
tracks: 40
|
||||
sides: 2
|
||||
layoutdata {
|
||||
sector_size: 512
|
||||
physical {
|
||||
start_sector: 1
|
||||
count: 9
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
encoder {
|
||||
ibm {
|
||||
trackdata {
|
||||
target_rotational_period_ms: 167
|
||||
target_clock_period_us: 3.333
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tpi: 48
|
||||
}
|
||||
}
|
||||
|
||||
option {
|
||||
name: "720"
|
||||
comment: '720kB 5.25"/3.5" 80-track 9-sector DSDD'
|
||||
|
||||
config {
|
||||
layout {
|
||||
tracks: 80
|
||||
sides: 2
|
||||
layoutdata {
|
||||
sector_size: 512
|
||||
physical {
|
||||
start_sector: 1
|
||||
count: 9
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
encoder {
|
||||
ibm {
|
||||
trackdata {
|
||||
# This also works on 166ms drives (producing a physical clock of
|
||||
# 3.33us).
|
||||
target_rotational_period_ms: 200
|
||||
target_clock_period_us: 4
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
option {
|
||||
name: "1200"
|
||||
comment: '1200kB 5.25" 80-track 15-sector DSHD'
|
||||
|
||||
config {
|
||||
layout {
|
||||
tracks: 80
|
||||
sides: 2
|
||||
layoutdata {
|
||||
sector_size: 512
|
||||
physical {
|
||||
start_sector: 1
|
||||
count: 15
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
encoder {
|
||||
ibm {
|
||||
trackdata {
|
||||
target_rotational_period_ms: 167
|
||||
target_clock_period_us: 2
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
option {
|
||||
name: "1232"
|
||||
comment: '1232kB 5.25"/3.5" 77-track 8-sector DSHD'
|
||||
|
||||
config {
|
||||
layout {
|
||||
tracks: 77
|
||||
sides: 2
|
||||
layoutdata {
|
||||
sector_size: 1024
|
||||
physical {
|
||||
start_sector: 1
|
||||
count: 8
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
encoder {
|
||||
ibm {
|
||||
trackdata {
|
||||
target_rotational_period_ms: 167
|
||||
target_clock_period_us: 2
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
option {
|
||||
name: "1440"
|
||||
comment: '1440kB 3.5" 80-track 18-sector DSHD'
|
||||
|
||||
config {
|
||||
layout {
|
||||
tracks: 80
|
||||
sides: 2
|
||||
layoutdata {
|
||||
sector_size: 512
|
||||
physical {
|
||||
start_sector: 1
|
||||
count: 18
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
encoder {
|
||||
ibm {
|
||||
trackdata {
|
||||
target_rotational_period_ms: 200
|
||||
target_clock_period_us: 2
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
comment: 'PC 1200kB 5.25" 80-track 15-sector DSHD'
|
||||
|
||||
image_reader {
|
||||
filename: "ibm1200.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
image_writer {
|
||||
filename: "ibm1200.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
layout {
|
||||
tracks: 80
|
||||
sides: 2
|
||||
layoutdata {
|
||||
sector_size: 512
|
||||
physical {
|
||||
start_sector: 1
|
||||
count: 15
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
encoder {
|
||||
ibm {
|
||||
trackdata {
|
||||
target_rotational_period_ms: 167
|
||||
target_clock_period_us: 2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
decoder {
|
||||
ibm {}
|
||||
}
|
||||
|
||||
drive {
|
||||
high_density: true
|
||||
}
|
||||
|
||||
filesystem {
|
||||
type: FATFS
|
||||
}
|
||||
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
comment: 'Japanese PC 1232kB 5.25"/3.5" 77-track 8-sector DSHD'
|
||||
|
||||
image_reader {
|
||||
filename: "ibm1232.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
image_writer {
|
||||
filename: "ibm1232.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
layout {
|
||||
tracks: 77
|
||||
sides: 2
|
||||
layoutdata {
|
||||
sector_size: 1024
|
||||
physical {
|
||||
start_sector: 1
|
||||
count: 8
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
encoder {
|
||||
ibm {
|
||||
trackdata {
|
||||
target_rotational_period_ms: 167
|
||||
target_clock_period_us: 2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
decoder {
|
||||
ibm {}
|
||||
}
|
||||
|
||||
drive {
|
||||
high_density: true
|
||||
}
|
||||
|
||||
filesystem {
|
||||
type: FATFS
|
||||
}
|
||||
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
comment: 'PC 1440kB 3.5" 80-track 18-sector DSHD'
|
||||
|
||||
image_reader {
|
||||
filename: "ibm1440.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
image_writer {
|
||||
filename: "ibm1440.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
layout {
|
||||
tracks: 80
|
||||
sides: 2
|
||||
layoutdata {
|
||||
sector_size: 512
|
||||
physical {
|
||||
start_sector: 1
|
||||
count: 18
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
encoder {
|
||||
ibm {
|
||||
trackdata {
|
||||
target_rotational_period_ms: 200
|
||||
target_clock_period_us: 2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
decoder {
|
||||
ibm {}
|
||||
}
|
||||
|
||||
filesystem {
|
||||
type: FATFS
|
||||
}
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
comment: 'PC 160kB 5.25" 40-track 8-sector SSDD'
|
||||
|
||||
image_reader {
|
||||
filename: "ibm160.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
image_writer {
|
||||
filename: "ibm160.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
layout {
|
||||
tracks: 40
|
||||
sides: 1
|
||||
layoutdata {
|
||||
sector_size: 512
|
||||
physical {
|
||||
start_sector: 1
|
||||
count: 8
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
encoder {
|
||||
ibm {
|
||||
trackdata {
|
||||
target_rotational_period_ms: 167
|
||||
target_clock_period_us: 3.333
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
decoder {
|
||||
ibm {}
|
||||
}
|
||||
|
||||
drive {
|
||||
high_density: false
|
||||
}
|
||||
|
||||
tpi: 48
|
||||
|
||||
filesystem {
|
||||
type: FATFS
|
||||
}
|
||||
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
comment: 'PC 180kB 5.25" 40-track 9-sector SSDD'
|
||||
|
||||
image_reader {
|
||||
filename: "ibm180.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
image_writer {
|
||||
filename: "ibm180.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
layout {
|
||||
tracks: 40
|
||||
sides: 1
|
||||
layoutdata {
|
||||
sector_size: 512
|
||||
physical {
|
||||
start_sector: 1
|
||||
count: 9
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
encoder {
|
||||
ibm {
|
||||
trackdata {
|
||||
target_rotational_period_ms: 167
|
||||
target_clock_period_us: 3.333
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
decoder {
|
||||
ibm {}
|
||||
}
|
||||
|
||||
drive {
|
||||
high_density: false
|
||||
}
|
||||
|
||||
tpi: 48
|
||||
|
||||
filesystem {
|
||||
type: FATFS
|
||||
}
|
||||
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
comment: 'PC 320kB 5.25" 40-track 8-sector DSDD'
|
||||
|
||||
image_reader {
|
||||
filename: "ibm320.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
image_writer {
|
||||
filename: "ibm320.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
layout {
|
||||
tracks: 40
|
||||
sides: 2
|
||||
layoutdata {
|
||||
sector_size: 512
|
||||
physical {
|
||||
start_sector: 1
|
||||
count: 8
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
encoder {
|
||||
ibm {
|
||||
trackdata {
|
||||
target_rotational_period_ms: 167
|
||||
target_clock_period_us: 3.333
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
decoder {
|
||||
ibm {}
|
||||
}
|
||||
|
||||
tpi: 48
|
||||
|
||||
filesystem {
|
||||
type: FATFS
|
||||
}
|
||||
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
comment: 'PC 360kB 5.25" 40-track 9-sector DSDD'
|
||||
|
||||
image_reader {
|
||||
filename: "ibm360.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
image_writer {
|
||||
filename: "ibm360.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
layout {
|
||||
tracks: 40
|
||||
sides: 2
|
||||
layoutdata {
|
||||
sector_size: 512
|
||||
physical {
|
||||
start_sector: 1
|
||||
count: 9
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
encoder {
|
||||
ibm {
|
||||
trackdata {
|
||||
target_rotational_period_ms: 167
|
||||
target_clock_period_us: 3.333
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
decoder {
|
||||
ibm {}
|
||||
}
|
||||
|
||||
tpi: 48
|
||||
|
||||
filesystem {
|
||||
type: FATFS
|
||||
}
|
||||
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
comment: 'PC 720kB 5.25"/3.5" 80-track 9-sector DSDD'
|
||||
|
||||
image_reader {
|
||||
filename: "ibm720.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
image_writer {
|
||||
filename: "ibm720.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
layout {
|
||||
tracks: 80
|
||||
sides: 2
|
||||
layoutdata {
|
||||
sector_size: 512
|
||||
physical {
|
||||
start_sector: 1
|
||||
count: 9
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
encoder {
|
||||
ibm {
|
||||
trackdata {
|
||||
# This also works on 166ms drives (producing a physical clock of
|
||||
# 3.33us).
|
||||
target_rotational_period_ms: 200
|
||||
target_clock_period_us: 4
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
decoder {
|
||||
ibm {}
|
||||
}
|
||||
|
||||
drive {
|
||||
high_density: false
|
||||
}
|
||||
|
||||
filesystem {
|
||||
type: FATFS
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
comment: 'Macintosh 800kB 3.5" DSDD GCR'
|
||||
comment: 'Macintosh GCR family'
|
||||
|
||||
image_reader {
|
||||
filename: "mac800.dsk"
|
||||
filename: "mac.dsk"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
image_writer {
|
||||
filename: "mac800.dsk"
|
||||
filename: "mac.dsk"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
@@ -64,8 +64,47 @@ decoder {
|
||||
macintosh {}
|
||||
}
|
||||
|
||||
filesystem {
|
||||
option_group {
|
||||
comment: "Format variant"
|
||||
|
||||
option {
|
||||
name: "400"
|
||||
comment: "400kB 80-track SSDD"
|
||||
|
||||
config {
|
||||
layout {
|
||||
sides: 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
option {
|
||||
name: "800"
|
||||
comment: "800kB 80-track DSDD"
|
||||
set_by_default: true
|
||||
|
||||
config {
|
||||
layout {
|
||||
sides: 2
|
||||
}
|
||||
|
||||
filesystem {
|
||||
type: MACHFS
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
option {
|
||||
name: "metadata"
|
||||
comment: "read/write 524 byte sectors"
|
||||
|
||||
config {
|
||||
layout {
|
||||
layoutdata {
|
||||
sector_size: 524
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
comment: 'Macintosh 400kB 3.5" SSDD GCR'
|
||||
|
||||
image_reader {
|
||||
filename: "mac400.dsk"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
image_writer {
|
||||
filename: "mac400.dsk"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
layout {
|
||||
tracks: 80
|
||||
sides: 1
|
||||
layoutdata {
|
||||
sector_size: 512
|
||||
physical {
|
||||
start_sector: 0
|
||||
skew: 6
|
||||
}
|
||||
}
|
||||
layoutdata {
|
||||
track: 0
|
||||
up_to_track: 15
|
||||
physical {
|
||||
count: 12
|
||||
}
|
||||
}
|
||||
layoutdata {
|
||||
track: 16
|
||||
up_to_track: 31
|
||||
physical {
|
||||
count: 11
|
||||
}
|
||||
}
|
||||
layoutdata {
|
||||
track: 32
|
||||
up_to_track: 47
|
||||
physical {
|
||||
count: 10
|
||||
}
|
||||
}
|
||||
layoutdata {
|
||||
track: 48
|
||||
up_to_track: 63
|
||||
physical {
|
||||
count: 9
|
||||
}
|
||||
}
|
||||
layoutdata {
|
||||
track: 64
|
||||
up_to_track: 79
|
||||
physical {
|
||||
count: 8
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
encoder {
|
||||
macintosh {}
|
||||
}
|
||||
|
||||
decoder {
|
||||
macintosh {}
|
||||
}
|
||||
113
src/formats/micropolis.textpb
Normal file
113
src/formats/micropolis.textpb
Normal file
@@ -0,0 +1,113 @@
|
||||
comment: ' Micropolis format family'
|
||||
|
||||
drive {
|
||||
hard_sector_count: 16
|
||||
}
|
||||
|
||||
image_reader {
|
||||
filename: "micropolis.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
image_writer {
|
||||
filename: "micropolis.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
layout {
|
||||
layoutdata {
|
||||
sector_size: 256
|
||||
physical {
|
||||
start_sector: 0
|
||||
count: 16
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
encoder {
|
||||
micropolis {}
|
||||
}
|
||||
|
||||
decoder {
|
||||
micropolis {}
|
||||
}
|
||||
|
||||
option {
|
||||
name: "vgi"
|
||||
comment: "Read/write VGI format images with 275 bytes per sector"
|
||||
|
||||
config {
|
||||
image_reader {
|
||||
filename: "micropolis.vgi"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
image_writer {
|
||||
filename: "micropolis.vgi"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
layout {
|
||||
layoutdata {
|
||||
sector_size: 275
|
||||
}
|
||||
}
|
||||
|
||||
decoder {
|
||||
micropolis {
|
||||
sector_output_size: 275
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
option_group {
|
||||
option {
|
||||
name: "143"
|
||||
comment: '143kB 5.25" SSDD hard-sectored; Micropolis MetaFloppy Mod I'
|
||||
|
||||
config {
|
||||
layout {
|
||||
tracks: 35
|
||||
sides: 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
option {
|
||||
name: "287"
|
||||
comment: '287kB 5.25" DSDD hard-sectored; Micropolis MetaFloppy Mod I'
|
||||
|
||||
config {
|
||||
layout {
|
||||
tracks: 35
|
||||
sides: 2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
option {
|
||||
name: "315"
|
||||
comment: '315kB 5.25" SSDD hard-sectored; Micropolis MetaFloppy Mod II'
|
||||
|
||||
config {
|
||||
layout {
|
||||
tracks: 77
|
||||
sides: 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
option {
|
||||
name: "630"
|
||||
comment: '630kB 5.25" DSDD hard-sectored; Micropolis MetaFloppy Mod II'
|
||||
|
||||
config {
|
||||
layout {
|
||||
tracks: 77
|
||||
sides: 2
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
comment: 'Micropolis MetaFloppy Mod I 143kB 5.25" SSDD hard-sectored'
|
||||
|
||||
include: '_micropolis'
|
||||
|
||||
layout {
|
||||
tracks: 35
|
||||
sides: 1
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
comment: 'Micropolis MetaFloppy Mod I 287kB 5.25" DSDD hard-sectored'
|
||||
|
||||
include: '_micropolis'
|
||||
|
||||
layout {
|
||||
tracks: 35
|
||||
sides: 2
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
comment: 'Micropolis MetaFloppy Mod II 315kB 5.25" SSDD hard-sectored'
|
||||
|
||||
include: '_micropolis'
|
||||
|
||||
layout {
|
||||
tracks: 77
|
||||
sides: 1
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
comment: 'Micropolis MetaFloppy Mod II 630kB 5.25" DSDD hard-sectored'
|
||||
|
||||
include: '_micropolis'
|
||||
|
||||
layout {
|
||||
tracks: 77
|
||||
sides: 2
|
||||
}
|
||||
76
src/formats/mx.textpb
Normal file
76
src/formats/mx.textpb
Normal file
@@ -0,0 +1,76 @@
|
||||
comment: 'DVK MX family'
|
||||
|
||||
image_writer {
|
||||
filename: "mx.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
layout {
|
||||
layoutdata {
|
||||
sector_size: 256
|
||||
physical {
|
||||
start_sector: 0
|
||||
count: 11
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
decoder {
|
||||
mx {}
|
||||
}
|
||||
|
||||
tpi: 48
|
||||
|
||||
option_group {
|
||||
comment: "Format family"
|
||||
|
||||
option {
|
||||
name: "110"
|
||||
comment: '110kB 5.25" 40-track SSSD'
|
||||
|
||||
config {
|
||||
layout {
|
||||
tracks: 40
|
||||
sides: 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
option {
|
||||
name: "220ds"
|
||||
comment: '220kB 5.25" 40-track DSSD'
|
||||
|
||||
config {
|
||||
layout {
|
||||
tracks: 40
|
||||
sides: 2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
option {
|
||||
name: "220ss"
|
||||
comment: '220kB 5.25" 80-track SSSD'
|
||||
|
||||
config {
|
||||
layout {
|
||||
tracks: 80
|
||||
sides: 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
option {
|
||||
name: "440"
|
||||
comment: '440kB 5.25" 80-track DSSD'
|
||||
set_by_default: true
|
||||
|
||||
config {
|
||||
layout {
|
||||
tracks: 80
|
||||
sides: 2
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
comment: 'DVK MX 110kB 5.25" (ro)'
|
||||
|
||||
include: '_mx'
|
||||
|
||||
layout {
|
||||
tracks: 40
|
||||
sides: 1
|
||||
}
|
||||
|
||||
tpi: 48
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
comment: 'DVK MX 220kB DS 40-track 5.25" (ro)'
|
||||
|
||||
include: '_mx'
|
||||
|
||||
layout {
|
||||
tracks: 40
|
||||
sides: 2
|
||||
}
|
||||
|
||||
tpi: 48
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
comment: 'DVK MX 220kB SS 80-track 5.25" (ro)'
|
||||
|
||||
include: '_mx'
|
||||
|
||||
layout {
|
||||
tracks: 80
|
||||
sides: 1
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
comment: 'DVK MX 440kB 5.25" (ro)'
|
||||
|
||||
include: '_mx'
|
||||
|
||||
layout {
|
||||
tracks: 80
|
||||
sides: 2
|
||||
}
|
||||
85
src/formats/northstar.textpb
Normal file
85
src/formats/northstar.textpb
Normal file
@@ -0,0 +1,85 @@
|
||||
comment: 'Northstar family'
|
||||
|
||||
image_reader {
|
||||
filename: "northstar.nsi"
|
||||
type: NSI
|
||||
}
|
||||
|
||||
image_writer {
|
||||
filename: "northstar.nsi"
|
||||
type: NSI
|
||||
}
|
||||
|
||||
layout {
|
||||
layoutdata {
|
||||
physical {
|
||||
start_sector: 0
|
||||
count: 10
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
drive {
|
||||
hard_sector_count: 10
|
||||
sync_with_index: true
|
||||
}
|
||||
|
||||
encoder {
|
||||
northstar {}
|
||||
}
|
||||
|
||||
decoder {
|
||||
northstar {}
|
||||
}
|
||||
|
||||
tpi: 48
|
||||
|
||||
option_group {
|
||||
comment: "Format variant"
|
||||
|
||||
option {
|
||||
name: "87"
|
||||
comment: '87.5kB 5.25" 35-track SSSD hard-sectored'
|
||||
|
||||
config {
|
||||
layout {
|
||||
tracks: 40
|
||||
sides: 1
|
||||
layoutdata {
|
||||
sector_size: 256
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
option {
|
||||
name: "175"
|
||||
comment: '175kB 5.25" 40-track SSDD hard-sectored'
|
||||
|
||||
config {
|
||||
layout {
|
||||
tracks: 40
|
||||
sides: 1
|
||||
layoutdata {
|
||||
sector_size: 512
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
option {
|
||||
name: "350"
|
||||
comment: '350kB 5.25" 40-track DSDD hard-sectored'
|
||||
set_by_default: true
|
||||
|
||||
config {
|
||||
layout {
|
||||
tracks: 40
|
||||
sides: 2
|
||||
layoutdata {
|
||||
sector_size: 512
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
comment: 'Northstar 175kB 5.25" 35-track SSDD hard-sectored'
|
||||
|
||||
include: '_northstar'
|
||||
|
||||
layout {
|
||||
tracks: 40
|
||||
sides: 1
|
||||
layoutdata {
|
||||
sector_size: 512
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
comment: 'Northstar 350kB 5.25" 35-track SSDD hard-sectored'
|
||||
|
||||
include: '_northstar'
|
||||
|
||||
layout {
|
||||
tracks: 40
|
||||
sides: 2
|
||||
layoutdata {
|
||||
sector_size: 512
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
comment: 'Northstar 87.5kB 5.25" 35-track SSSD hard-sectored'
|
||||
|
||||
include: '_northstar'
|
||||
|
||||
layout {
|
||||
tracks: 40
|
||||
sides: 1
|
||||
layoutdata {
|
||||
sector_size: 256
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
144
src/formats/tiki.textpb
Normal file
144
src/formats/tiki.textpb
Normal file
@@ -0,0 +1,144 @@
|
||||
comment: 'Tiki 100 family'
|
||||
|
||||
image_writer {
|
||||
filename: "tiki.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
decoder {
|
||||
ibm {}
|
||||
}
|
||||
|
||||
tpi: 48
|
||||
|
||||
option_group {
|
||||
comment: "Format variant"
|
||||
|
||||
option {
|
||||
name: "90"
|
||||
comment: '90kB 40-track 18-sector SSSD'
|
||||
|
||||
config {
|
||||
layout {
|
||||
tracks: 40
|
||||
sides: 1
|
||||
layoutdata {
|
||||
side: 0
|
||||
sector_size: 128
|
||||
physical {
|
||||
start_sector: 1
|
||||
count: 18
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
filesystem {
|
||||
type: CPMFS
|
||||
cpmfs {
|
||||
filesystem_start {
|
||||
track: 3
|
||||
}
|
||||
block_size: 1024
|
||||
dir_entries: 32
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
option {
|
||||
name: "200"
|
||||
comment: '200kB 40-track 10-sector SSSD'
|
||||
|
||||
config {
|
||||
layout {
|
||||
tracks: 40
|
||||
sides: 1
|
||||
layoutdata {
|
||||
side: 0
|
||||
sector_size: 512
|
||||
physical {
|
||||
start_sector: 1
|
||||
count: 10
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
filesystem {
|
||||
type: CPMFS
|
||||
cpmfs {
|
||||
filesystem_start {
|
||||
track: 2
|
||||
}
|
||||
block_size: 1024
|
||||
dir_entries: 64
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
option {
|
||||
name: "400"
|
||||
comment: '400kB 40-track 10-sector DSSD'
|
||||
|
||||
config {
|
||||
layout {
|
||||
tracks: 40
|
||||
sides: 2
|
||||
layoutdata {
|
||||
sector_size: 512
|
||||
physical {
|
||||
start_sector: 1
|
||||
count: 10
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
filesystem {
|
||||
type: CPMFS
|
||||
cpmfs {
|
||||
filesystem_start {
|
||||
side: 0
|
||||
track: 1
|
||||
}
|
||||
block_size: 2048
|
||||
dir_entries: 128
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
option {
|
||||
name: "800"
|
||||
comment: '800kB 80-track 10-sector DSSD'
|
||||
|
||||
config {
|
||||
layout {
|
||||
tracks: 80
|
||||
sides: 2
|
||||
layoutdata {
|
||||
sector_size: 512
|
||||
physical {
|
||||
start_sector: 1
|
||||
count: 10
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
filesystem {
|
||||
type: CPMFS
|
||||
cpmfs {
|
||||
filesystem_start {
|
||||
side: 0
|
||||
track: 1
|
||||
}
|
||||
block_size: 2048
|
||||
dir_entries: 128
|
||||
}
|
||||
}
|
||||
|
||||
tpi: 96
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
comment: 'Tiki 100 200kB 40-track 10-sector SSSD (ro)'
|
||||
|
||||
image_writer {
|
||||
filename: "tiki200.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
layout {
|
||||
tracks: 40
|
||||
sides: 1
|
||||
layoutdata {
|
||||
side: 0
|
||||
sector_size: 512
|
||||
physical {
|
||||
start_sector: 1
|
||||
count: 10
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
decoder {
|
||||
ibm {}
|
||||
}
|
||||
|
||||
filesystem {
|
||||
type: CPMFS
|
||||
cpmfs {
|
||||
filesystem_start {
|
||||
track: 2
|
||||
}
|
||||
block_size: 1024
|
||||
dir_entries: 64
|
||||
}
|
||||
}
|
||||
|
||||
tpi: 48
|
||||
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
comment: 'Tiki 100 400kB 40-track 10-sector DSSD (ro)'
|
||||
|
||||
image_writer {
|
||||
filename: "tiki400.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
layout {
|
||||
tracks: 40
|
||||
sides: 2
|
||||
layoutdata {
|
||||
sector_size: 512
|
||||
physical {
|
||||
start_sector: 1
|
||||
count: 10
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
decoder {
|
||||
ibm {}
|
||||
}
|
||||
|
||||
filesystem {
|
||||
type: CPMFS
|
||||
cpmfs {
|
||||
filesystem_start {
|
||||
side: 0
|
||||
track: 1
|
||||
}
|
||||
block_size: 2048
|
||||
dir_entries: 128
|
||||
}
|
||||
}
|
||||
|
||||
tpi: 48
|
||||
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
comment: 'Tiki 100 800kB 80-track 10-sector DSSD (ro)'
|
||||
|
||||
image_writer {
|
||||
filename: "tiki900.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
layout {
|
||||
tracks: 80
|
||||
sides: 2
|
||||
layoutdata {
|
||||
sector_size: 512
|
||||
physical {
|
||||
start_sector: 1
|
||||
count: 10
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
decoder {
|
||||
ibm {}
|
||||
}
|
||||
|
||||
filesystem {
|
||||
type: CPMFS
|
||||
cpmfs {
|
||||
filesystem_start {
|
||||
side: 0
|
||||
track: 1
|
||||
}
|
||||
block_size: 2048
|
||||
dir_entries: 128
|
||||
}
|
||||
}
|
||||
|
||||
tpi: 96
|
||||
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
comment: 'Tiki 100 90kB 40-track 18-sector SSSD (ro)'
|
||||
|
||||
image_writer {
|
||||
filename: "tiki90.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
layout {
|
||||
tracks: 40
|
||||
sides: 1
|
||||
layoutdata {
|
||||
side: 0
|
||||
sector_size: 128
|
||||
physical {
|
||||
start_sector: 1
|
||||
count: 18
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
decoder {
|
||||
ibm {}
|
||||
}
|
||||
|
||||
filesystem {
|
||||
type: CPMFS
|
||||
cpmfs {
|
||||
filesystem_start {
|
||||
track: 3
|
||||
}
|
||||
block_size: 1024
|
||||
dir_entries: 32
|
||||
}
|
||||
}
|
||||
|
||||
tpi: 48
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
comment: 'Victor 9000 / Sirius One 1224kB DSHD GCR variable sector)'
|
||||
comment: 'Victor 9000 / Sirius One family'
|
||||
|
||||
image_reader {
|
||||
filename: "victor9k_ds.img"
|
||||
filename: "victor9k.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
image_writer {
|
||||
filename: "victor9k_ds.img"
|
||||
filename: "victor9k.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
@@ -261,3 +261,30 @@ encoder {
|
||||
decoder {
|
||||
victor9k {}
|
||||
}
|
||||
|
||||
option_group {
|
||||
comment: "Format family"
|
||||
|
||||
option {
|
||||
name: "612"
|
||||
comment: '612kB 80-track DSHD GCR'
|
||||
|
||||
config {
|
||||
layout {
|
||||
sides: 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
option {
|
||||
name: "1224"
|
||||
comment: '1224kB 80-track DSHD GCR'
|
||||
|
||||
config {
|
||||
layout {
|
||||
sides: 2
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,188 +0,0 @@
|
||||
comment: 'Victor 9000 / Sirius One 612kB SSHD GCR variable sector)'
|
||||
|
||||
image_reader {
|
||||
filename: "victor9k.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
image_writer {
|
||||
filename: "victor9k.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
layout {
|
||||
tracks: 80
|
||||
sides: 1
|
||||
layoutdata {
|
||||
sector_size: 512
|
||||
physical {
|
||||
start_sector: 0
|
||||
}
|
||||
}
|
||||
layoutdata {
|
||||
track: 0
|
||||
up_to_track: 3
|
||||
physical {
|
||||
count: 19
|
||||
}
|
||||
}
|
||||
layoutdata {
|
||||
track: 4
|
||||
up_to_track: 15
|
||||
physical {
|
||||
count: 18
|
||||
}
|
||||
filesystem {
|
||||
start_sector: 0
|
||||
count: 18
|
||||
skew: 4
|
||||
}
|
||||
}
|
||||
layoutdata {
|
||||
track: 16
|
||||
up_to_track: 26
|
||||
physical {
|
||||
count: 17
|
||||
}
|
||||
filesystem {
|
||||
start_sector: 0
|
||||
count: 17
|
||||
skew: 4
|
||||
}
|
||||
}
|
||||
layoutdata {
|
||||
track: 27
|
||||
up_to_track: 37
|
||||
physical {
|
||||
count: 16
|
||||
}
|
||||
filesystem {
|
||||
start_sector: 0
|
||||
count: 16
|
||||
skew: 4
|
||||
}
|
||||
}
|
||||
layoutdata {
|
||||
track: 38
|
||||
up_to_track: 47
|
||||
physical {
|
||||
count: 15
|
||||
}
|
||||
filesystem {
|
||||
start_sector: 0
|
||||
count: 15
|
||||
skew: 4
|
||||
}
|
||||
}
|
||||
layoutdata {
|
||||
track: 48
|
||||
up_to_track: 59
|
||||
physical {
|
||||
count: 14
|
||||
}
|
||||
filesystem {
|
||||
start_sector: 0
|
||||
count: 14
|
||||
skew: 4
|
||||
}
|
||||
}
|
||||
layoutdata {
|
||||
track: 60
|
||||
up_to_track: 70
|
||||
physical {
|
||||
count: 13
|
||||
}
|
||||
filesystem {
|
||||
start_sector: 0
|
||||
count: 13
|
||||
skew: 4
|
||||
}
|
||||
}
|
||||
layoutdata {
|
||||
track: 71
|
||||
up_to_track: 79
|
||||
physical {
|
||||
count: 12
|
||||
}
|
||||
filesystem {
|
||||
start_sector: 0
|
||||
count: 12
|
||||
skew: 4
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
encoder {
|
||||
victor9k {
|
||||
trackdata {
|
||||
clock_period_us: 2.1367 # 468kHz
|
||||
post_index_gap_us: 500.0
|
||||
pre_header_sync_bits: 150
|
||||
post_header_gap_bits: 60
|
||||
pre_data_sync_bits: 40
|
||||
post_data_gap_bits: 300
|
||||
}
|
||||
trackdata {
|
||||
head: 0
|
||||
min_track: 0
|
||||
max_track: 3
|
||||
rotational_period_ms: 237.9
|
||||
}
|
||||
trackdata {
|
||||
head: 0
|
||||
min_track: 4
|
||||
max_track: 15
|
||||
rotational_period_ms: 224.5
|
||||
}
|
||||
trackdata {
|
||||
head: 0
|
||||
min_track: 16
|
||||
max_track: 26
|
||||
rotational_period_ms: 212.2
|
||||
}
|
||||
trackdata {
|
||||
head: 0
|
||||
min_track: 27
|
||||
max_track: 37
|
||||
rotational_period_ms: 199.9
|
||||
}
|
||||
trackdata {
|
||||
head: 0
|
||||
min_track: 38
|
||||
max_track: 47
|
||||
rotational_period_ms: 187.6
|
||||
}
|
||||
trackdata {
|
||||
head: 0
|
||||
min_track: 48
|
||||
max_track: 59
|
||||
rotational_period_ms: 175.3
|
||||
}
|
||||
trackdata {
|
||||
head: 0
|
||||
min_track: 60
|
||||
max_track: 70
|
||||
rotational_period_ms: 163.0
|
||||
}
|
||||
trackdata {
|
||||
head: 0
|
||||
min_track: 71
|
||||
max_track: 79
|
||||
rotational_period_ms: 149.6
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
decoder {
|
||||
victor9k {}
|
||||
}
|
||||
|
||||
filesystem {
|
||||
cpmfs {
|
||||
filesystem_start {
|
||||
track: 5
|
||||
}
|
||||
block_size: 2048
|
||||
dir_entries: 128
|
||||
}
|
||||
}
|
||||
@@ -577,43 +577,31 @@ private:
|
||||
_formatNames[formatChoice->GetSelection()];
|
||||
FlagGroup::parseConfigFile(formatName, formats);
|
||||
|
||||
std::set<std::string> exclusivityGroups;
|
||||
for (auto& option : config.option())
|
||||
for (auto& group : config.option_group())
|
||||
{
|
||||
if (option.has_exclusivity_group())
|
||||
exclusivityGroups.insert(option.exclusivity_group());
|
||||
}
|
||||
|
||||
if (config.option().empty())
|
||||
sizer->Add(new wxStaticText(formatOptionsContainer,
|
||||
wxID_ANY,
|
||||
"(no options for this format)"));
|
||||
else
|
||||
{
|
||||
/* Add grouped radiobuttons for anything in an exclusivity
|
||||
* group. */
|
||||
group.comment() + ":"));
|
||||
|
||||
for (auto& group : exclusivityGroups)
|
||||
{
|
||||
bool first = true;
|
||||
for (auto& option : config.option())
|
||||
bool valueSet = false;
|
||||
wxRadioButton* defaultButton = nullptr;
|
||||
for (auto& option : group.option())
|
||||
{
|
||||
if (option.exclusivity_group() != group)
|
||||
continue;
|
||||
|
||||
auto* rb = new wxRadioButton(formatOptionsContainer,
|
||||
wxID_ANY,
|
||||
option.comment());
|
||||
auto key =
|
||||
std::make_pair(formatName, option.name());
|
||||
option.comment(),
|
||||
wxDefaultPosition,
|
||||
wxDefaultSize,
|
||||
first ? wxRB_GROUP : 0);
|
||||
auto key = std::make_pair(formatName, option.name());
|
||||
sizer->Add(rb);
|
||||
|
||||
rb->Bind(wxEVT_RADIOBUTTON,
|
||||
[=](wxCommandEvent& e)
|
||||
{
|
||||
for (auto& option : config.option())
|
||||
for (auto& option : group.option())
|
||||
{
|
||||
if (option.exclusivity_group() == group)
|
||||
_formatOptions.erase(std::make_pair(
|
||||
formatName, option.name()));
|
||||
}
|
||||
@@ -623,30 +611,34 @@ private:
|
||||
OnControlsChanged(e);
|
||||
});
|
||||
|
||||
if (_formatOptions.find(key) !=
|
||||
_formatOptions.end())
|
||||
if (_formatOptions.find(key) != _formatOptions.end())
|
||||
{
|
||||
rb->SetValue(true);
|
||||
valueSet = true;
|
||||
}
|
||||
|
||||
if (option.set_by_default() || !defaultButton)
|
||||
defaultButton = rb;
|
||||
|
||||
if (first)
|
||||
rb->SetExtraStyle(wxRB_GROUP);
|
||||
first = false;
|
||||
}
|
||||
|
||||
if (!valueSet && defaultButton)
|
||||
defaultButton->SetValue(true);
|
||||
}
|
||||
|
||||
/* Anything that's _not_ in a group gets a checkbox. */
|
||||
|
||||
for (auto& option : config.option())
|
||||
{
|
||||
if (option.has_exclusivity_group())
|
||||
continue;
|
||||
|
||||
auto* choice = new wxCheckBox(
|
||||
formatOptionsContainer, wxID_ANY, option.comment());
|
||||
auto key = std::make_pair(formatName, option.name());
|
||||
sizer->Add(choice);
|
||||
|
||||
if (_formatOptions.find(key) != _formatOptions.end())
|
||||
choice->SetValue(true);
|
||||
choice->SetValue(
|
||||
(_formatOptions.find(key) != _formatOptions.end()) ||
|
||||
option.set_by_default());
|
||||
|
||||
choice->Bind(wxEVT_CHECKBOX,
|
||||
[=](wxCommandEvent& e)
|
||||
@@ -659,7 +651,11 @@ private:
|
||||
OnControlsChanged(e);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (config.option().empty() && config.option_group().empty())
|
||||
sizer->Add(new wxStaticText(formatOptionsContainer,
|
||||
wxID_ANY,
|
||||
"(no options for this format)"));
|
||||
}
|
||||
|
||||
formatOptionsContainer->SetSizerAndFit(sizer);
|
||||
|
||||
Reference in New Issue
Block a user