| TZX FORMAT |
| 1. | Introduction |
|
TZX is a file format designed to preserve all (hopefully) of the tapes with turbo or custom loading routines. Even though some of the newer and 'smarter' emulators can find most of the info about the loader from the code itself, this isn't possible if you want to save the file to tape, or to a real Spectrum. And with all this information in the file, the emulators don't have to bother with finding out the baud rate and other things. This file format was originally written for usage on ZX Spectrum compatible computers only, but as it turned out the SAM Coupe, Amstrad CPC, Jupiter ACE and Enterprise range of computers use the same tape encoding. It can be used for ZX-81 type of computers also, even though the encoding is somewhat different (for now there is no converter for ZX-81 tapes into TZX). There are also some special blocks which can be used on Commodore 64. At the end of this document you can find a description of encoding differences between these machines and a table which displays timings used by their respective ROM loading routines (some of them are not official). If you know of any other machines that have similar encoding that could be represented with this file format then let us know. The latest version of the TZX format specifications can be found at 'World Wide Ramsoft' web site. If you're looking for TZX files, you can find an extensive collection at Martijn van der Heide's 'World of Spectrum'. The format was first started off by Tomaz Kac who was maintainer until revision 1.13, and then passed to Martijn v.d. Heide. Now maintenance is in the hands of Ramsoft; if you have any questions about the format, please send an e-mail to ramsoft@bbk.org. The default format file extension is "TZX" and hopefully this won't have to change in the future; for RISC OS, the current TAP file type will be used. Amstrad CPC files should use the extension "CDT" to distinguish them from the ZX Spectrum files, otherwise the inner structure is totally the same. |
| 2. | Rules and definitions |
|
| 3. | TZX file format |
The file is identified with the first 8 bytes being 'ZXTape!' plus the 'end of file' byte 26 (1A hex). This is followed by two bytes containing the major and minor version numbers. To be able to use a TZX file, your program (emulator, utility, or whatever) must be able to handle files of at least its major version number. If your program can handle (say) version 1.05 and you encounter a file with version number 1.06, your program must be able to handle it, even if it cannot handle all the data in the file. The data it cannot handle should be relatively unimportant. Then the main body of the file follows. It consists of a mixture of blocks, each identified by an ID byte; currently there are 20 types of blocks. TZX block ID list:
This block must be replayed with the standard Spectrum ROM values for all loading speed variables (values in brackets []). The pilot tone consists in 8063 pulses if the first data byte (flag byte) is < 128, 3223 otherwise. This block can be used for the ROM loading routines AND for custom loading routines that use the same timings as ROM ones do. Return to ID list - Return to index
This block is very similar to the normal TAP block but with some additional info on the timings and other important differences. The same tape encoding is used as for the standard speed data block. If a block should use some non-standard sync or pilot tones (i.e. all sorts of protection schemes) then use the next three blocks to describe it. Return to ID list - Return to index
This will produce a tone which is basically the same as the pilot tone in the first two data blocks. You can define how long the pulse is and how many pulses are in the tone. Return to ID list - Return to index
This will produce N pulses, each having its own timing. Up to 255 pulses can be stored in this block; this is useful for non-standard sync tones used by some protection schemes. Return to ID list - Return to index
This is the same as in the turbo loading data block, except that it has no pilot or sync pulses. Return to ID list - Return to index
This block is used for tapes which have some parts in a format such that the turbo loader block cannot be used. This is not like a VOC file, since the information is much more compact. Each sample value is represented by one bit only (0 for low, 1 for high) which means that the block will be at most 1/8 the size of the equivalent VOC. The preferred sampling frequencies are 22050 or 44100 Hz (158 or 79 T-states/sample). Please, if you can, don't use other sampling frequencies. Please use this block only if you cannot use the turbo load block. Return to ID list - Return to index
Well, this block was created to support the Commodore 64 standard ROM and similar tape blocks. It is made so basically anything that uses two or four pulses (which are the same in pairs) per bit can be written with it. Some explanation:
Return to ID list - Return to index
This block is made to support another type of encoding that is commonly used by the C64. Most of the commercial software uses this type of encoding, i.e. the Pilot tone is not made from one type of Wave only, but it is made from actual Data byte which is repeated many times. As the Sync value another, different, Data byte is sent to signal the start of the data. The Data Bits are made from ONE wave only and there is NO XOR checksum either! Trailing byte is played AFTER the DATA has ended. Return to ID list - Return to index
This will make a silence (low amplitude level (0)) for a given time in milliseconds. If the value is 0 then the emulator or utility should (in effect) STOP THE TAPE, i.e. should not continue loading until the user or emulator requests it. Return to ID list - Return to index
This block marks the start of a group of blocks which are to be treated as one single (composite) block. This is very handy for tapes that use protected blocks like Speedlock 1 (which has around 64 pure tone blocks) or Bleepload (which may well have over 160 custom loading blocks). You can also give the group a name (example 'Speedlock 1 Block'). For each group start block, there must be a group end block. Nesting of groups is not allowed. Return to ID list - Return to index
This indicates the end of a group. This block has no body. Return to ID list - Return to index
This block will enable you to jump from one block to another within the file. The value is a signed short word (usually 'signed short' in C); Some examples:
Return to ID list - Return to index
If you have a sequence of identical blocks, or of identical groups of blocks, you can use this block to tell how many times they should be repeated. This block is the same as the FOR statement in BASIC. For simplicity reasons don't nest loop blocks! Return to ID list - Return to index
This is the same as BASIC's NEXT statement. It means that the utility should jump back to the start of the loop if it hasn't been run for the specified number of times. This block is also without any body. Return to ID list - Return to index
This block is analogue of the CALL Subroutine statement. It basically executes a sequence of blocks that are somewhere else and then goes back to the next block. Because more than one call can be normally used you can include a list of sequences to be called. The 'nesting' of call blocks is also not allowed for the same reasons. You can, of course, use the CALL blocks in the LOOP sequences and vice versa. The value is relative for the obvious reasons - so you can add some blocks in the beginning of the file without disturbing the call values. Please take a look at 'Jump To Block' for reference on the values. Return to ID list - Return to index
This block indicates the end of the Called Sequence. The next block played will be the block after the last CALL block (or the next Call, if the Call block had multiple calls). Again, this block has no body. Return to ID list - Return to index
This block is useful when the tape consists of two or more separately-loadable parts. With this block, you are able to select one of the parts and the utility/emulator will start loading from that block. For example you can use it when the game has a separate Trainer or when it is a multiload. Of course, to make some use of it the emulator/utility has to show a menu with the selections when it encounters such a block. All offsets are relative signed words. Return to ID list - Return to index
When this block is encountered, the tape will stop ONLY if the machine is an 48K Spectrum. This block is to be used for multiloading games that load one level at a time in 48K mode, but load the entire tape at once if in 128K mode. This block has no body of its own, but follows the extension rule. Return to ID list - Return to index
This is meant to identify parts of the tape, so you know where level 1 starts, where to rewind to when the game ends, etc. This description is not guaranteed to be shown while the tape is playing, but can be read while browsing the tape or changing the tape pointer. The description can be up to 255 characters long but please keep it down to about 30 so the programs can show it in one line (where this is appropriate). Please use 'Archive Info' block for title, authors, publisher, etc. Return to ID list - Return to index
This will enable the emulators to display a message for a given time. This should not stop the tape and it should not make silence. If the time is 0 then the emulator should wait for the user to press a key. The text message should:
However, it is not guaranteed that the emulator will actually display the message. Return to ID list - Return to index
Use this block at the beginning of the tape to identify the title of the game, author, publisher, year of publication, price (including the currency), type of software (arcade adventure, puzzle, word processor, ...), protection scheme it uses (Speedlock 1, Alkatraz, ...) and its origin (Original, Budget re-release, ...), etc. This block is built in a way that allows easy future expansion. The block consists of a series of text strings. Each text has its identification number (which tells us what the text means) and then the ASCII text. To make it possible to skip this block, if needed, the length of the whole block is on the start of it. If all texts in the tape are in English language then you don't have to supply the 'Language' field The information about what hardware the tape uses is in the 'Hardware Type' block, so no need for it here. Return to ID list - Return to index
This selects what hardware the programs on this tape use. Please include only machines and hardware for which you are 100% sure that it either runs (or doesn't run) on or with, or you know it uses (or doesn't use) the hardware or special features of that machine. If the tape runs only on the ZX81 (and TS1000, etc.) then it clearly won't work on any Spectrum or Spectrum variant, so there's no need to list this information. If you are not sure or you haven't tested a tape on some particular machine/hardware combination then do not include it in the list. The list of hardware types and IDs is somewhat large, and may be found at the end of the format description. Return to ID list - Return to index
This is a special block that would normally be generated only by emulators. For now it contains info on everything I could find that other formats support. Please inform me of any additions/corrections since this is a very important part for emulators. Those bits that are not used by the emulator that stored the info, should be left at their DEFAULT values. Return to ID list - Return to index
This block can be used to save any information you want. For example, it might contain some information written by a utility, extra settings required by a particular emulator, the title screen, the cover art or even poke data. Some of the most common uses of this block have become standardised:
Return to ID list - Return to index
This would enable one to snapshot the game at the start and still have all the tape blocks (level data, etc.) in the same file. Only .Z80 and .SNA snapshots are supported for compatibility reasons! The emulator should take care of that the snapshot is not taken while the actual Tape loading is taking place (which doesn't do much sense). And when an emulator encounters the snapshot block it should load it and then continue with the next block. Return to ID list - Return to index
This block is generated when you merge two ZX Tape files together. It is here so you can easily copy the files together and use them. Of course, this means that resulting file would be 10 bytes longer than if this block was not used. All you have to do if you encounter this block ID is to skip next 9 bytes. If you can avoid using this block for this purpose, then do so; it is preferable to use a utility to join the two files and ensure that they are both of the higher version number. Return to ID list - Return to index | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 4. | Hardware information reference |
This is the list of all hardware types and hardware identification ID's that are used in the 'Hardware info' block. Please send any additions you might have to me so they can be included. By Default you don't have to write any of the information if the game is made for the ZX Spectrum and complies with the following:
If the game is 128K ONLY then you would include two entries: The game works on AND uses the hardware of a 128K Spectrum AND the game DOESN'T work on a 48K Spectrum. If the game works on both 48K and 128K Spectrum, but it only uses the sound chip (AY) of the 128K Spectrum and none of its extra memory then you would only include the entry that says that the game uses the 'Classic AY hardware (Spectrum 128 sompatible sound device)'. These were only some examples of the usage of this block.
|
| 5. | Machine specific information |
Currently supported machines are: ZX Spectrum, Amstrad CPC, SAM Coupe, ZX-81 Jupiter ACE and Enterprise. Only ZX-81 (or the old Timex 1000) and Jupiter ACE use different tape encoding than the others.
|
| 6. | Revision history |
CHANGES SINCE v1.13
|
This document has passed W3C HTML 4.0 Validation. Click here for more informations.