APD file structure
------------------

The APD file is a GZip compressed version of the original APD file.

Compressed file always starts:
    1F 8B 08 00 00 00 00 00 00 0B
    ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^
    |  |  |  |  |  |  |  |  |  |
    |  |  |  |  |  |  |  |  |  +- OS
    |  |  |  |  |  |  |  |  +---- xfl
    |  |  |  |  +--+--+--+------- time
    |  |  |  +------------------- gzip flags
    |  |  +---------------------- gzip compression*
    |  |
    +--+------------------------- gzip header

*  Compression method: 8 is the only supported format

Original APD file structure:
           0 - 7   "APDX0001" identifier
           8 - B   t0sd - Track 0 SD length in bits
           C - F   t0dd - Track 0 DD length in bits
          10 - 13  t0qd - Track 0 QD length in bits
          14 - 1F  t1sd - Track 1 SD length in bits
          20 - 23  t1dd - Track 1 DD length in bits
          24 - 27  t1qd - Track 1 QD length in bits
...                repeated to Track 159
        77C - 787  Track 160 (blank)
        7C4 - 7CF  Track 166 (blank)

              7D0  Track 0 SD data
+ (t0sd + 7) >> 3  Track 0 DD data
+ (t0dd + 7) >> 3  Track 0 QD data

+ (t0qd + 7) >> 3  Track 1 SD data
+ (t1sd + 7) >> 3  Track 1 DD data
+ (t1dd + 7) >> 3  Track 1 QD data

SD    data is big-endian raw FM words
DD/QD data is big-endian raw MFM words

As far as I can tell, the tracks are always sequential, so
physical tracks translate as:

Physical         APD
--------------   -------
Side 0 Track 0 > Track 0
Side 1 Track 0 > Track 1
Side 0 Track 1 > Track 2
etc.



MFM details:
------------

Sectors start at the byte following &44895545 - which may not be
byte aligned, so you have to step though a bit at a time

MFM track header (not in an APD, here for reference):

MFM    Byte
---    ----
5224   C2
5224   C2
??     FC
9254   4E (repeated 50 times)


MFM sector header:

MFM    Byte
----   ----
4489   A1
4489   A1
4489   A1
5554   FE (sector ID marker)
tttt
hhhh
ssss
LLLL
crc1      (CRC of ID)
crc2
9254   4E (repeated 22 times)
AAAA   00 (repeated 12 times)
4489   A1
4489   A1
4489   A1
5545   FB (data ID marker)
1<<(L+7) bytes of data
crc1      (CRC of data)
crc2
9254   4E (repeated 40 times)


FM details:
----------

FM sector header:

FM     Byte
----   ----
AAAA   00
AAAA   00
AAAA   00
AAAA   00
AAAA   00
AAAA   00
F57E   FE (sector ID marker)
tttt
hhhh
ssss
LLLL
crc1      (CRC of ID)
crc2
AAAA   00 (repeated 17 times)
F56A   FB (data ID marker)
1<<(L+7) bytes of data
crc1      (CRC of data)
crc2
AAAA   00 (repeated 10 times)


Where:
 tttt - Track number
 hhhh - Side (0 / 1)
 ssss - Sector number
 LLLL - Sector length (1 << LLLL+7)



Calculating sector timing:

The following equation is used to calculate each sectors timing
from the start of the track, whilst reading an APD file:

200 - ( (200 / (track length in bits))) * (bits left) )



JFD file structure
------------------

A JFD file is a gzip compressed version of the original JFD
file.

Official files should be named "[optional text name] Fxxxxxnn"
(see below for xxxx / nn explanation) eg "Fire & Ice (1995)
 (Warner Interactive Entertainment) F1015401" or shortened to
"F1015401" on an Arc that doesn't support long file names.

Compressed file always starts:
    1F 8B 08 00 00 00 00 00 02 0D
    ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^
    |  |  |  |  |  |  |  |  |  |
    |  |  |  |  |  |  |  |  |  +- OS (RISCOS)
    |  |  |  |  |  |  |  |  +---- xfl
    |  |  |  |  +--+--+--+------- time
    |  |  |  +------------------- gzip flags
    |  |  +---------------------- gzip compression*
    |  |
    +--+------------------------- gzip header

*  Compression method: 8 is the only supported format


Original JFD file structure:

+0   "JFDI" identifier
+4   Min. version of ADFFS required to handle file * 100
      eg 1.25 would be 125
+8   Memory allocation required to load file in bytes
      ie uncompressed file size
+12  Disc sequence number - SSSSnnnn
      Where:
        SSSS is the number of discs in this set
        nnnn is the number of this disc
+16  Game ID number (xxxxx) - official release ID of this
      floppy set.  Unofficial releases should be an ID of zero
+20  Image version number: VVVwwwww
      Where:
        VVV - major release version, 0 being initial release
      wwwww - minor version, reset to 0 on a major release
              and is incremented on each flush / save as
+24  Offset to Track Table, the end of which is denoted by
      the start of the Sector Table
+28  Offset to Sector Table, end of which is denoted by
      the start of the Data Table
+32  Offset to Data Table
+36  Offset to optional Delta Track Table.  Changes to the
      Track table are written here post initial release
      0 denotes not present
+40  Offset to optional Delta Sector Table.  Changes to the
      Sector table are written here post initial release
      0 denotes not present
+44  Offset to optional Delta Data Table.  Changes to the
      Data table are written here post initial release
      0 denotes not present
+48  Disc title.  eg "Fire & Ice (1995) (Warner Interactive
      Entertainment)", zero terminated
+304 ... future expansion space (additions in 2.04+)

+304 Bit flags:
      0 - Disk write protected
      1 - Disk is RW, write delta changes back to JFD
      2 - Protect CMOS required
      3 - Protect Modules required
      4 - Hide Hourglass
      5 - Requires Shift-Break to load
      6 - Remap video memory to 1FFFFFF downwards

      8 - ARM3 compatible
      9 - ARM250 compatible
     10 - ARM610/710 compatible
     11 - ARM7500 compatible
     12 - StrongArm compatible
     13 = ARMv5/v5/v7 compatible

     16 - RiscOS 2 compatible
     17 - RiscOS 3.1 compatible
     18 - RiscOS 3.5 compatible
     19 - RiscOS 3.7 compatible
     20 - RiscOS 3.8 / 4.x compatible
     21 - RiscOS 5.x compatible
     22 - RiscOS 6.x compatible
+308 FPS of the original game * 2 (eg for 12.5 FPS use 25)
+309 - 311 reserved
+312 Length of Obey file in bytes
+316 ... future expansion space (currently 0 bytes)

[Track Table]
+0 Track 0 offset within Sector Table
+4 Track 1 offset within Sector Table
...
+n*4 Track n offset within Sector Table
       n can be any value, although to allow writes should be at
       least 160.  For reference, APD's are 166
       A blank track is denoted by FFFFFFFF

[Sector Table]
+0 ttBdnnCs - Sector Header description (see below)
+4 Offset within Data Table of sector data, if this value is
     FFFFFFFF no data is associated with the sector.  In the
     case of a sector with a CRC flag set in C set, the sector
     is a stub to produce a specific error.

.. repeats for all sectors in track, two doubles (ie 8 bytes) per
     sector

+n FFFFFFFF - end of track marker

The above repeats for all tracks containing sector data.


[Data Table]
... X bytes of sector data in native byte format.
     Not necessarily in disc order, as sectors are located
     individually during reads.

[Obey file]
... Obey file used to boot the floppy


Sector Header description:  ttBdnnCs
Where:

tt - time of sector from start of index marker in milliseconds
     max being 200 (optional, required for duplicate sectors)
B  - Option bits
       bit 0 - sector data contains DiscOp 3 data for the track
       bit 1 - reserved
       bit 2 - reserved
       bit 3 - reserved
d  - Density value, where:
       1 - single
       2 - double
       4 - quad
       8 - octal
nn - Sector number
C  - CRC bits, where:
       bit 0 - ID CRC invalid
       bit 1 - Data CRC invalid
       bit 2 - reserved
       bit 3 - Slow sector (read at normal floppy speed)
s  - 1772 sector size, where:
       0 - 128 bytes
       1 - 256 bytes
       2 - 512 bytes
       3 - 1024 bytes



ConvRec internal structures
---------------------------

ConvRec sector table (16 bytes per entry):

+0  - sector
+1  - track
+2  - 0 normal sector read
      1 manually add sector ID without reading from the disc
      2 (+12) contains length of raw DiscOp 3 data
+3  - reserved (byte)
+4  - density
+5  - heads
+6  - secspertrack
+7  - log2secsize
+8  - discsize
+12 - 0 or DiscOp 3 data length
+16 - DiscOp 3 data (optional)



ADFFS recording structure (20 bytes per entry):
-------------------------

+0  - 00x000bc

 Where:
  c - DiscOp 0 / 1 / 2 / 3
        0 - verify
        1 - read sectors
        2 - write sectors
        3 - read track
        F - manually forced sector ID without data
  b -   DiscOp bits
         bit 0 - IDs requested on a DiscOp3
         bit 1 - scatter list
         bit 2 - escape conditions are ignored
         bit 3 - ignore timeout, wait forever
  x - Manually forced entry
         bit 0 - reserved (must be 0)
         bit 1 - perform a DiscOp 3 reading data instead of sector ID's
         bit 2 - slow read sector (it's read at actual floppy speed when read
                                   back through ADFFS)
         bit 3 - duplicate sector (re-read the sector until two differing
                                   sectors have been captured)

+4  - disc address
+8  - size of data read
+12 - ddhhssll - DiscRec
+16 - disc size

 Where:
  ll - log2 sector size (ie 8 - 256 byte)
  ss - Sectors per track
  hh - Number of heads
  dd - Density (1 - single, 2 - double, 3 - double+, 4 - quad, 8 - octal)

+16 - disc size
