Reenigne Disk Image Format:

Goals:
* preservation/archiving - ability to accurately represent any physical floppy disk as it would appear to the drive.
* emulation - ability to modify the image as the emulator formats and writes, accurate timing for when the DMAs occur
* interoperability with raw data image formats
  * if a raw image format is used and is rewritten but not formatted, it will be persisted in raw data image format.


File format description:

If a file is 160KB, 180KB, 320KB, 360KB, 720KB, 1440KB or 2880KB, just interpret it as raw data. If it's a structured file, make sure it is not one of these sizes by adding an extra padding byte if
necessary.

Otherwise, the structured file format is as follows:

Magic bytes: RDIF
Version word: Only 0 currently defined.
File compression word: 0 for uncompressed data follows, 1 for zlib compressed data follows
Creator string pointer word
Creator string length word
Label string pointer word
Label string length word
Description string pointer word
Description string length word
Medium word: 0 = 8" disk, 1 = 5.25" disk, 2 = 3.5" disk
Tracks per inch word: 48, 96, 100
Write enable word
RPM word
Bit rate word
FM/MFM word
Default number of bytes per sector (for "just the data" type blocks)
Default number of sectors per track (for "just the data" type blocks)

File base: this is offset 0 in the file
Number of entries in Block table word: N
Block table: N entries of:
  Offset word: relative to file base
  Size word: in bytes when uncompressed. Overlapping the index hole causes the next part to go onto the following track.
  Cylinder word: 24.8 signed fixed point, relative to track 0
  Head word: Should be an integer
  Track position word: .32 fixed point in revolutions, relative to index hole
  Data rate word: 24.8 bits per revolution
  Track width word: 24.8 bits, in tracks
  Media amplification: 24.8 bits. Normally 0x1.00 (or 0x0.00 for a laser hole). Value read = value written * amplification. As this is a property of the medium, not the message, it cannot be changed by format/write, so any media amplification boundaries persist across writes. If amplification == 0x00 then rewriting doesn't work at all.
  Type word:
    0 = just the data as 512 byte sectors (logical, not physical order)
    1 = data including gaps
    2 = FM/MFM flux-reversal data (two bits per one actual data bit)
    3 = raw flux measurement (4 bytes per one actual data bit)
  Block compression word: same meaning as file compression word
Raw block data chunks follow


Explanation:

A disk is an array of heads.

Think of each head as a rectangle, with angular-position on the X axis and distance-from-hub on the Y axis.
Each block then represents a sub-rectangle of this, with 1-dimensional bitmap data.
  A block may actually span multiple rectangles on multiple heads, but this is an optimization detail.

In memory, a head is stored as a binary tree (alternating between dividing in the angular and track axes)
  This makes it easy (O(log(N))) to find the "top-left" of a sub-block and therefore to find the data for a track


Implementation plan:

Initially assume a single block of type 0
Initially implement read only
Convert type 0 to type 1
Implement read of type 1
Implement write of type 1
Implement format of type 1
Convert type 1 back to type 0 if no data loss would be incurred (standard gaps)
Convert type 1 to type 2
Implement read of type 2
Implement write of type 2
Implement format of type 2
Convert type 2 back to type 1 if no data loss would be incurred (standard encoding)
Convert type 2 to type 3
Implement read of type 3
Implement write of type 3
Implement format of type 3
Convert type 3 back to type 2 if no data loss would be incurred (standard transitions)
Optimize as necessary


References:

http://www.kryoflux.com/
http://www.softpres.org/_media/files:ipfdoc102a.zip

