formats index
*** T64 (C64s Tape images)
** Document revision 1.1
This format, designed by Miha Peternel, is for use with his C64s
emulator. It has a very structured directory with each entry taking up 32
bytes, and a reasonably well-documented format.
It has a large header at the beginning of the file used for file
signature, tape name, number of directory entries, used entries, and the
remainder for actual tape directory entries.
Following immediately after the end of the directory comes the data for
each file. Each directory entry includes the information of where its data
starts in the file (referenced to the beginning of the file), as well as
the starting and ending C64 load addresses. From these addresses we can
determine how long the stored file is (end-start).
Unfortunately, in the early days of the C64s emulator, before Miha had
his MAKETAPE utility ready, another program called CONV64 was on the scene,
and it created faulty T64 files. The ending load address was usually set to
$C3C6 regardless of file size. Be aware that these files are still quite
common on the Web and FTP sites.
Here is a HEX dump of the first few bytes of a standard T64 file:
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII
----------------------------------------------- ----------------
000000: 43 36 34 53 20 74 61 70 65 20 69 6D 61 67 65 20 C64S.tape.image.
000010: 66 69 6C 65 00 00 00 00 00 00 00 00 00 00 00 00 file............
000020: 01 01 90 01 05 00 00 00 43 36 34 53 20 44 45 4D ........C64S.DEM
000030: 4F 20 54 41 50 45 20 20 20 20 20 20 20 20 20 20 O.TAPE..........
000040: 01 01 01 08 85 1F 00 00 00 04 00 00 00 00 00 00 ................
000050: 53 50 59 4A 4B 45 52 48 4F 45 4B 20 20 20 20 20 SPYJKERHOEK.....
000060: 01 01 01 08 B0 CA 00 00 84 1B 00 00 00 00 00 00 ................
000070: 49 4D 50 4F 53 53 49 42 4C 45 20 4D 49 53 53 2E IMPOSSIBLE MISS.
...
0003E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0003F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000400: 1A 08 E4 07 9E 32 30 38 30 14 14 14 14 14 14 14 ................
The first 32 bytes ($000000-00001F) represent the signature of the file,
telling us it is a tape image file for C64S. Note that it is padded with
$00 to make the signature 32 bytes long.
000000: 43 36 34 53 20 74 61 70 65 20 69 6D 61 67 65 20 C64S.tape.image.
000010: 66 69 6C 65 00 00 00 00 00 00 00 00 00 00 00 00 file............
It is important that the string "C64" be at the beginning of the file
because it is the string which is common enough to be used to identify the
file type. There are several variations of this string like "C64S tape
file" or "C64 tape image file". The string is stored in ASCII.
The next 32 bytes contain all the info about the directory size, number
of used entries, tape image name, tape version#, etc.
000020: 01 01 90 01 05 00 00 00 43 36 34 53 20 44 45 4D ........C64S.DEM
000030: 4F 20 54 41 50 45 20 20 20 20 20 20 20 20 20 20 O TAPE..........
Bytes:$20-21: Tape version number of either $0100 or $0101. I am not sure
what differences exist between versions.
22-23: Maximum number of entries in the directory, stored in
low/high byte order (in this case $0190 = 400 total)
24-25: Total number of used entries, once again in low/high byte.
Used = $0005 = 5 entries.
26-27: Not used
28-3F: Tape image name, padded with $20 (space)
The next 32 bytes (and on until the end of the directory) contain
individual directory entries.
000040: 01 01 01 08 85 1F 00 00 00 04 00 00 00 00 00 00 ................
000050: 53 50 59 4A 4B 45 52 48 4F 45 4B 20 20 20 20 20 SPYJKERHOEK.....
000060: 01 01 01 08 B0 CA 00 00 84 1B 00 00 00 00 00 00 ................
000070: 49 4D 50 4F 53 53 49 42 4C 45 20 4D 49 53 53 2E IMPOSSIBLE MISS.
Bytes $40: C64s filetype
0 = free (usually)
1 = Normal tape file
3 = Memory Snapshot, v .9, uncompressed
2-255 = Reserved (for memory snapshots)
41: 1541 file type (0x82 for PRG, 0x81 for SEQ, etc). You will
find it can vary between 0x01, 0x44, and the normal D64
values. In reality any value that is not a $00 is seen as a
PRG file. When this value is a $00 (and the previous byte at
$40 is >1), then the file is a special T64 "FRZ" (frozen) C64s
session snapshot.
42-43: Start address (or Load address). This is the first two bytes
of the C64 file which is usually the load address (typically
$01 $08). If the file is a snapshot, the address will be 0.
44-45: End address (actual end address in memory, if the file was
loaded into a C64). If the file is a snapshot, then the
address will be a 0.
46-47: Not used
48-4B: Offset into the image file (from the beginning) of where the
C64 file starts (stored as low/high byte)
4C-4F: Not used
50-5F: C64 filename (in PETASCII, padded with $20, not $A0)
Typically, an empty entry will have no contents at all, and not just have
the first byte set to $00. If you only set the C64s filetype byte to $00
and then use the file in C64S, you will see the entry is still in the
directory.
0003E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0003F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
Starting at $000400 (assuming a directory with 30 entries) we now have
actual file data.
000400: 1A 08 E4 07 9E 32 30 38 30 14 14 14 14 14 14 14 .....2080.......
---------------------------------------------------------------------------
What it takes to support T64:
This format has some advantages over D64's in that there is very little
wasted space, except for the empty directory entries. It is laid out very
logically, with entries and headers all being in 32-byte chunks, making for
easy support. There is also a signature, and the directory size can be a
large as you need for expansion.
One large drawback is it is not meant to support multi-file programs
under C64s. If you have a program which requires several sub-files to be
loaded, under C64s a T64 file will not work. It would be best to use a D64
in this case.
When removing a file from a T64, you must remove the entry completely
from the directory. Failure to do so results in the file still being
visible to C64s. It is not even good enough to set the whole entry to zero,
but it must be *removed*.
The directory also contains the load start and end addresses. Why? Since
T64 was designed for C64s, having the load address was something useful to
show when selecting files inside of C64s. However, the end address would
have been better if it was replaced with "file size", so you could easier
determine the file size for display.
While the directory design allows for C64 file types to be used, it would
appear to be a waste as T64 really only supports loadable files (PRG) and
nothing else. REL is out of the question.
Also, since the filename entries are not padded with A0 characters (but
rather with spaces), filenames can't have trailing spaces.
---------------------------------------------------------------------------
Overall Good/Bad of T64 Files:
Good
----
* The header is *adequately* defined (but some improvement in the
description would be good)
* Supports a 16 character filename
* Has a verifiable file signature
* The format is extendible (can add delete to even a full archive, the
central directory doesn't have a small file limit)
* If you pack the T64 directory full, you minimize the DOS cluster slack
space loss, since the file size is variable
* Has a description field in the header
* Can have loadable files with the same name(?)
Bad
---
* Filenames can't have spaces at the ends due to the padding characters
being spaces ($20) and not the standard $A0 character
* It is not designed to support multi-load programs. Unless C64s starts
to allow this, it would not be a good idea to use them this way even if
other emulators do start to support this feature as the T64 files would
*not* be compatible with C64s
* Doesn't practically support >63 files (this is a limitation of C64s,
nothing more)
* No directory customization, as zero-length files not allowed (minimum
filesize is 2 bytes)
* No actual file size for contained files is stored, so you need to use a
poor method to determine the file size based on the load addresses
* Can't easily re-write contained files as they are blocked in by the
files around them
* No REL file support, as format really only supports PRG's
* Header could have been laid out better, to make it a much more
versatile format than it is now
* Can't have $00's in a filename(?)
* Even though you can set the directory entry to be the real 1541
filetype (SEQ, USR, PRG), C64s still sees them as PRG's (?)
ÿ