TAP- and BLK tape format

The TAP- (and BLK-) format is nearly a direct copy of the data that is stored in real tapes, as it is 'written' by the ROM save routine of the ZX-Spectrum. It is supported by many Spectrum emulators:

TAP file format:
Offset: Field type: Length: Description: Additional information:
0 #1 ? first datablock a TAP file is simply one datablock or 
a group of 2 or more datablocks, one followed after the other. The TAP file may be empty. Then it has a size of 0 bytes. There's no real file size limit, like real tapes, TAP files can also contain huge amounts of data blocks.
??? #2 ? second datablock
??? #N ? last (Nth) datablock

TAP files use the following sub-format only:

(2+[data length] bytes):
Offset: Field type: Length: Description: Additional information:
0 2 [data length]

length of the following datablock in bytes (0..65535)

2 [data length]  

data as it is stored on tape, may be a header or any data from ZX-Spectrum


Here follows the description of blocks. Please note that these are re-used for the TZX file format as well. Data blocks must have at least 2 bytes, to build up a valid tape data block, because each block should have a flag and a checksum byte. Shorter data blocks (1 or 0 bytes long) are so-called "fragmented" ones.

Valid data blocks - headers (always 19 bytes long):

case #1: program header or program autostart header - for storing BASIC programs

Offset: Field type: Length: Description: Additional information:
0 1 flag byte

always 0. Byte indicating a standard ROM loading header

1 1 data type

always 0: Byte indicating a program header

2 10 file name

loading name of the program. filled with spaces (CHR$(32))

12 2 [data length]

length of the following data (after the header)
= length of BASIC program + variables

14 2 autostart line LINE parameter of SAVE command. Value 32768 means "no auto-loading"; 0..9999 are valid line numbers.
16 2 [program 
length]
length of BASIC program;
remaining bytes ([data length] - [program length]) = offset of variables
18 1 checksum byte simply all bytes (including flag byte) XORed

 

case #2: numeric data array header - for storing numeric arrays

Offset: Field type: Length: Description: Additional information:
0 1 flag byte

always 0. Byte indicating a standard ROM loading header

1 1 data type

always 1: Byte indicating a numeric array

2 10 file name

loading name of the program. filled with spaces (CHR$(32))

12 2 [data length]

length of the following data (after the header)
= length of number array * 5 +3

14 1 unused  
15 1 variable name = (1..26 meaning A..Z) +128
16 2 unused = 32768
17 1 checksum byte simply all bytes (including flag byte) XORed

 

case #3: alphanumeric data array header - for storing string arrays

Offset: Field type: Length: Description: Additional information:
0 1 flag byte

always 0. Byte indicating a standard ROM loading header

1 1 data type

always 2: Byte indicating an alphanumeric array

2 10 file name

loading name of the program. filled with spaces (CHR$(32))

12 2 [data length]

length of the following data (after the header)
= length of string array +3

14 1 unused  
15 1 variable name = (1..26 meaning A$..Z$) +192
16 2 unused = 32768
17 1 checksum byte simply all bytes (including flag byte) XORed

 

case #4: byte header or SCREEN$ header - for storing machine code or screens

Offset: Field type: Length: Description: Additional information:
0 1 flag byte

always 0. Byte indicating a standard ROM loading header

1 1 data type

always 3: Byte indicating a byte header

2 10 file name

loading name of the program. filled with spaces (CHR$(32))

12 2 [data length]

length of the following data (after the header)
in case of a SCREEN$ header = 6912

14 2 start address in case of a SCREEN$ header = 16384
16 2 unused = 32768
17 1 checksum byte simply all bytes (including flag byte) XORed

Valid data blocks - data blocks:

case #5: standard data blocks or custom data blocks - (2+[data length]) bytes

Offset: Field type: Length: Description: Additional information:
0 1 flag byte

always 255 indicating a standard ROM loading data block or any other value to build a custom data block

1 [data length] data block

the essential data (may be empty)

1+[data length] 1 checksum byte

simply all bytes (including flag byte) XORed

Fragmented data blocks:

Fragmented data blocks cannot be produced by ROM saving routines - they must be produced with machine code programs. They have less than 2 bytes. In some games you really find zero length fragment data blocks:

case #6: fragment data blocks - without flag or checksum byte

Offset: Field type: Length: Description: Additional information:
0 < 2 data block

the essential data (may be empty)