573in1/doc/formats.md

3.7 KiB

Data formats

Security cartridge dump (.573 file)

Security cartridge dumps saved to IDE hard drives use a custom structured data format, consisting of a raw dump of the cartridge's EEPROM preceded by a 44-byte header. The data can be broken down as follows:

Offset Length Description
0 1 EEPROM chip type: 1 = X76F041, 2 = reserved, 3 = ZS01
1 1 Dump flags, see below
2 2 Reserved (should be zero)
4 8 System identifier, zerofilled if none such
12 8 Cartridge DS2401 identifier, zerofilled if none such
20 8 Cartridge ZS01 identifier, zerofilled if none such
28 8 Key used to unlock the cartridge, zerofilled if none such
36 8 EEPROM configuration registers, zerofilled if none such
44 112-512 EEPROM contents (512 bytes for X76F041, 112 for ZS01)

The dump flags field is a single-byte bitfield containing the following flags:

Bit Description
0 System has an identifier (i.e. a digital I/O board)
1 Cartridge has a DS2401 chip
2 EEPROM configuration registers present in the dump
3 System identifier present in the dump (requires bit 0)
4 Cartridge DS2401 identifier present in the dump (requires bit 1)
5 Cartridge ZS01 identifier present in the dump
6 Unprotected EEPROM data present in the dump
7 Protected EEPROM data and key present in the dump (requires bit 6)

NOTE: bit 0 being set without bit 3 also being set means the tool was able to detect the presence of a digital I/O board, but could not read its identifier. The same goes for bits 1 and 4 respectively for cartridges with a DS2401 chip.

Security cartridge dump (QR code)

The format used by QR code dumps is essentially the same as .573 files, but with an additional layer of compression and a custom base-41 encoding on top of the raw data. Scanning a QR code generated by the tool yields a string similar to this one:

573::OGI8APY-U7W9553SDY9J+F.TGR1XY92YKJFAGN16ALNTMDDWGM0-U2MPP:60M3NJO1.TU05T5QZ376SRN4S3LFHHGXNTSA6ZSTSQPZBBA96RCXZQ6M01E1CTKR7941MH9D7B0Y.:JZ0PN8K2000::

In order to extract the dump data from such a string, a decoder must:

  1. remove any framing (the 573:: prefix at the beginning of the string and the :: suffix at the end);
  2. decode the base-41 encoded string into an array of bytes (see below);
  3. decompress the decoded binary data.

The base-41 encoding replaces each group of 2 bytes in the compressed data with a group of 3 characters out of a custom 41-character set (the data is padded to an even number of bytes in order for this to work). It can be undone using the following pseudocode:

CHARSET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ+-./:"

while not isEndOfData(input):
    a = findCharacterInString(CHARSET, readByte(input))
    b = findCharacterInString(CHARSET, readByte(input))
    c = findCharacterInString(CHARSET, readByte(input))

    value = a + (b * 41) + (c * 1681)
    writeByte(output, value >> 8)
    writeByte(output, value & 0xff)

The contents of the dump can then obtained by running the decoded data through zlib's decompress() function or a zlib-compatible decompressor.