Atari ST Protection: PASTI file format

Files in this format have the extension “.stx”, probably for “ST - eXtended”. This description is valid for files created with PASTI 0.4b BETA.

A typical protected file looks like this:

File header (16 bytes)

After the file header one block for each track is following. Each block also starts with a 16 byte header:

Track Header (16 bytes)

The bitmask for the flags

If Bit 0 is clear, the track is unprotected and the number of sectors as stored in the track block header are simply saved as 512 byte blocks directly after the header. The track is therefore 16 + 512 * sectors bytes long.

If Bit is set, the header is first followed the sector headers. One for each sector in the track, again 16 bytes per header.

Sector Header (16 bytes)

The CRC is a CCITT CRC16 calculated by the FDC. It is initialized with 0xFFFF and includes the sync marks, therefore typically 0xA1,0xA1,0xA1,0xFE plus the 4 bytes from the address block.

The FDC status is typically 0x00. Also common is 0x10 for a sector not found and 0x08 for a CRC error when reading. Bit 7 has a special meaning: it hints that the sector has fuzzy bits and the fuzzy sector mask should be used. If Bit 7 is set, Bit 3 is usually also set, because fuzzy bits will trigger a CRC error inside the sector.

After the sector headers the fuzzy sector mask is following, if the value is != 0 in the track header. The mask identifies the bits that are random in a given sector. The size of the fuzzy sector mask depends on the sector size (from the header) and the number of fuzzy sectors in the track itself. The fuzzy sector mask has bits set for every bit in in the sector, that is not random. Therefore a byte generated with the mask could be calculated like this:

fdcSectorByte[byteOffset] = (sectorData[byteOffset] & fuzzyMask[byteOffset])
                            | (rand() & ~fuzzyMask[byteOffset])`

After the fuzzy sector mask, the sectors are written to the file. If neither Bit 6 or 7 in the track flags is set, only the content of the sectors is written. Again with the sector size in the header taking into consideration. These tracks can be also easily recognized by sector offsets that are always a power of 2 (typically in 512 byte increments), starting at 0.

Following the fuzzy sector mask is the track data area. This area can contain either the sectors by itself, or the complete track image with the sectors embedded, or the complete track with the sectors separate (following the track image). How they are stored is stored in Bit 6 and 7 in the track flags.

If Bit 6 and 7 are clear, there is no track image and the sectors are stored just by order end length - just like the fuzzy sector mask, except this time for all sectors. Warning: sectors can be missing, if only a header was read, but the data was missing. The FDC status has Bit 4 (Record not found) set in this case.

If Bit 6 is set and 7 is clear, the track image is written with a track image header and the sectors follow the track image in the usually order and length. The track image header is just a word (little endian, as usual) that contains the length of the track image.

Bit Bit 6 and 7 is set, the track image is written with a track image header that has two words: the first one is a byte offset to the first 0xA1 address mark sync, the second word is the length of the track image in bytes.

If Bit 7 is set, the sector data is usually merged inside the track image, the sector offsets then point inside the actual track image. However, it is possible for single sectors to have an offset behind the track image, if PASTI couldn’t map them correctly into the track image. A software should always read the sectors based on the sector offset in the sector header.

Previous post:
Next post: