As of Applesauce 1.66, it is possible for users to be able to add their own format definitions to be used by Applesauce. When you add a format, it will automatically be recognized everywhere in the client software such as the Disk Analyzer and Fast Imager. In order to add new formats, there is an Applesauce directory in your Documents folder. Within this folder there is a Formats one that contains the file ibmsector_config.json
. The IBM sector configuration files are text files in JSON format. The root object of the JSON should be an array. A single file can have as may format descriptions as desired. Whenever you edit the ibmsector_config.json
, you will need to restart the Applesauce client in order to have it load the changes.
Creating a format definition is a highly technical process and if you are not very familiar with how disks are structured, this will likely seem a daunting task.
There is an example of a configuration file at the end of this document.
String - Required
This is a descriptive name of the format. It must be unique, but otherwise is only used for informational purposes.
ex: “name”: “IBM”
String - Required
This name is used by the Fast Imager to remember user preferences related to this format.
ex: “settings”: “IbmMFM”
String - Required
This is used by the Fast Imager when displaying the name of this format.
ex: “fastname”: “IBM”
[String]
An array of disk image format names that can be used to save images of this format. It uses the internal names of formats. Raw disk output (IMG) will always be available.
ex: “export”: [“any_imd”]
[String] - Required
Array of the physical type of media used as well as the encoding and density. It is represented as a string structured as {media}_{encoding}_{density}
. If the format supports more than a single value for either the media or density parameters you can use a *
as a wildcard value. Being as specific as possible speeds up the analysis process as it limits the number of comparisons that need to be done.
Media | Description |
---|---|
5.25 | 5.25“ Floppy Disk |
3.5 | 3.5” Floppy Disk |
8 | 8“ Floppy Disk |
Encoding | Description |
---|---|
fm | FM encoding |
mfm | MFM encoding |
m2fm | M2FM encoding |
Density | Description |
---|---|
250 | 250kbps (4µs cell window) also covers 125K FM |
500 | 500kbps (2µs cell window) |
ex: “encodingAndMedia”: [“5.25_mfm_*”,”8_mfm_500]
String
Bytes stored on disk are most commonly stored in “most significant bit” order, although some platforms store bytes in “least significant bit” order. This value allows you to specify which order should be used. If no value is provided, then it defaults to msb
.
Value | Description |
---|---|
msb | Most significant bit comes first |
lsb | Least significant bit comes first |
ex: “bitOrder”: “lsb”
String
Byte order of any values larger than 8-bits like the CRC-16. If no value is provided, then it defaults to “be”
.
Value | Description |
---|---|
be | Stored checksum is big endian |
le | Stored checksum is little endian |
ex: “addrCksumEndian”: “le”
[String] - Required
All disk formats have sync pattern(s) that inform the disk controller about how to synchronize itself to the proper start of bytes. Applesauce uses a sequence of 48 bits (6 bytes) that are represented by their hex values. Please note that the values used here are the values physically on the media for FM or MFM encoding, so every logical byte (8 bits) is represented by 16 bits. The last value of the sync pattern is also typically used as a start marker for the disk controller. If there are multiple possible sync sequences, then include them all.
ex: “syncPatterns”: [“AAAAAAAAFFEF”]
[String] - Required
Array of valid address field marker values in hex.
ex: “addrMarkers”: [“FE”]
Int - Required
Number of bytes from the last synchronization byte to the marker. FM encoding uses a marker that is also the synchronization byte, so it has a value of 0
. Whereas MFM encoding tends to have a sequence of 3 A1 bytes that are the synchronization bytes followed by the marker, so it has a value of 1
.
ex: “addrMarkerInset”: 1
Int - Required
Byte size of the address field following the marker.
ex: “addrFieldSize”: 6
Int - Required
Byte index of the start of the stored checksum relative to the address marker (0 = address marker).
ex: “addrStoredCRCIndex”: 5
Int - Required
Byte index of the first byte of the address field that needs to be checksummed, relative to the address marker (0 = address marker).
ex: “addrCRCFromIndex”: 1
Int - Required
Byte index of the last byte of the address field that needs to be checksummed, relative to the address marker (0 = address marker).
ex: “addrCRCToIndex”: 4
Int
Starting value (seed) of the CRC-16. If omitted, then it defaults to 65535
(FFFF hex).
ex: “addrCRCInit”: 0
Int
The polynomial to use for the CRC-16. If omitted, then it defaults to 4129
(1021 hex).
ex: “addrCRCPoly”: 0
Boolean
True if the input data should be reflected (bit reversed) before passing to the CRC-16. Defaults to false
.
ex: “addrCRCRefIn”: false
Boolean
True if the CRC-16 result should be reflected (bit reversed) before returning. Defaults to false
.
ex: “addrCRCRefOut”: false
Int
A 16-bit value that is xor'ed with checksum post calculation. If no value is provided, then it defaults to 0
which means not to perform an xor.
ex: “addrCRCXorOut”: 0
These values are within the address field and used to identify which sector it is. The IBM standard uses a set of 4 values which are: cylinder, head, sector, and size. All bit indexes referenced below are relative to the address marker (0 is the first bit of the address marker, 8 is the start of the byte following the address marker). For the size value, the IBM standard uses the value 0 to describe a 128 byte sector, 1 for 256 bytes, 2 for 512 byes, etc.
Int - Required
The bit index of the start of the track number.
ex: “trackBitIndex”: 8
Int
The number of bits that comprise the track number. If no value is provided, then it defaults to 8
.
ex: “trackBitSize”: 8
Int
The bit index of the start of the head number. If no value is provided, then it defaults to 16
.
ex: “headBitIndex”: 16
Int
The number of bits that comprise the head number. If no value is provided, then it defaults to 8
. If the format does not contain an entry for the head number, then you can set this value to 0
and the physical head number will be used instead.
ex: “headBitSize”: 8
Int - Required
The bit index of the start of the sector number.
ex: “sectorBitIndex”: 24
Int
The number of bits that comprise the sector number. If no value is provided, then it defaults to 8
.
ex: “sectorBitSize”: 8
Int
The bit index of the start of the size value. If no value is provided, then it defaults to 32
.
ex: “sectorBitIndex”: 32
Int
The number of bits that comprise the size value. If no value is provided, then it defaults to 8
. If the format does not contain an entry for the size, then you can set this value to 0
and the size defined by sizeDefault
will be used instead.
ex: “sizeBitSize”: 8
Int
Used only if the format does not contain an entry for the size and you have sizeBitSize
set to 0
. This value defines the sector size to use for all sectors. The IBM standard uses the value 0 to describe a 128 byte sector, 1 for 256 bytes, 2 for 512 byes, etc.
ex: “sizeDefault”: 1
[String] - Required
Array of data field marker values in hex.
ex: “dataMarkers”: [“FB”, “F8”]
Int - Required
Number of bytes from the last synchronization byte to the marker. FM encoding uses a marker that is also the synchronization byte, so it has a value of 0
. Whereas MFM encoding tends to have a sequence of 3 A1 bytes that are the synchronization bytes followed by the marker, so it has a value of 1
.
ex: “dataMarkerInset”: 1
Int - Required
Byte index of the start of the actual sector data relative to the data marker (0 = data marker).
ex: “dataStartIndex”: 1
Int - Required
Byte index of the start of the stored checksum value relative to the data field. Positive values are offset from the end of the data (0 = immediately following data) and negative numbers are relative to the start of the data (-2 = immediately preceding the data).
ex: “dataStoredCRCOffset”: 0
Int - Required
Byte index offset (0 = data marker) of first byte used for checksum calculation.
ex: “dataCRCFromOffset”: 0
Int - Required
Byte index offset (0 = last byte of data field) of last byte used for checksum calculation. The data field size is determined by the size value provided in the address field.
ex: “dataCRCToOffset”: 0
Int
Starting value (seed) of the CRC-16. If omitted, then it defaults to 65535
(FFFF hex).
ex: “dataCRCInit”: 0
Int
The polynomial to use for the CRC-16. If omitted, then it defaults to 4129
(1021 hex).
ex: “dataCRCPoly”: 0
Boolean
True if the input data should be reflected (bit reversed) before passing to the CRC-16. Defaults to false
.
ex: “dataCRCRefIn”: false
Boolean
True if the CRC-16 result should be reflected (bit reversed) before returning. Defaults to false
.
ex: “dataCRCRefOut”: false
Int
A 16-bit value that is xor'ed with checksum post calculation. If no value is provided, then it defaults to 0
which means not to perform an xor.
ex: “dataCRCXorOut”: 0
String
If the data field required special handling/processing, then that can be indicated here. Defaults to none
.
Value | Description |
---|---|
none | No special handling is needed |
rx02 | DEC RX02 format uses an FM sector structure, but the data fields contain MFM encoded data |
ex: “specialDataHandling”: “rx02”
[ { "name": "IBM MFM", "enabled": true, "settings": "IbmMFM", "fastname": "IBM", "encodingAndMedia": ["*_mfm_*"], "syncPatterns": ["AAAA44894489", "AAAA52245224"], "addrMarkers": ["FE"], "addrMarkerInset": 1, "addrFieldSize": 6, "addrStoredCRCIndex": 5, "addrCRCFromIndex": -3, "addrCRCToIndex": 4, "trackBitIndex": 8, "headBitIndex": 16, "sectorBitIndex": 24, "sizeBitIndex": 32, "dataMarkers": ["FB","F8"], "dataMarkerInset": 1, "dataStartIndex": 1, "dataStoredCRCOffset": 0, "dataCRCFromOffset": -3, "dataCRCToOffset": 0 } ]