*** L64 (64LAN image files) *** Document revision 1.1 64LAN gives your C64 access to files on your PC hard disk (similar to 64NET). It uses a custom file format extension "L64", which contains the original C64 filename and attributes. 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII ----------------------------------------------- ---------------- 0000: 36 34 4C 41 4E 20 49 44 42 4C 4F 43 4B 20 0D 0A 64LANIDBLOCK 0010: 73 64 66 67 73 66 20 20 20 20 20 20 20 20 20 20 sdfgsf 0020: 0D 0A 30 38 30 31 2C 44 33 45 42 0D 0A 20 20 20 0801,D3EB 0030: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 0040: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 0050: 20 20 20 20 0D 0A 20 20 20 20 20 20 20 20 20 20 0060: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 0070: 20 20 20 20 20 20 20 20 20 20 20 20 20 0D 0A 1A 0080: 09 65 FF FF FF FF FF 01 00 00 00 00 00 00 00 00 e 0090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0100: 0E 08 E9 03 9E 20 28 32 30 36 34 29 00 00 00 78 (2064)x Bytes: $00-0F: 64LAN file signature ("64LAN IDBLOCK ", with ) 10-21: 16-byte filename of contained C64 file, with . Filename padded with $20 (spaces!) 22-2C: Starting and ending HEX load addresses, with 2D-55: 39-byte comment #1, with 56-7E: 39-byte comment #2, with 7F: EOF marker, for text viewing 80-81: Version number of file (high/low byte format), Above example provides a version of 09.65 82-86: 5-byte CRC 87: Origin of file: 0 - Real C64 1 - C64s emulator 88-FF: Reserved for future use 100-: File data starts here, without the original load address All the strings in the beginning of the file, from 00-7F are in ASCII, and delimited with and markers. This block ends in a text-mode EOF marker. This is to help with the viewing of the contents of these files using the DOS "TYPE" command. *** N64 (64NET image files) *** Document revision 1.1 64NET links your C64 and PC together through a special cable, and provides the C64 access to many emulator and native files stored on your PC hard disk. Early versions only provided access to 64NET's custom filetype "N64", which is explained here, but newer versions also support many of the common emulator files (LNX, T64, D64, etc). The following is a dump of an N64 file: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII ----------------------------------------------- ---------------- 00: 43 36 34 01 82 01 08 C4 0C 00 00 00 00 00 00 00 C64 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 31 1 20: 35 58 58 20 2D 3E 20 36 34 4E 45 54 00 00 00 00 5XX->64NET 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 .. .. .. Bytes: $00-02: 64NET file signature ("C64") 03: File version ($01) 04: C64 filetype. Valid types are: $x0=DEL $x1=SEQ $x2=PRG $x3=SEQ $x4=REL $x5=DIR (not really implemented) $x6=VOL (not really implemented) Bit 0-3: The actual filetype 000 (0) - DEL 001 (1) - SEQ 010 (2) - PRG 011 (3) - USR 100 (4) - REL Values 5-15 are illegal, but if used will produce very strange results. The 1541 is inconsistent in how it treats these bits. Some routines use all 4 bits, others ignore bit 3, resulting in values from 0-7. Bit 4: Not used Bit 5: Used only during SAVE-@ replacement Bit 6: Locked flag (Set produces ">" locked files) Bit 7: Closed flag (Not set produces "*", or "splat" files) 05-06: Load address of contained file in low/high format. Some versions do not contain this address, so use the one at the beginning of the file data. 07-0A: File size (in bytes, low/med1/med2/high format). This provides access to *very* large files, up to 2 Gigabytes! 0B: Network security level $00 - None 01 - Visitor 02 - Low 03 - High 04 - Master 0C-1E: Reserved for future use 1F-2E: 16-byte C64 filename in PETASCII, padded with $00 2F: Set to $00 30-FD: Reserved for future use FE-: Start of file data (including original load address) Some versions of these files are longer than what the header and file size total up to. It is safe to ignore this inconsistency and only read the amount of data dictated by the "file size". *** ARC (compressed ARChive) *** Document revision 1.1 The name is likely a shortened version of "ARChive". It is a direct relative of SDA, as SDA's are simply self-dissolving ARC files. ARC does not contain the dissolving code on the front of the file. Do not confuse these ARC files with C64 ARKive files (made with the ARKIVE program), or with PC .ARC files, as they are all completely different. Below is a dump of the first 48 bytes of an ARC file... 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII ----------------------------------------------- ---------------- 0000: 02 01 20 9D 47 01 00 01 00 50 01 41 FE 3A 21 FE ..G..P.A:! 0010: 00 01 FE 00 02 FE 03 02 A9 00 20 90 FF A9 02 A6 ..... 0020: BA A0 01 20 BA FF A9 04 A2 35 A0 02 20 BD FF A2 ..5. Byte: $00 - Archive version $01 = original 02 = extended header 01 - Compression mode $00 - Stored 01 - Packed 02 - Squeezed 03 - Crunched (arc version 2 only) 04 - Squeezed and packed (arc version 2 only) 05 - Crunched in 1 pass (arc version 2 only) 02-03 - Checksum (low/high format) 04-06 - Original file size in bytes (low/med/high format). This value is not valid if the compression mode (from above) is 5, a one pass crunch) 07-08 - Number of blocks compressed file takes (low/high, 254 bytes/block) 09 - Filetype ("P", "S", "U", "R", uppercase in ASCII, lowercase in PETASCII ) 0A - Filename length 0B-0B+length - Filename (in PETASCII, no longer than 16 characters) 0B+length+1 - Relative file record length (only for arc version 2) 0B+length+2 - Date (2 bytes, in MSDOS format, only in arc vers. 2) The header can also have some extra fields, depending on what version the archive is. Version 1 archives do not have the RECORD length and DATE fields, meaning they cannot contian REL files. The RECORD length is only used when the filetype is REL. Immediately following the filename (for version 1 archives) is the RLE control byte, and then follows the LZ table and compressed data. 64COPY can unpack ARC files easily, as they are treated like any emulator file, and just hitting return on them will open the archive. Simply select what files you want to extract, and copy them out. *** ARK (ARKive) *** SRK (compressed ARKive, very rare) *** Document revision 1.1 Written by Edward Rohr, the ARKive program went through several revisions, with the last known being version 3.0. It was intended as a replacement for LNX as the author explained he had too many bad experiences with LyNX destroying his data. Version 3 was also the only one to support creation and extraction of the compressed SRK archives. The ARK format bears a strong resemblance to LNX archives in that all the files are simply stored one after the other, and are block aligned to take up multiples of 254 bytes (256 on a real 1541). However, there is no BASIC program at the beginning telling you to "Use XXX to dissolve this file", and therefore there is no reconizeable signature to determine if the file is actually an ARK. ARK's can contain up to 255 files, but this number is restricted by the limitations of the drive being used for addition and extraction. SRK is the compressed version of ARK. The layout of the directory is the same as below, only the files themselves (except for REL) might be compressed. As I only seen one file (which was damaged), and my attempts to create one with ARKive 3.0 failed badly, I can't comment on the compression used. The biggest difference is the files contained inside the SRK are not block-aligned since they are compressed, and therefore must be decompressed to create the destination file, rather than just "unlinked". The structure of the directory is very simple, where all entries take up 29 bytes (unlike LNX's variable size). Below is a sample of an ARK file, with a few of its directory entries... 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII ----------------------------------------------- ---------------- 0000: 1F 82 9F 42 4F 4F 54 A0 A0 A0 A0 A0 A0 A0 A0 A0 .BOOT 0010: A0 A0 A0 00 00 00 00 00 00 00 00 00 01 00 82 F1 . 0020: 53 55 50 45 52 20 4B 4F 4E 47 A0 A0 A0 A0 A0 A0 SUPERKONG 0030: 00 00 00 00 00 00 00 00 00 79 00 82 FB 41 54 4F yATO 0040: 4D 49 43 20 48 41 4E 44 42 41 4C 4C A0 00 00 00 MICHANDBALL 0050: 00 00 00 00 00 00 0F 00 82 FE 58 45 52 4F 4E 53 .XERONS 0060: A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 00 00 00 00 00 00 0070: 00 00 00 2A 00 82 FF 57 45 54 20 50 41 49 4E 54 *WETPAINT 0080: A0 A0 A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 0090: 12 00 82 5A 47 52 4F 55 4E 44 20 53 4E 49 50 45 .ZGROUNDSNIPE Byte: $00: Number of files in the ARKive ($1F = 31 files) 01-1D: First directory entry (29 bytes per entry) 01: File Attribute (same as a D64 attribute) Typical values for this location are: $80 - DEL 81 - SEQ 82 - PRG 83 - USR 84 - REL Bit 0-2: The actual filetype 000 (0) - DEL 001 (1) - SEQ 010 (2) - PRG 011 (3) - USR 100 (4) - REL Values 5-15 are illegal types. Bit 3: Not used Bit 4: Compressed flag (only for SRK). If set, file is compressed. Not used in ARK files. Bit 5: Not used Bit 6: Locked flag (Set produces ">" locked files) Bit 7: Closed flag (not set produces "*", or "splat" files) 02: LSU byte (see "INTRO.TXT" document for description of "LSU") 03-12: 16-byte filename (in PETASCII, padded with $A0) 13: REL file RECORD size 14-19: Unused (can contain the unused locations from the D64 entry) 1A: REL file side sector block count (side sector info contained at end of file) 1B: Number of bytes+1 used in the last side sector entry 1C-1D: Length of file, in sectors (low/high byte order) 1E-3A: Second directory entry 3B-57: Third directory entry 58-74: Fourth directory entry 75-91: Fifth directory entry ... The starting location of the file information takes only a small calculation to find out. As we have 31 entries, the total byte size of the directory is 31 * 29 + 1 = 900 bytes (the 1 comes from the first byte of the file, which represents the # of entries). Now, we take the 900 and divide it by 254 to see the number of blocks, 900/254 = 3.543. If there is any remainder, we always round up to the nearest integer, which in this case makes it 4 blocks. So now we know that the file information starts at 4*254 = 1016 ($03F8 offset) REL files are stored like a normal file except the side sectors are stored directly following the normal file data. It would seem that the actual contents of the side sectors are unimportant (except for the RECORD length), just that the correct number of blocks exist. Seeing as no emulator that I know of supports ARK format, I can't see any usefulness in using it. It does have a better directory structure than LNX as each entry has a consistent byte size (versus LNX's variable size). There are also a few utilities for UnARK'ing on the PC. It would seem that LNX is the better supported format (although I think it shouldn't be), on both the C64 and the emulators. 64COPY supports these files on a read-only basis, allowing you to convert them to another format, but nothing else. Star Commander also contains a utility called Star Arkive which will un-Arkive these files into a D64 image. --------------------------------------------------------------------------- What it takes to support ARK: ARK shares many features with LNX. It has a directory size that is always a multiple of 254 bytes, and the files contained are also block aligned to 254 byte boundaries. The directory entries also have room for the unused part of the D64 entry, used for time/date stamps, and it supports REL files. Unlike LNX, this format uses a consistent 29-byte directory entry, which is a very great advantage. However, it has a few drawbacks as well. It contains no recognizeable signature, and can only hold up to 255 files. The most annoying thing is there is no provision for having a multi-block directory, with only a few entries (which by the way LNX allows for). This means I cannot have a directory with only 2 entries, yet have the directory take up 2 blocks. For the 1541, this limitation makes no difference, but on a PC it makes a world of difference. If I wanted to add files to an existing ARK file on a PC, I might have to increase the directory by several blocks, and on a PC that takes some work. This also means that I cannot cancel a "copy" operation in the middle because I may end with a directory with too many blocks for the number of entries it contains. *** Binary *** Document revision 1.1 This is really a non-format, as it has no specific layout whatsoever, but instead is simply a data file. This does make it difficult to describe any general layout, as there are many possibilities. It is assumed that a binary is a single file, usually having no special extension (like LNX/SFX/SDA, etc), sitting on a PC hard disk, not inside of *any* other file (like in a D64/T64/LNX etc). By looking at the whole file (but especially the beginning) with a HEX editor, and a well-trained eye, you can usually determine what file type it is by the BASIC code, load address, and text strings contained within. If the file is a normal C64 program, then the first two bytes are the load address, stored in low/high byte format. If it is a BASIC program (or has a BASIC header), then the first two bytes might be $01 $08 (or $01 $04 for PET, $01 $1C for C128, the numbers vary for different systems like VIC-20, Plus4, C61, etc), and the rest is line number pointers, line numbers and BASIC code. If it is not a BASIC file (like part of a game loader), then it could be a machine language file, requiring a SYS call to execute. Many secondary files with multi-file games have load addresses other than $0801 (like $C000, or $8000 for cartridges), and some have none at all, where the loader program will actually specify where to load the file. Below is a typical header for a game, using a SYS call to start (in this case, SYS 2064). 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII ----------------------------------------------- ---------------- 0000: 01 08 0E 08 E9 03 9E 20 28 32 30 36 34 29 00 00 .....(2064) 0010: 00 78 A2 FF 9A A0 00 84 01 A2 CC BD 57 08 9D 33 x.̽W.3 One reason this non-archive format is important is because of the filename limitations imposed by the PC architecture, and some of the problems that it can cause. The PC has an 8.3 filename convention (assuming DOS, and not OS/2 or Windows 95/NT long filenames), allowing for, at most, a filename of 11 characters. The PC also has character limitations on filenames, most of which don't apply to the C64. When converting a C64 file from any emulator file, you *cannot* use the C64 filename directly on the PC since, first of all its likely too long, and secondly it may contain characters illegal in the DOS world (i.e. ASCII 46, the 'extension' separator). One other reason that binary is not a good way to keep C64 files is that you lose the C64 filetype. You *can* set the file extension to show the type (xxx.PRG, xxx.SEQ), but this is not typically done. If the DOS extension is not set, it is much more difficult to know what format the file originally was. In order to convert a filename from C64 to DOS, the use of translate tables (translating illegal characters to legal ones) as well as an algorithm to reduce the filesize down to useable size (typically only 8 characters from 16) must be used. Included within the PC64 distribution archive is a 'C' program which does just what I have described. It contains an algorithm which will remove illegal characters, then reduce the filename down using several different rules, all to make the filename conform to the DOS 8.3 naming standards. There are some people who feel that with Windows95 (or OS/2, or Windows NT) long filename support, we should be able to have C64 files with the full 16 character filename on the PC hard disk. This is a fallacy as the useable character limitations of the C64 and those of any OS supporting long filenames are not the same. If you convert a C64 filename, many characters must be removed and or changed to allow it to be used in DOS (or Win95). There is very little benefit or disadvantage to using binary. About the only thing which is important to remember is you could lose most of the original C64 filename, which *will* cause problems when you try to reconstruct them. Binaries have no way of preserving the actual long names. --------------------------------------------------------------------------- Overall Good/Bad of BINARY Files: Good ---- * Easily determined filesize (the DOS filesize is the C64 filesize) * It is the *native* C64 file, so emulators can *easily* support it Bad --- * No 16 char filename, no real C64 filename at all * No filetype, or special attribute bits * No REL, GEOS or FRZ file support * No signature or file description * Difficult to support multi-file, as original C64 filenames are not retained * Since there is no filetype, you may not always be able to determine if the file is a SEQ, USR or really a PRG without knowledge of the file contents *** Standard C64 BITMAP Images (HIRES & HIRES-MULTICOLOR) *** Document revision 1.1 Below is a table to help in the identification of C64 bitmap images. If you require further information about how bitmap images are displayed then you should refer to the C64 Programmers Reference Manual. To automatically identify the type of image you need to compare the length of the file and the Load address. Once you have identified the image type, you can then use the bitmap, screen and colour offsets to help in the displaying of the bitmap. Format for image types: Load - Load address (first two bytes of the file) Length - File length in bytes (including load address bytes) Bitmap - Bitmap offset (8000 bytes) Screen - Screen data offset (1000 bytes) Colour - Colour data offset (1000 bytes) ScrCol - Screen colour offset (1 byte) Name (Black/white) Load Length Bitmap Screen Colour ScrCol --------------------- ----- ------ ------ ------ ------ ------ "Art Studio" $2000 9009 0 8000 - - "Doodle" $5C00 9218 1024 0 - - "Image System (hi)" $4000 9194 0 8192 - - Name (Multicolor) Load Length Bitmap Screen Colour ScrCol --------------------- ----- ------ ------ ------ ------ ------ "Artist 64" $4000 10242 0 8192 9216 10239 "Adv Art Studio" $2000 10018 0 8000 9016 9001 "Blazing Paddles" $A000 10242 0 8192 9216 8064 "Koala Painter" $6000 10003 0 8000 9000 10000 "Image System (mc)" $3C00 10218 1024 9216 0 9215 "Vidcom 64" $5800 10050 2048 1024 0 2024 "CDU Paint" $7EEF 10277 273 8273 9273 10273 *** FRZ (C64s saved-session FRoZen files) *** Document revision 1.1 These files, similar in nature to PC64's .C64 files, are a complete memory dump of the 64K RAM, color RAM, and all I/O ports and CPU registers. The only emulator file which can hold FRZ files is a T64, as its directory/filetype values allow for it. These files (up to C64s V2.0), when converted to raw binaries, are 66806 bytes large. 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ----------------------------------------------- 00000: 00 00 .. .. .. .. .. .. .. .. .. .. .. .. .. .. <- Load Address ... 00000: .. .. 2F 47 00 AA B1 91 B3 00 00 00 00 00 00 FF <- 64k main RAM 00010: 00 00 00 40 02 00 BE 00 19 16 00 00 C9 9E 00 00 00020: 00 00 00 00 40 02 69 00 00 00 03 00 00 01 08 2A 00030: 3A A8 3A AA 4D C9 9E C9 9E 00 A0 BE 00 00 00 D9 ... 10000: .. .. 01 01 01 01 01 01 01 01 01 01 01 01 01 01 <- Color RAM 10010: 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 10020: 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 10030: 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ... 10400: .. .. F1 B0 F1 01 69 20 3A 00 00 00 00 00 00 00 <- I/O 10410: 00 00 00 00 00 00 00 00 00 00 00 9B 37 00 00 00 10420: 08 00 15 0F F0 00 00 00 00 00 00 00 01 02 03 04 10430: 00 01 02 03 04 05 06 07 4C 00 00 00 00 00 00 00 ... Bytes:$00000-00001: Load address (always $00 $00) 00002-10001: Main 64k RAM ($0000-FFFF) 10002-10401: Color RAM ($D800-DBFF) 10402-10409: CPU registers (8 bytes) in the following order: - PC (Program Counter, 2 bytes), - SP (Stack Pointer, 2 bytes), - A (Accumulator, 2 bytes) - X/Y (X and Y registers, 2 bytes) 1040A-10438: VIC-II ($D000, 47 bytes) 10439-10455: SID ($D400, 29 bytes) 10456-10465: CIA #1 ($DC00, 16 bytes) 10466-10475: CIA #2 ($DD00, 16 bytes) 10476-104F5: CPU Task data (128 bytes), containing: - Shadow registers - Emulation Registers Seeing as each emulator uses its own format for its "snapshot" images, there is no simple conversion method to take one snapshot (i.e. a PC64 .C64 file) and convert it to another emulator snapshot format (i.e. a C64s FRZ file). The only commonalities would be the main 64k RAM and color RAM areas, whereas the rest of the file would be quite different. *** CRT - CaRTridge Files (from the CCS64 emulator) *** Document revision 1.0 Cartridge files were introduced in the CCS64 emulator, written by Per Hakan Sundell, and use the ".CRT" file extension. This format was created to handle the non-standard ROM cartridges that exist, such as Action Replay and the Power cartridge. Typically, normal game cartridges loaded into one of two specified memory ranges ($8000 or $E000), but newer utility cartridges were less intrusive, hiding themselves until called upon. Because of this "stealthing" method, a special cartridge format was necessary, to let the emulator where the cartridge should reside, as well as any special hardware features it uses. Here is a dump of a cartridge supplied with the CCS emulator, which contains the CCS Machine Language Monitor... 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII ----------------------------------------------- ---------------- 0000: 43 36 34 20 43 41 52 54 52 49 44 47 45 20 20 20 C64CARTRIDGE 0010: 00 00 00 20 01 00 00 00 00 01 00 00 00 00 00 00 0020: 43 43 53 4D 4F 4E 00 00 00 00 00 00 00 00 00 00 CCSMON 0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0040: 43 48 49 50 00 00 20 10 00 00 00 00 80 00 20 00 CHIP Bytes:$0000-000F - 16-byte cartridge signature "C64 CARTRIDGE " 0010-0013 - File header length ($00000020, in high/low format starting at offset $0000 0014-0015 - Cartridge version (high/low, presently $0100) 0016-0017 - Cartridge hardware type ($0000) 0 - Normal cartridge 1 - Action Replay 2 - KCS Power Cartridge 0018 - Cartridge port EXROM line active 0 - inactive 1 - active 0019 - Cartridge port GAME line active 0 - inactive 1 - active 001A-001F - Reserved for future use 0020-003F - 32-byte cartridge name "CCSMON" (null terminated) 0040-xxxx - Cartridge contents (called CHIP PACKETS, as there can be more than one per CRT file) Folling is the contents of the above HEX dump, from position $0040 on. Note I have re-adjusted the starting address to be $0000, since we are now looking at a file contained in the .CRT file, and all size references are from where it starts. 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII ----------------------------------------------- ---------------- 0000: 43 48 49 50 00 00 20 10 00 00 00 00 80 00 20 00 CHIP 0010: 00 94 63 94 C3 C2 CD 38 30 00 01 02 03 04 11 06 c80 0020: 07 08 09 0C 0D 0E 0F 12 13 14 15 17 18 23 24 2A #$* 0030: 3B 3A 25 27 2D 2B 2C 05 00 10 FF FF 10 8B B6 91 ;:%'-+, 0040: B2 87 DE 8B A5 93 DC 82 64 83 2E 91 82 85 B8 88 ދ܂d. Bytes:$0000-0003 - Contained ROM image signature "CHIP" (note there can be more than one image in a .CRT file) 0004-0007 - Total packet length ($00002010, ROM image size and header combined) 0008-0009 - Chip type 0 - ROM 1 - RAM, no ROM data 000A-000B - Bank location (0 - normal cartridge) 000C-000D - Load address range (high/low format) 000E-000F - ROM image size (high/low format) 0010-xxxx - ROM data *** CKIT (Compression KIT compressed files) *** Document revision 1.1 Written by Eugene F. Barker and Ryan Vander Stoep, this archiver does whole-disk archiving from the various Commodore drives (1541/1571/1581), as well as the larger CMD drives (hard disks). The latest known version is "CKIT-94", meaning it was released in 1994. The compressor program is commercial and dongle protected, but the decompressor is publically available. From reports I have received the compression used is RLE, which is not generally very good and it is also not very fast. One point in CKIT's favor is that it supports all the presently available storage devices (CMD hard disks, 15xx). The file extension for single disk files (i.e. when a compressed disk image only takes up one archive file) is "C4-". If an compressed image takes more than 1 file, the extension changes to "C4A" for the first and "C`A" for the second. I do not know what the extensions will be for compressed files taking more than two images, but CKIT does allow for an archive to span up to 27 disks. The header of the compressed file always starts with the string "MMS " (with a space and $00 null termination) which stands for "Mad Man Software", the company which makes the product. 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII ----------------------------------------------- ---------------- 0000: 4D 4D 53 20 00 58 58 21 90 89 A0 00 60 00 04 00 MMSXX!`. 0010: 00 29 5A EC 94 03 40 06 20 2F BF D5 20 B4 68 81 )Z.@./h 0020: A0 8D 10 B4 10 AF 15 03 61 08 07 50 00 10 80 68 ....a..P.h 0030: 8A 88 08 91 03 32 1A 0F B7 30 1D 94 D0 7B 28 80 ..2..0.{( Byte: $0000-0004 - ASCII string "MMS " with null termination. 0005-???? - Compressed data Any other information on this format would be greatly appreciated. *** Conclusion This document was compiled in an attempt to unify all the other smaller files dealing with file types that are floating about the net, or that exist with other programs. It is by no means exhaustive (even though it looks like it), but attempts will be made to keep it up-to-date, and correct anything which is wrong. Use it, pass it around, upload it, whatever. Just be sure to leave it INTACT, don't remove bits of it. The following people have helped in many ways with the details, compilation, source code and other aspects of this document (whether they know it or not!): Immers/Neufeld ----- 1541 disk layout (from "Inside Commodore DOS") Joe Forster/STA ---- FilePacked ZipCode, basic LHA/LZH header layout, LBR samples/layout, GEOS info, many document corrections Jouko Valta -------- The latest X64 specification and header layout Marko Makela ------- Generic LNX format Andreas Varga ------ GEOS file information Miha Peternel ------ Basic T64 layout, FRZ (C64s version <= 2.0) file info Wolfgang Lorenz ---- Conversion algorithm for PC64 files, .C64 file info Andre Fachat ------- CPK format layout (he's the author) Peter Weighill ----- Info on C64 bitmap images and Power64 saved files Todd Elliott ------- Info on WRAptor, more info on CKIT-94 John Iannetta ------ SPYne info (he's the author) Markus Mehring ----- 64NET, 64LAN, PCLINK custom files Christian Link ----- F64 info and sample binaries Per Hakan Sundell -- CRT ROM cartridge layout A very special thank you goes to Paul David Doherty for his extensive (what an understatement!) contributions regarding the 4 & 5 file DiskPacked ZipCode format, Sixpack ZipCode, much of the GEOS file layout, some ideas/samples for CKIT, and proof-reading this entire document! Without his help, all three file format areas would rather sparse, and there would be lots of silly spelling mistakes as well. Also, plenty of good information can also be gleaned from the source code contained in the archive CBMConvert, which is on the FTP.FUNET.FI FTP site. Contained in it are the sources for UnZipCode, UnLNX, Ark, some LHA info, etc. It is an invaluable set of utilities put together by both Marko Makela and Paul Doherty. I also don't want to forget the volunteer "testers". They are in no particular order, and not all are included as I don't have an official tester group: Pontus Berg ------ General testing, ideas, WWW promotion, sounding board. Quite a lot actually! Kai Lewinski ----- Testing and bug reporting on lower-end machines (DOS only, 286/386/486, no math-coprocessors, no Win95) Wolfgang Stoeggl - More ideas, testing. Paul Doherty ----- More ideas, testing. Matthias Walther - All-around beta-testing and great program thrashing. If there's a bug, he'll find it! Noam Ravid ------- More testing. --------------------------------------------------------------------------- BINARY/HEX/DECIMAL conversion chart Binary HEX Dec Binary HEX Dec Binary HEX Dec Binary HEX Dec ---------------- ---------------- ---------------- ---------------- 00000000 $00 0 01000000 $40 64 10000000 $80 128 11000000 $C0 192 00000001 01 1 01000001 41 65 10000001 81 129 11000001 C1 193 00000010 02 2 01000010 42 66 10000010 82 130 11000010 C2 194 00000011 03 3 01000011 43 67 10000011 83 131 11000011 C3 195 00000100 04 4 01000100 44 68 10000100 84 132 11000100 C4 196 00000101 05 5 01000101 45 69 10000101 85 133 11000101 C5 197 00000110 06 6 01000110 46 70 10000110 86 134 11000110 C6 198 00000111 07 7 01000111 47 71 10000111 87 135 11000111 C7 199 00001000 08 8 01001000 48 72 10001000 88 136 11001000 C8 200 00001001 09 9 01001001 49 73 10001001 89 137 11001001 C9 201 00001010 0A 10 01001010 4A 74 10001010 8A 138 11001010 CA 202 00001011 0B 11 01001011 4B 75 10001011 8B 139 11001011 CB 203 00001100 0C 12 01001100 4C 76 10001100 8C 140 11001100 CC 204 00001101 0D 13 01001101 4D 77 10001101 8D 141 11001101 CD 205 00001110 0E 14 01001110 4E 78 10001110 8E 142 11001110 CE 206 00001111 0F 15 01001111 4F 79 10001111 8F 143 11001111 CF 207 00010000 10 16 01010000 50 80 10010000 90 144 11010000 D0 208 00010001 11 17 01010001 51 81 10010001 91 145 11010001 D1 209 00010010 12 18 01010010 52 82 10010010 92 146 11010010 D2 210 00010011 13 19 01010011 53 83 10010011 93 147 11010011 D3 211 00010100 14 20 01010100 54 84 10010100 94 148 11010100 D4 212 00010101 15 21 01010101 55 85 10010101 95 149 11010101 D5 213 00010110 16 22 01010110 56 86 10010110 96 150 11010110 D6 214 00010111 17 23 01010111 57 87 10010111 97 151 11010111 D7 215 00011000 18 24 01011000 58 88 10011000 98 152 11011000 D8 216 00011001 19 25 01011001 59 89 10011001 99 153 11011001 D9 217 00011010 1A 26 01011010 5A 90 10011010 9A 154 11011010 DA 218 00011011 1B 27 01011011 5B 91 10011011 9B 155 11011011 DB 219 00011100 1C 28 01011100 5C 92 10011100 9C 156 11011100 DC 220 00011101 1D 29 01011101 5D 93 10011101 9D 157 11011101 DD 221 00011110 1E 30 01011110 5E 94 10011110 9E 158 11011110 DE 222 00011111 1F 31 01011111 5F 95 10011111 9F 159 11011111 DF 223 00100000 20 32 01100000 60 96 10100000 A0 160 11100000 E0 224 00100001 21 33 01100001 61 97 10100001 A1 161 11100001 E1 225 00100010 22 34 01100010 62 98 10100010 A2 162 11100010 E2 226 00100011 23 35 01100011 63 99 10100011 A3 163 11100011 E3 227 00100100 24 36 01100100 64 100 10100100 A4 164 11100100 E4 228 00100101 25 37 01100101 65 101 10100101 A5 165 11100101 E5 229 00100110 26 38 01100110 66 102 10100110 A6 166 11100110 E6 230 00100111 27 39 01100111 67 103 10100111 A7 167 11100111 E7 231 00101000 28 40 01101000 68 104 10101000 A8 168 11101000 E8 232 00101001 29 41 01101001 69 105 10101001 A9 169 11101001 E9 233 00101010 2A 42 01101010 6A 106 10101010 AA 170 11101010 EA 234 00101011 2B 43 01101011 6B 107 10101011 AB 171 11101011 EB 235 00101100 2C 44 01101100 6C 108 10101100 AC 172 11101100 EC 236 00101101 2D 45 01101101 6D 109 10101101 AD 173 11101101 ED 237 00101110 2E 46 01101110 6E 110 10101110 AE 174 11101110 EE 238 00101111 2F 47 01101111 6F 111 10101111 AF 175 11101111 EF 239 00110000 30 48 01110000 70 112 10110000 B0 176 11110000 F0 240 00110001 31 49 01110001 71 113 10110001 B1 177 11110001 F1 241 00110010 32 50 01110010 72 114 10110010 B2 178 11110010 F2 242 00110011 33 51 01110011 73 115 10110011 B3 179 11110011 F3 243 00110100 34 52 01110100 74 116 10110100 B4 180 11110100 F4 244 00110101 35 52 01110101 75 117 10110101 B5 181 11110101 F5 245 00110110 36 54 01110110 76 118 10110110 B6 182 11110110 F6 246 00110111 37 55 01110111 77 119 10110111 B7 183 11110111 F7 247 00111000 38 56 01111000 78 120 10111000 B8 184 11111000 F8 248 00111001 39 57 01111001 79 121 10111001 B9 185 11111001 F9 249 00111010 3A 58 01111010 7A 122 10111010 BA 186 11111010 FA 250 00111011 3B 59 01111011 7B 123 10111011 BB 187 11111011 FB 251 00111100 3C 60 01111100 7C 124 10111100 BC 188 11111100 FC 252 00111101 3D 61 01111101 7D 125 10111101 BD 189 11111101 FD 253 00111110 3E 62 01111110 7E 126 10111110 BE 190 11111110 FE 254 00111111 3F 63 01111111 7F 127 10111111 BF 191 11111111 FF 255 *** CPK *** Document revision 1.1 This format, created by Andre Fachat, was not designed for the emulators specifically, but was made primarily for Andre's own purposes. It is a very basic format using simple RLE compression, with each file following in sequential order (as Andre put it, "its similar to a UNIX TAR file"). There is no central directory, none of the files are byte aligned, and it uses compression so every file will be different. 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII ----------------------------------------------- ---------------- 0000: 01 40 41 2E 41 4E 4C 2C 50 00 01 08 24 08 64 00 .@A.ANL,P..$.d 0010: 99 22 93 20 20 20 41 4E 4C 45 49 54 55 4E 47 20 "ANLEITUNG 0020: 5A 55 4D 20 40 41 53 53 45 4D 42 4C 45 52 00 4E ZUM@ASSEMBLERN 0030: 08 6E 00 99 22 11 40 41 53 53 20 49 53 54 20 45 .n".@ASSISTE 0040: 49 4E 20 32 2D 50 41 53 53 2D 41 53 53 45 4D 42 IN2-PASS-ASSEMB 0050: 4C 45 52 2E 20 44 45 52 00 78 08 78 00 99 22 11 LER.DERx.x". The first byte of the file is the version byte. Presently, only $01 is supported. 0000: 01 .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ................ The filename follows, stored in standard PETASCII, and no padding characters ($A0) are included. 0000: .. 40 41 2E 41 4E 4C .. .. .. .. .. .. .. .. .. .@A.ANL......... The filetype is attached to the end of the filename in the form of ',x', where x is the filetype used (P,S,U), and it is in PETASCII upper case. The filename ends with a $00 (null terminated). REL files are *not* supported as there is no provision made for the RECORD size byte. Note that not *all* CPK files will have the ",x" extension added on. If it doesn't exist, assume that the file is a "PRG" type. 0000: .. .. .. .. .. .. .. 2C 50 00 .. .. .. .. .. .. .......,P...... Following the filename, we get program data. 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII ----------------------------------------------- ---------------- 0000: .. .. .. .. .. .. .. .. .. .. 01 08 24 08 64 00 ............$.d 0010: 99 22 93 20 20 20 41 4E 4C 45 49 54 55 4E 47 20 "ANLEITUNG ... 0270: 00 83 0A E6 00 99 22 11 20 20 31 32 33 F7 08 20 ".123. 0280: 2D 44 45 5A 49 4D 41 4C 00 A4 0A F0 00 99 22 11 -DEZIMAL". 0290: 20 20 24 33 34 35 F7 07 20 2D 48 45 58 41 44 45 $345.-HEXADE The data requires some explanation as it uses RLE (Run Length Encoding) compression. When creating the archives, data in the file to be compressed is scanned for runs of repeating bytes, and when a string of 3 or more (up to 255) is found, then the following sequence of bytes is output... $F7 $xx $yy - where F7 is the code used for "encoded sequence follows", $xx is the number of times to repeat the byte and $yy is the byte to repeat. Using the sample below, we see the F7 code, then a "repeat 7 times the number $20" 0290: .. .. .. .. .. .. F7 07 20 .. .. .. .. .. .. .. .............. Using $F7 as the encoder byte presents one problem: When encoding a file, and we encounter an $F7, what does the packer do? Simple, it gets encoded into $F7 $xx $F7 meaning repeat $F7 for as many times as is needed (if its only 1 $F7, then the value for $xx is $01). The code 'F7' was chosen because it is not a 6502 opcode, a BASIC token, or any commonly used byte, but *not* because it has the least statistical probability of occuring. The stored program ends when the string $F7 $00 is encountered, since this sequence can not occur in the file naturally. If you need to search through a CPK file for the filenames, do a hex search for all $F7 $00 sequences, since they preceed all filenames except the first. The end of the archive is known two different ways: 1. When an EOF (end of file) occurs, after an $F7 $00 byte sequence. This is the normal method. 2. When a filename of $00 occurs, meaning there is no filename, just a null termination. This is not much used anymore. Using method #1 for ending the file is more common because it makes adding files to the archive very easy. All you have to do as append the new filename/data to the archive. Using method #2 means you have to check and see if the last three characters are $F7 $00 $00, and start writing the new file into the archive starting after the first $00. In order to extract *one* specific file, you would need to read the whole archive until you find the filename you want, then output that file only. As this format has no central directory and no file location references, there is no other way to do it. This format has not been used for some time now, as when it came out D64 and T64 were also being developed and accepted into common use. It is unlikely you will find *any* files in this format. 64COPY V3.2 (and up) does support extraction of these files just in case any are encountered. *** CVT (ConVerT) *** Document revision 1.1 These are sequential representations of GEOS files, both sequential and VLIR. In order to be transmitted and up/downloaded, they must be converted to this intermediate format because the file's INFO block must be included. Note that the track/sector references at the beginning of each sector are not included here, making the block size 254 bytes. Also, any values in track/sector references are invalid, since the value is sure to change once the file is converted back from CVT to a GEOS format. I will not include much of the GEOS file layout details here, as you can read the GEOS.TXT document to get the information. With CVT's that contain VLIR files, there are four distinct sections: signature, info, record and data. CVT's that contain non-VLIR files (i.e. standard GEOS sequential) do not include the record block. The first part, which exists in both CVT types, is the signature block. It contains the complete directory entry and CVT file signature. 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII ----------------------------------------------- ---------------- 0000: 83 00 00 44 45 53 4B 20 54 4F 50 A0 A0 A0 A0 A0 DESKTOP 0010: A0 A0 A0 00 00 01 04 58 08 13 0D 23 78 00 50 52 ..X...#xPR 0020: 47 20 66 6F 72 6D 61 74 74 65 64 20 47 45 4F 53 GformattedGEOS 0030: 20 66 69 6C 65 20 56 31 2E 30 00 00 00 00 00 00 fileV1.0 0040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 .. .. .. Byte:$00-1D: Complete directory entry. Note that the first two bytes of *any* directory entry are never used, and thus are not incuded here either. 1E-39: File signature. It can contain "PRG formatted..." or "SEQ formatted...". Here we can check that the CVT is really what it claims. 3A-FF: Usually $00 What follows the signature block is the complete GEOS file INFO block. 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII ----------------------------------------------- ---------------- 00F0: .. .. .. .. .. .. .. .. .. .. .. .. .. .. 03 15 ................ 0100: BF FF FF FF 92 49 01 FF FF 01 80 00 1D BF FF DD I... 0110: A0 00 5D BF FF C1 A0 00 5D A1 C6 55 A0 29 5D A0 ]]U)] 0120: C9 41 A1 09 41 B9 D6 41 A8 00 41 BF FF C1 80 00 A.AAA 0130: 1D 9C 00 15 9C 00 15 80 00 1D 80 00 01 FF FF FF ..... 0140: 83 04 01 56 19 55 19 75 51 64 65 73 6B 54 6F 70 ..V.U.uQdeskTop 0150: 20 41 4D 20 20 56 32 2E 30 00 00 00 00 42 72 69 AMV2.0Bri 0160: 61 6E 20 44 6F 75 67 68 65 72 74 79 00 00 00 00 anDougherty 0170: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0180: 00 00 00 00 00 4C 2A 5B 4C 59 5D 4C A7 61 4C 3A L*[LY]LaL: 0190: 62 AD 8A 84 D0 01 60 20 7E 23 20 9C 55 73 65 20 b.`~#Use 01A0: 74 68 65 20 64 65 73 6B 54 6F 70 20 74 6F 20 6D thedeskToptom 01B0: 61 6E 61 67 65 20 61 6E 64 20 6D 61 6E 69 70 75 anageandmanipu 01C0: 6C 61 74 65 20 79 6F 75 72 20 66 69 6C 65 73 2E lateyourfiles. 01D0: 00 03 20 E3 5C 68 85 FB 20 4F 61 20 13 61 20 32 .\hOa.a2 01E0: 61 20 F2 5C A9 0C 20 CC 49 A9 2E 85 13 A9 F9 85 a\.I.. 01F0: 12 A9 2F 85 15 A9 01 85 14 A9 84 85 .. .. .. .. ./....... The third block is the RECORD block. In the sequential version of the CVT, this block won't exist. The way to well if the file is VLIR or sequential is to look at byte position 23 of the directory entry (from above, it's value is $01). If it's a $00, the file is sequential, if it's $01 it's VLIR. 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII ----------------------------------------------- ---------------- 01F0: .. .. .. .. .. .. .. .. .. .. .. .. 43 41 0A 0B ............CA.. 0200: 0B F4 0A 8C 0B A1 09 70 00 00 00 00 00 00 00 00 ..p 0210: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0220: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0230: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0240: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0250: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0260: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0270: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0290: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02F0: 00 00 00 00 00 00 00 00 00 00 .. .. .. .. .. .. ...... Note that the RECORD block is modified from the original GEOS entry. Instead of containing the track and sector references, we now have the sector count and the size of the last sector in the chain. Looking over the block above, we get the following usage chart: Count Size Comment ----- ---- -------------------------------------- 43 41 Sector count=67, last sector index=$41 0A 0B Sector count=10, last sector index=$0B 0B F4 Sector count=11, last sector index=$F4 0A 8C Sector count=10, last sector index=$8C 0B A1 Sector count=11, last sector index=$A1 09 70 Sector count=9, last sector index=$70 00 00 No more records. Two things of interest can be noted from the record block... 1. When a 00/00 is encountered, the record block is done. 2. When a 00/FF is encountered, the record does not exist (see the GEOS.TXT format for more info on invalid records), but the entry must still be made in the re-created RECORD block. From here on we have the actual data, all of the record chains strung together to form one long file. All of this data must be broken apart to form the original records that GEOS expects. 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII ----------------------------------------------- ---------------- 02F0: .. .. .. .. .. .. .. .. .. .. A9 00 8D EE 04 A4 ........... 0300: FE B9 86 84 30 06 29 0F C9 02 D0 12 A4 70 B9 86 0.)...p 0310: 84 30 06 29 0F C9 02 D0 05 A9 07 8D A0 1D 20 1E 0.)...... 0320: 23 20 04 1A 8A D0 20 20 12 1A 18 A9 00 6D F4 03 #.....m. 0330: 8D F4 03 A9 03 6D F5 03 8D F5 03 20 C5 22 20 7C ..m.."| 0340: 1B 20 04 1A 20 6B 1A A9 08 8D A0 1D B8 50 53 8D ...k...PS 0350: EE 04 20 12 1A A2 00 A4 70 20 3F 24 C9 04 B0 3F ...p?$.? *** D64 (Electronic form of a physical 1541 disk) *** Document revision 1.1 (Note: This document will try to explain the layout of the 1541 disks, as well as the files they contain. However, I do not explain GEOS files here. See the file GEOS.TXT for more information on that file type.) First and foremost we have D64, which is basically a sector-for-sector copy of a 1540/1541 disk. There are several versions of these which I will cover shortly. The standard D64 is a 174848 byte file comprised of 256 byte sectors arranged in 35 tracks with a varying number of sectors per track for a total of 683 sectors. Track counting starts at 1, not 0, and goes up to 35. Sector counting starts at 0, not 1, for the first sector, therefore a track with 21 sectors will go from 0 to 20. The original media (a 5.25" disk) has the tracks laid out in circles, with track 1 on the very outside of the disk (closest to the sides) to track 35 being on the inside of the disk (closest to the hub ring). Commodore (in their infinite wisdom) varied the number of sectors per track (and data densities across the disk) to optimize available storage, resulting in the chart below. It shows the sectors/track for a standard D64. Since the outside diameter of a circle is the largest (versus closer to the center), the outside tracks have the largest amount of storage. Track Sectors/track # Sectors ----- ------------- --------- 1-17 21 357 18-24 19 133 25-30 18 108 31-35 17 85 --- 683 Track #Sect #SectorsIn D64 Offset Track #Sect #SectorsIn D64 Offset ----- ----- ---------- ---------- ----- ----- ---------- ---------- 1 21 0 $00000 21 19 414 $19E00 2 21 21 $01500 22 19 433 $1B100 3 21 42 $02A00 23 19 452 $1C400 4 21 63 $03F00 24 19 471 $1D700 5 21 84 $05400 25 18 490 $1EA00 6 21 105 $06900 26 18 508 $1FC00 7 21 126 $07E00 27 18 526 $20E00 8 21 147 $09300 28 18 544 $22000 9 21 168 $0A800 29 18 562 $23200 10 21 189 $0BD00 30 18 580 $24400 11 21 210 $0D200 31 17 598 $25600 12 21 231 $0E700 32 17 615 $26700 13 21 252 $0FC00 33 17 632 $27800 14 21 273 $11100 34 17 649 $28900 15 21 294 $12600 35 17 666 $29A00 16 21 315 $13B00 36* 17 683 $2AB00 17 21 336 $15000 37* 17 700 $2BC00 18 19 357 $16500 38* 17 717 $2CD00 19 19 376 $17800 39* 17 734 $2DE00 20 19 395 $18B00 40* 17 751 $2EF00 *Extra tracks on 40-track images only The directory track should be contained totally on track 18. Sectors 1-18 contain the entries and sector 0 contains the BAM (Block Availability Map) and disk name/ID. Since the directory is only 18 sectors large (19 less one for the BAM), and each sector can contain only 8 entries (32 bytes per entry), the maximum number of directory entries is 18 * 8 = 144. The first directory sector is always 18/1, even though the t/s pointer at 18/0 (first two bytes) might point somewhere else. It then follows the same chain structure as a normal file. Each directory sector has the following layout (18/1 partial dump): 00: 12 04 81 11 00 4E 41 4D 45 53 20 26 20 50 4F 53 <- notice the T/S link 10: 49 54 A0 A0 A0 00 00 00 00 00 00 00 00 00 15 00 <- to 18/4 ($12/$04) 20: 00 00 84 11 02 41 44 44 49 54 49 4F 4E 41 4C 20 <- and how its not here 30: 49 4E 46 4F A0 11 0C FE 00 00 00 00 00 00 61 01 <- ($00/$00) The first two bytes of the sector ($12/$04) indicate the location of the next track/sector of the directory (18/4). If the track is set to $00, then it is the last sector of the directory. It is possible, however unlikely, that the directory may *not* be competely on track 18 (some disks do exist like this). Just follow the chain anyhow. When the directory is done, the track value will be $00. The sector link should contain a value of $FF, meaning the whole sector is allocated, but the actual value doesn't matter. The drive will return all the available entries anyways. This is a breakdown of a standard directory sector and entry: Bytes: $00-1F: First directory entry 00-01: Track/Sector location of next directory sector ($00 $00 if not the first entry in the sector) 02: File type. Typical values for this location are: $00 - Scratched (deleted file entry) 80 - DEL 81 - SEQ 82 - PRG 83 - USR 84 - REL Bit 0-3: The actual filetype 000 (0) - DEL 001 (1) - SEQ 010 (2) - PRG 011 (3) - USR 100 (4) - REL Values 5-15 are illegal, but if used will produce very strange results. The 1541 is inconsistent in how it treats these bits. Some routines use all 4 bits, others ignore bit 3, resulting in values from 0-7. Bit 4: Not used Bit 5: Used only during SAVE-@ replacement Bit 6: Locked flag (Set produces ">" locked files) Bit 7: Closed flag (Not set produces "*", or "splat" files) 03-04: Track/sector location of first sector of file 05-14: 16 character filename (in PETASCII, padded with $A0) 15-16: Track/Sector location of first side-sector block (REL file only) 17: REL file record length (REL file only) 18-1D: Unused (except with GEOS disks) 1E-1F: File size in sectors, low/high byte order ($1E+$1F*256). The approx. filesize in bytes is <= #sectors * 254 20-3F: Second dir entry. From now on the first two bytes of each entry in this sector should be $00 $00, as they are unused. 40-5F: Third dir entry 60-7F: Fourth dir entry 80-9F: Fifth dir entry A0-BF: Sixth dir entry C0-DF: Seventh dir entry E0-FF: Eighth dir entry Note: No GEOS entries are listed in the above description. See the GEOS.TXT file for GEOS info. The layout of the BAM area (sector 18/0) is a bit more complicated... 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ----------------------------------------------- 00: 12 01 41 00 12 FF F9 17 15 FF FF 1F 15 FF FF 1F 10: 15 FF FF 1F 12 FF F9 17 00 00 00 00 00 00 00 00 20: 00 00 00 00 0E FF 74 03 15 FF FF 1F 15 FF FF 1F 30: 0E 3F FC 11 07 E1 80 01 15 FF FF 1F 15 FF FF 1F 40: 15 FF FF 1F 15 FF FF 1F 0D C0 FF 07 13 FF FF 07 50: 13 FF FF 07 11 FF CF 07 13 FF FF 07 12 7F FF 07 60: 13 FF FF 07 0A 75 55 01 00 00 00 00 00 00 00 00 70: 00 00 00 00 00 00 00 00 01 08 00 00 03 02 48 00 80: 11 FF FF 01 11 FF FF 01 11 FF FF 01 11 FF FF 01 90: 53 48 41 52 45 57 41 52 45 20 31 20 20 A0 A0 A0 A0: A0 A0 56 54 A0 32 41 A0 A0 A0 A0 00 00 00 00 00 B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Bytes:$00-01: Track/Sector location of the first directory sector (should be set to 18/1 but it doesn't matter, and don't trust what is there, always go to 18/1 for first directory entry) 02: Disk DOS version type (see note below) $41 ("A") 03: Unused 04-8F: BAM entries for each track, in groups of four bytes per track, starting on track 1 (see below for more details) 90-9F: Disk Name (padded with $A0) A0-A1: Filled with $A0 A2-A3: Disk ID A4: Usually $A0 A5-A6: DOS type, usually "2A" A7-AA: Filled with $A0 AB-FF: Normally unused, except for 40 track extended format, see the following two entries: AC-BF: DOLPHIN DOS track 36-40 BAM entries (only for 40 track) C0-D3: SPEED DOS track 36-40 BAM entries (only for 40 track) Note: The BAM entries for SPEED and DOLPHIN dos use the same layout as standard BAM entries. One of the interesting things from the BAM sector is the byte at offset $02, the DOS version byte. If it is set to anything other than $41 or $00, then we have what is called "soft write protection". Any attempt to write to the disk will return the "DOS Version" error code 73 ,"CBM DOS V 2.6 1541". The 1541 is simply telling you that it thinks the disk format version is incorrect. This message will normally come up when you first turn on the 1541 and read the error channel. If you write a $00 or a $41 into 1541 memory location $00FF (for device 0), then you can circumvent this type of write-protection, and change the DOS version back to what it should be. The BAM entries require a bit (no pun intended) more of a breakdown. Take the first entry at bytes $04-$07 ($12 $FF $F9 $17). The first byte ($12) is the number of free sectors on that track. Since we are looking at the track 1 entry, this means it has 18 (decimal) free sectors. The next three bytes represent the bitmap of which sectors are used/free. Since it is 3 bytes (8 bits/byte) we have 24 bits of storage. Remember that at most, each track only has 21 sectors, so there are a few unused bits. Bytes: 04-07: 12 FF F9 17 Track 1 BAM 08-0B: 15 FF FF FF Track 2 BAM 0C-0F: 15 FF FF 1F Track 3 BAM ... 8C-8F: 11 FF FF 01 Track 35 BAM These entries must be viewed in binary to make any sense. We will use the first entry (track 1) at bytes 04-07: FF=11111111, F9=11111001, 17=00010111 In order to make any sense from the binary notation, flip the bits around. 111111 11112222 01234567 89012345 67890123 -------------------------- 11111111 10011111 11101000 ^ ^ sector 0 sector 20 Since we are on the first track, we have 21 sectors, and only use up to the bit 20 position. If a bit is on (1), the sector is free. Therefore, track 1 has sectors 9,10 and 19 used, all the rest are free. Each filetype has its own unique properties, but most follow one simple structure. The first file sector is pointed to by the directory and follows a t/s chain, until the track value reaches $00. When this happens, the value in the sector link location indicates how much of the sector is used. For example, the following chain indicates a file 6 sectors long, and ends when we encounter the $00/$34 chain. At this point the last sector occupies from bytes $02-$34. 1 2 3 4 5 6 ---- ----- ----- ----- ----- ----- 17/0 17/10 17/20 17/1 17/11 0/52 (11/00) (11/0A) (11/14) (11/01) (11/0B) (0/34) --------------------------------------------------------------------------- *** REL files The REL filetype, however, has a most unusual structure. It was designed to make access to data *anywhere* on the disk very fast. Take a look at this directory entry... 00: 00 00 84 11 02 41 44 44 49 54 49 4F 4E 41 4C 20 ..ADDITIONAL 10: 49 4E 46 4F A0 11 0C FE 00 00 00 00 00 00 61 01 INFO..a. The third byte ($84) indicates this entry is a REL file and that the three normally empty entries at offset $15, $16 and $17 are now used as they are explained above. It's the sector chain that this entry points to (called the SIDE SECTORS) which are of interest here (in this case, 17/12). Here is a dump of the beginning of that sector... 00: 0C 13 00 FE 11 0C 0C 13 06 09 00 00 00 00 00 00 10: 11 02 11 0D 11 03 11 0E 11 04 11 0F 11 05 11 10 Bytes: $00: Track location of next side-sector ($00 if last sector) 01: Sector location of next side-sector 02: Side-sector block number (first sector is $00, the next is $01, then $02, etc) 03: REL file RECORD size (from directory entry) 04-0F: Track/sector locations of the six other side-sectors. Note the first entry is this very sector we have listed here. The next is the next t/s listed at the beginning of the sector. All of this information must be correct. If one of these chains is $00/$00, then we have no more side sectors. Also, all of these (up to six) side sectors must have the same values in this range. 10-FF: T/S chains of *each* sector of the data portion. When we get a $00/$00, we are at the end of the file. If the speed advantage regarding this type file file isn't obvious yet, consider the following scenario... If we need record 4000, its only a couple of calculations to see how many bytes into the file it is (record# * record length). Once we know this, we can calculate how many sectors into the file it is (result/254). Now that we know the number of sectors, we can look it up in our side-sector tables to see where the record is. The speed of this system is truly amazing, given the era of the C64, and a floppy drive. --------------------------------------------------------------------------- *** Variations on the D64 layout These are some variations of the D64 layout: 1. Standard 35 track layout but with 683 error bytes added on to the end of the file. Each byte of the error info corresponds to a single sector stored in the D64, indicating if the sector on the original disk contained an error. The first byte is for track 1/0, and the last byte is for track 35/16. 2. A 40 track layout, following the same layout as a 35 track disk, but with 5 extra tracks. These contain 17 sectors each, like tracks 31-35. Some of the PC utilities do allow you to create and work with these files. The location of the extra BAM information in sector 18/0 will be different depending on what standard the disks have been formatted with. SPEED DOS stores them from $C0 to $D3, and DOLPHIN DOS stores them from $AC to $BF. 64COPY and Star Commander lets you select from several different types of extended disk formats you want to create/work with. Disk type Size --------- ------ 35 track, no errors 174848 35 track, 683 error bytes 175531 40 track, no errors 196608 40 track, 768 error bytes 197376 Here is the meaning of the error bytes added onto the end of any extended D64. The CODE is the same as that generated by the 1541 drive controller... it reports these numbers, not the error code we usually see when an error occurs. Some of what comes below is taken from Immers/Neufeld book "Inside Commodore DOS". Note the descriptions are not completely accurate as to what the drive DOS is actually doing to seek/read/decode/write sectors, but serve as simple examples only. The "type" field is where the error usually occurs, but it can occur elsewhere. Code Error Type 1541 error description ---- ----- ---- ------------------------------ 01 00 N/A No error. Self explanatory. No errors were detected in the reading and decoding of the sector. 02 20 Read Header descriptor byte not found ($08) Each sector is preceeded by an 8-byte header block, which starts with the value $08. If this value is not $08, this error is generated. 03 21 R/W No sync sequence found. Each sector data block and header block are preceeded by SYNC marks. If *no* sync sequence is found, then the whole track is unreadable, and likely unformatted. 04 22 Read Data descriptor byte not found ($07) Each sector data block is preceeded by the value $07, the "data block" descriptor. If this value is not there, this error is generated. Each encoded sector has actually 260 bytes. First is the descriptor byte, then follows the 256 bytes of data, a checksum, and two "off" bytes. 05 23 Read Checksum error in data block The checksum of the data read of the disk is calculated, and compared against the one stored at the end of the sector. If there's a discrepancy, this error is generated. 06 24 Write Write verify (on format) 07 25 Write Write verify error Once the GCR-encoded sector is written out, the drive waits for the sector to come around again and verifies the whole 325-byte GCR block. Any errors encountered will generate this error. 08 26 Write Write protect on Self explanatory. Remove the write-protect tab, and try again. 09 27 Seek Checksum error in header block The 8-byte header block contains a checksum value, calculated by XOR'ing the TRACK, SECTOR, ID1 and ID2 values. If this checksum is wrong, this error is generated. 0A 28 Write Write error In actual fact, this error never occurs, but it is included for completeness. 0B 29 Seek Disk sector ID mismatch The ID's from the header block of the currently read sector are compared against the ones from the header of 18/0. If there is a mismatch, this error is generated. 0F 74 Read Drive Not Ready (no device 1) The advantage with using the 35 track D64 format, regardless of error bytes, is that it can be converted directly back to a 1541 disk by either using the proper cable and software on the PC, or send it down to the C64 and writing it back to a 1541. It is the best documented format since it is also native to the C64, with many books explaining the disk layout and the internals of the 1541. --------------------------------------------------------------------------- What it takes to support D64: The D64 layout is probably the most robust of all the ones that exist, being that it is an electronic representation of a physical 1541 disk. It shares *most* of the 1541 attributes and it supports all file formats, since all C64 files came from here. The only file I have found that can't be copied to a D64 is a T64 FRZ (FRoZen image), since you lose the file type attribute. Since the D64 layout seems to be an exact byte copy of a 1541 floppy, it would appear to be the perfect format for *any* emulator. However, it does not contain certain vital bits of information that, as a user, you normally don't have access to on a 1541 floppy. Preceeding each sector on a real 1541 disk, there is a header block which contains the sector ID bytes and checksum. From the information contained in the header, the drive determines if there's an error on that header (27-checksum error, 29-disk ID mismatch). The sector itself also contains info (data block signature, checksum) that result in error detection (23 checksum, 22 data block not present, etc). The error bytes had to be added on to the D64 image, "extending" the format to take into account the missing info. The disk ID is important in the copy protection of some programs. Since the D64 doesn't contain these ID's, some programs fail to work properly. These bytes are an addition to the format which has never been done, and would be difficult to do. (As an aside, the 4-pack ZipCode files do contain the original master disk ID, but these are lost in the conversion of a ZipCode to a D64. Only storing *one* of the ID's is not enough, all the sector ID's should be kept.) The extended track 1541 disks also presented a problem, as there are several different formats (and how/where to store the extra BAM entries in a sector that was not designed for them, yet still remain compatible). Because of the additions to the format (error bytes and 40 tracks) there exists 4 different types of D64's, all recognizeable by their size. It is also the only format that uses the sector count for the file size rather than actual bytes used. This can present some problems when converting/copying the to another format because you may have to know the size before you begin (see LBR format). It also contains no consistent signature, useful for recognizing if a file is really what it claims to be. In order to determine if a file is a D64, you must check the file size. --------------------------------------------------------------------------- Overall Good/Bad of D64 Files: Good ---- * D64 files are the most widely supported and well-defined format, as it is simply an electronic version of a 1541 disk * Supports *all* filenames, even those with $00's in them * Filenames are padded with the standard $A0 character * Supports GEOS files * Supports REL files * Allows complete directory customization * Because it is a random-access device, it supports fast-loaders and random sector access * Cluster slack-space loss is minimized since the file is a larger fixed size * Has a label (description) field * Format extentible to allow for 40-track disks * With the inclusion of error bytes, you have support for basic copy-protection * Files on a disk can easily be re-written, as long as there is free blocks Bad --- * The format doesn't contain *all* the info from the 1541 disk (no sector header info like ID bytes, checksums). This renders some of the original special-loaders and copy-protection useless. * You don't *really* know the file size of the contained C64 files in bytes, only blocks * It can't store C64s FRZ files due to FRZ files needing a special flag that a D64 can't store * It is not an expandable filesize, like LNX or T64 * Unless most of the space on a D64 disk is used, you do end up with lost space * Directory limited to 144 files maximum * Cannot have loadable files with the same names * Has no recognizeable file signature (unlike most other formats). The only reliable way to know if a file is a D64 is by its size * It is too easy for people to muck up the standard layout * It is much more difficult to support fully, as you really need to emulate the 1541 DOS (sector interleave, REL support, GEOS interleave) *** D71 (Electronic form of a double-sided 1571 disk) *** Document revision 1.1 Similar to the D64 (1541), the 1571 drive can operate in either single-sided (1541 compatible) mode or double-sided (1571) mode. In this document I will be dealing with the double-sided mode only. For the breakdown of the single-sided mode, read the D64.TXT document. The D71 has 70 tracks, double that of the 1541, with a DOS file size of 349696 bytes. If the error byte block (1366 bytes) is attached, this makes the file size 351062 bytes. The track range and offsets into the D71 files are as follows: Track Sec/trk # Sectors -------------- ------- --------- 1-17 (side 0) 21 357 18-24 (side 0) 19 133 25-30 (side 0) 18 108 31-35 (side 0) 17 85 36-52 (side 1) 21 357 53-59 (side 1) 19 133 60-65 (side 1) 18 108 66-70 (side 1) 17 85 --- total 1366 Track #Sect #SectorsIn D71 Offset Track #Sect #SectorsIn D71 Offset ----- ----- ---------- ---------- ----- ----- ---------- ---------- 1 21 0 $00000 36 21 683 $2AB00 2 21 21 $01500 37 21 704 $2C000 3 21 42 $02A00 38 21 725 $2D500 4 21 63 $03F00 39 21 746 $2EA00 5 21 84 $05400 40 21 767 $2FF00 6 21 105 $06900 41 21 788 $31400 7 21 126 $07E00 42 21 809 $32900 8 21 147 $09300 43 21 830 $33E00 9 21 168 $0A800 44 21 851 $35300 10 21 189 $0BD00 45 21 872 $36800 11 21 210 $0D200 46 21 893 $37D00 12 21 231 $0E700 47 21 914 $39200 13 21 252 $0FC00 48 21 935 $3A700 14 21 273 $11100 49 21 956 $3BC00 15 21 294 $12600 50 21 977 $3D100 16 21 315 $13B00 51 21 998 $3E600 17 21 336 $15000 52 21 1019 $3FB00 18 19 357 $16500 53 19 1040 $41000 19 19 376 $17800 54 19 1059 $42300 20 19 395 $18B00 55 19 1078 $43600 21 19 414 $19E00 56 19 1097 $44900 22 19 433 $1B100 57 19 1116 $45C00 23 19 452 $1C400 58 19 1135 $46F00 24 19 471 $1D700 59 19 1154 $48200 25 18 490 $1EA00 60 18 1173 $49500 26 18 508 $1FC00 61 18 1191 $4A700 27 18 526 $20E00 62 18 1209 $4B900 28 18 544 $22000 63 18 1227 $4CB00 29 18 562 $23200 64 18 1245 $4DD00 30 18 580 $24400 65 18 1263 $4EF00 31 17 598 $25600 66 17 1281 $50100 32 17 615 $26700 67 17 1298 $51200 33 17 632 $27800 68 17 1315 $52300 34 17 649 $28900 69 17 1332 $53400 35 17 666 $29A00 70 17 1349 $54500 The directory structure is the same as a D64/1541. All the same filetypes apply, the directory still only holds 144 files per disk and should only exist on track 18. The first two bytes of the sector ($12/$04 or 18/4) indicate the location of the next track/sector of the directory. If the track value is set to $00, then it is the last sector of the directory. It is possible, however unlikely, that the directory may *not* be competely on track 18 (some disks do exist like this). Just follow the chain anyhow. When the directory is done, the track value will be $00. The sector link should contain a value of $FF, meaning the whole sector is allocated, but the actual value doesn't matter. The drive will return all the available entries anyways. This is a breakdown of a standard directory sector and entry: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII ----------------------------------------------- ---------------- 00: 12 04 82 11 00 4A 45 54 20 53 45 54 20 57 49 4C .JETSETWIL 10: 4C 59 A0 A0 A0 00 00 00 00 00 00 00 00 00 2B 00 LY+ 20: 00 00 82 0F 01 4A 53 57 20 31 A0 A0 A0 A0 A0 A0 ..JSW1 30: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 BF 00 40: 00 00 82 06 03 53 4F 4E 20 4F 46 20 42 4C 41 47 ..SONOFBLAG 50: 47 45 52 A0 A0 00 00 00 00 00 00 00 00 00 AE 00 GER 60: 00 00 82 15 0D 50 4F 54 54 59 20 50 49 47 45 4F ..POTTYPIGEO 70: 4E A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 A2 00 N 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Bytes: $00-1F: First directory entry 00-01: Track/Sector location of next directory sector ($00/$FF if its the last sector) 02: File type. Typical values for this location are: $00 - Scratched (deleted file entry) 80 - DEL 81 - SEQ 82 - PRG 83 - USR 84 - REL Bit 0-3: The actual filetype 000 (0) - DEL 001 (1) - SEQ 010 (2) - PRG 011 (3) - USR 100 (4) - REL Values 5-15 are illegal, but if used will produce very strange results. The 1541 is inconsistent in how it treats these bits. Some routines use all 4 bits, others ignore bit 3, resulting in values from 0-7. Bit 4: Not used Bit 5: Used only during SAVE-@ replacement Bit 6: Locked flag (Set produces ">" locked files) Bit 7: Closed flag (Not set produces "*", or "splat" files) 03-04: Track/sector location of first sector of file 05-14: 16 character filename (in PETASCII, padded with $A0) 15-16: Track/Sector location of super side-sector block (REL file only) 17: REL file record length (REL file only) 18-1D: Unused (except with GEOS disks) 1C-1D: Track/sector of replacement file (only used during an @SAVE or an @OPEN command) 1E-1F: File size in sectors, low/high byte order ($1E+$1F*256). The approx. filesize in bytes is <= #sectors * 254 20-3F: Second dir entry. From now on the first two bytes of each entry in this sector should be $00/$00, as they are unused. 40-5F: Third dir entry 60-7F: Fourth dir entry 80-9F: Fifth dir entry A0-BF: Sixth dir entry C0-DF: Seventh dir entry E0-FF: Eighth dir entry When the 1571 is in is native ("1571") mode, files are stored with a sector interleave of 6, rather than 10 which the 1541 (and the 1571 in "1541" mode) uses. The directory still uses an interleave of 3. The BAM is somewhat different as it now has to take 35 new tracks into account. In order to do this, most of the extra BAM information is stored on track 53/0, and the remaining sectors on track 53 are marked in the BAM as allocated. This does mean that except for one allocated sector on track 53, the rest of the track is unused and wasted. (Track 53 is the equivalent to track 18, but on the flip side of the disk). Here is a dump of the first BAM sector... 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII ----------------------------------------------- ---------------- 00: 12 01 41 80 12 FF F9 17 15 FF FF 1F 15 FF FF 1F ..A...... 10: 15 FF FF 1F 15 FF FF 1F 15 FF FF 1F 15 FF FF 1F ........ 20: 15 FF FF 1F 15 FF FF 1F 15 FF FF 1F 15 FF FF 1F ........ 30: 15 FF FF 1F 15 FF FF 1F 15 FF FF 1F 15 FF FF 1F ........ 40: 15 FF FF 1F 15 FF FF 1F 11 FC FF 07 13 FF FF 07 ........ 50: 13 FF FF 07 13 FF FF 07 13 FF FF 07 13 FF FF 07 ........ 60: 13 FF FF 07 12 FF FF 03 12 FF FF 03 12 FF FF 03 ........ 70: 12 FF FF 03 12 FF FF 03 12 FF FF 03 11 FF FF 01 ........ 80: 11 FF FF 01 11 FF FF 01 11 FF FF 01 11 FF FF 01 ........ 90: A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0: A0 A0 30 30 A0 32 41 A0 A0 A0 A0 00 00 00 00 00 002A B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 15 15 15 ... E0: 15 15 15 15 15 15 15 15 15 15 15 15 15 15 00 13 ................ F0: 13 13 13 13 13 12 12 12 12 12 12 11 11 11 11 11 ................ Bytes:$00-01: Track/Sector location of the first directory sector (should be set to 18/1 but it doesn't matter, and don't trust what is there, always go to 18/1 for first directory entry) 02: Disk DOS version type (see note below) $41 ('A') = 1541 03: Double-sided flag $00 - Single sided disk $80 - Double sided disk 04-8F: BAM entries for each track, in groups of four bytes per track, starting on track 1. 90-9F: Disk Name (padded with $A0) A0-A1: Filled with $A0 A2-A3: Disk ID A4: Usually $A0 A5-A6: DOS type, usually "2A" A7-AA: Filled with $A0 AB-DC: Not used ($00's) DD-FF: Free sector count for tracks 36-70 (1 byte/track). The "free sector" entries for tracks 36-70 are likely included here in the first BAM sector due to some memory restrictions in the 1571 drive. There is only enough memory available for one BAM sector, but in order to generate the "blocks free" value at the end of a directory listing, the drive needs to know the extra track "free sector" values. It does make working with the BAM a little more difficult, though. These are the values that would normally be with the 4-byte BAM entry, but the rest of the entry is contained on 53/0. Note: If the DOS version byte is set to anything other than $41 or $00, then we have what is called "soft write protection". Any attempt to write to the disk will return the "DOS Version" error code 73. The 1571 is simply telling you that it thinks the disk format version is incorrect. The BAM entries require some explanation. Take the first entry at bytes $04-$07 ($12 $FF $F9 $17). The first byte ($12) is the number of free sectors on that track. Since we are looking at the track 1 entry, this means it has 18 (decimal) free sectors. The next three bytes represent the bitmap of which sectors are used/free. Since it is 3 bytes (8 bits/byte) we have 24 bits of storage. Remember that at most, each track only has 21 sectors, so there are a few unused bits. These entries must be viewed in binary to make any sense. We will use the first entry (track 1) at bytes 04-07: FF=11111111, F9=11111001, 17=00010111 In order to make any sense from the binary notation, flip the bits around. 111111 11112222 01234567 89012345 67890123 -------------------------- 11111111 10011111 11101000 ^ ^ sector 0 sector 20 Since we are on the first track, we have 21 sectors, and only use up to the bit 20 position. If a bit is on (1), the sector is free. Therefore, track 1 has sectors 9,10 and 19 used, all the rest are free. In order to complete the BAM, we must check 53/0. 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII ----------------------------------------------- ---------------- 00: FF FF 1F FF FF 1F FF FF 1F FF FF 1F FF FF 1F FF ..... 10: FF 1F FF FF 1F FF FF 1F FF FF 1F FF FF 1F FF FF ..... 20: 1F FF FF 1F FF FF 1F FF FF 1F FF FF 1F FF FF 1F ...... 30: FF FF 1F 00 00 00 FF FF 07 FF FF 07 FF FF 07 FF .... 40: FF 07 FF FF 07 FF FF 07 FF FF 03 FF FF 03 FF FF ..... 50: 03 FF FF 03 FF FF 03 FF FF 03 FF FF 01 FF FF 01 ...... 60: FF FF 01 FF FF 01 FF FF 01 00 00 00 00 00 00 00 ... 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Each track from 36-70 has 3 byte entries, starting at address $00. Byte: $00-02: FF FF 1F - BAM map for track 36 03-05: FF FF 1F - BAM map for track 37 ... 33-35: 00 00 00 - BAM map for track 53 ... 66-68: FF FF 01 - BAM map for track 70 69-FF: - Not used You can break down the entries for tracks 36-70 the same way as track 1, just combine the free sector bytes from 18/0 and the BAM usage from 53 to get the full 4-byte entry. Just like a D64, you can attach error bytes to the file, for sector error information. This block is 1366 bytes long, 1 byte for each of the 1366 sectors in the image. With the error bytes, the file size is 351062 bytes. ------------------------------------------------------------------------------- *** REL files The REL filetype requires some extra explaining. It was designed to make access to data *anywhere* on the disk very fast. Take a look at this directory entry... 00: 00 00 84 11 02 41 44 44 49 54 49 4F 4E 41 4C 20 ..ADDITIONAL 10: 49 4E 46 4F A0 11 0C FE 00 00 00 00 00 00 61 01 INFO..a. The third byte ($84) indicates this entry is a REL file and that the three normally empty entries at offset $15, $16 and $17 are now used as they are explained above. It's the track/sector chain that this entry points to, called the SUPER SIDE SECTOR, which is of interest here (in this case, 17/12). The SUPER SIDE SECTOR is very different from the D64 format. If you check the D64 entry for a REL file and do the calculations, you will find that the maximum file size of the REL file is 720 data sectors. With the new SUPER SIDE SECTOR, you can now have 126 groups of these SIDE SECTORS chains, allowing for file sizes up to (theoretically) 90720 sectors, or about 22.15 Megabytes. Here is a dump of the beginning of the SUPER SIDE SECTOR... 00: 11 0B FE 11 0B 0C 13 06 09 00 00 00 00 00 00 00 Bytes:$00-01: Track/sector of first side sector in group 0 02: Always $FE 03-04: Track/sector of first side sector in group 0 (again) ... FD-FE: Track/sector of first side sector in group 125 FF: Unused (likely $00) The side sector layout is the same as the D64. 00: 02 11 00 FE 11 0C 07 13 04 09 00 00 00 00 00 00 10: 11 02 11 0D 11 03 11 0E 11 04 11 0F 11 05 11 10 Bytes: $00: Track location of next side-sector ($00 if last sector) 01: Sector location of next side-sector 02: Side-sector block number (first sector is $00, the next is $01, then $02, etc) 03: REL file RECORD size (from directory entry) 04-0F: Track/sector locations of the six other side-sectors. Note the first entry is this very sector we have listed here. The next is the next t/s listed at the beginning of the sector. All of this information must be correct. If one of these chains is $00/$00, then we have no more side sectors. Also, all of these (up to six) side sectors must have the same values in this range. 10-FF: T/S chains of *each* sector of the data portion. When we get a $00/$00, we are at the end of the file. --------------------------------------------------------------------------- Overall Good/Bad of D71 Files: Good ---- * Supports *all* filenames, even those with 00's in them * Filenames are padded with the standard $A0 character * Supports GEOS files * supports REL files * Allows full directory customization * Because it is a random-access device, it supports fast-loaders and random sector access * Cluster slack-space loss is minimized since the file is a larger fixed size * Has a label (description) field * With the inclusion of error bytes, you have support for basic copy-protection * Files on a disk can easily be re-written, as long as there is free blocks Bad --- * Most emulators don't support D71 yet. * The format doesn't contain *all* the info from the 1571 disk (no sector header info like ID bytes, checksums). This renders some of the original special-loaders and copy-protection useless. * You don't *really* know the file size of the contained C64 files in bytes, only blocks * It can't store C64s FRZ files due to FRZ files needing a special flag that a D71 can't store * It is not an expandable filesize, like LNX or T64 * Unless most of the space on a D71 disk is used, you do end up with lost space * Directory limited to 144 files maximum * Cannot have loadable files with the same names * Has no recognizeable file signature (unlike most other formats). The only reliable way to know if a file is a D71 is by its size * It is too easy for people to muck up the standard layout * It is much more difficult to support fully, as you really need to emulate the 1571 DOS (sector interleave, REL support, GEOS interleave) *** D81 (Electronic form of a physical 1581 disk) *** Document revision 1.1 Like D64 and D71, this is a byte for byte copy of a physical 1581 disk. It consists of 80 tracks, 40 sectors each (0 to 39) for a size of 819200 bytes, or 3200 sectors. If the error byte block is attached, this makes the file size 822400 bytes. There are three sectors on the directory track used for disk internals (header and BAM), leaving 37 sectors for filename entries, thus allowing for 296 files (37 * 8) to be stored at the root level of the disk. The actual physical layout on the disk is quite different from what the user sees, but this is unimportant to the scope of this document. One important difference from the D64 and D71 is all the sector interleaves is now 1 for both files and directory storage (rather than 3 for directory and 10 for file on a D64/D71) . This is due to the built-in buffering in the 1581. When reading a sector, the whole track will be buffered in memory, and any sectors being modified will be done in memory. Once it has to be written, the whole track will be written out in one step. The track range and offsets into the D81 files are as follows: Track #Sect #SectorsIn D81 Offset | Track #Sect #SectorsIn D81 Offset ----- ----- ---------- ---------- | ----- ----- ---------- ---------- 1 40 0 $00000 | 41 40 1600 $64000 2 40 40 $02800 | 42 40 1640 $66800 3 40 80 $05000 | 43 40 1680 $69000 4 40 120 $07800 | 44 40 1720 $6B800 5 40 160 $0A000 | 45 40 1760 $6E000 6 40 200 $0C800 | 46 40 1800 $70800 7 40 240 $0F000 | 47 40 1840 $73000 8 40 280 $11800 | 48 40 1880 $75800 9 40 320 $14000 | 49 40 1920 $78000 10 40 360 $16800 | 50 40 1960 $7A800 11 40 400 $19000 | 51 40 2000 $7D000 12 40 440 $1B800 | 52 40 2040 $7F800 13 40 480 $1E000 | 53 40 2080 $82000 14 40 520 $20800 | 54 40 2120 $84800 15 40 560 $23000 | 55 40 2160 $87000 16 40 600 $25800 | 56 40 2200 $89800 17 40 640 $28000 | 57 40 2240 $8C000 18 40 680 $2A800 | 58 40 2280 $8E800 19 40 720 $2D000 | 59 40 2320 $91000 20 40 760 $2F800 | 60 40 2360 $93800 21 40 800 $32000 | 61 40 2400 $96000 22 40 840 $34800 | 62 40 2440 $98800 23 40 880 $37000 | 63 40 2480 $9B000 24 40 920 $39800 | 64 40 2520 $9D800 25 40 960 $3C000 | 65 40 2560 $A0000 26 40 1000 $3E800 | 66 40 2600 $A2B00 27 40 1040 $41000 | 67 40 2640 $A5000 28 40 1080 $43800 | 68 40 2680 $A7800 29 40 1120 $46000 | 69 40 2720 $AA000 30 40 1160 $48800 | 70 40 2760 $AC800 31 40 1200 $4B000 | 71 40 2800 $AF000 32 40 1240 $4D800 | 72 40 2840 $B1800 33 40 1280 $50000 | 73 40 2880 $B4000 34 40 1320 $52800 | 74 40 2920 $B6800 35 40 1360 $55000 | 75 40 2960 $B9000 36 40 1400 $57800 | 76 40 3000 $BB800 37 40 1440 $5A000 | 77 40 3040 $BE000 38 40 1480 $5C800 | 78 40 3080 $C0800 39 40 1520 $5F000 | 79 40 3120 $C3000 40 40 1560 $61800 | 80 40 3160 $C5800 The header sector is stored at 40/0, and contains the disk name, ID and DOS version bytes, but the BAM is no longer contained here (like the D64). 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII ----------------------------------------------- ---------------- 00: 28 03 44 00 31 35 38 31 20 55 54 49 4C 49 54 59 (.D1581UTILITY 10: 20 56 30 31 A0 A0 47 42 A0 33 44 A0 A0 00 00 00 V01GB3D 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Bytes:$00-01: Track/Sector location of the first directory sector (should be set to 40/3 but it doesn't matter, and don't trust what is there, always go to 40/3 for first directory entry) 02: Disk DOS version type (see note below) $44 ('D')=1581 03: $00 04-13: 16 character Disk Name (padded with $A0) 14-15: $A0 16-17: Disk ID 18: $A0 19: DOS Version ("3") 1A: Disk version ("D") 1B-1C: $A0 1D-FF: Unused (usually $00) The following might be set if the disk is a GEOS format (this info is based on the D64 layout, and might not prove to be true) AB-AC: Border sector (GEOS only, else set to $00) AD-BC: GEOS ID string ("geos FORMAT V1.x" GEOS only, else $00) BD-FF: Unused (usually $00) Note: If the DOS version byte is changed to anything other than a $44 (or $00), then we have what is called "soft write protection". Any attempt to write to the disk will return the "DOS Version" error code 73. The drive is simply telling you that it thinks the disk format version is incompatible. The BAM is located on 40/1 (for side 0, tracks 1-40) and 40/2 (for side 1, tracks 41-80). Each entry takes up six bytes, one for the "free sector" count and five for the allocation bitmap. 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII ----------------------------------------------- ---------------- 00: 28 02 44 BB 47 42 C0 00 00 00 00 00 00 00 00 00 (.DGB 10: 28 FF FF FF FF FF 28 FF FF FF FF FF 28 FF FF FF ((( 20: FF FF 28 FF FF FF FF FF 28 FF FF FF FF FF 28 FF ((( 30: FF FF FF FF 28 FF FF FF FF FF 28 FF FF FF FF FF (( 40: 28 FF FF FF FF FF 28 FF FF FF FF FF 28 FF FF FF ((( 50: FF FF 28 FF FF FF FF FF 28 FF FF FF FF FF 28 FF ((( 60: FF FF FF FF 28 FF FF FF FF FF 28 FF FF FF FF FF (( 70: 28 FF FF FF FF FF 28 FF FF FF FF FF 28 FF FF FF ((( 80: FF FF 28 FF FF FF FF FF 28 FF FF FF FF FF 28 FF ((( 90: FF FF FF FF 28 FF FF FF FF FF 28 FF FF FF FF FF (( A0: 28 FF FF FF FF FF 28 FF FF FF FF FF 28 FF FF FF ((( B0: FF FF 28 FF FF FF FF FF 28 FF FF FF FF FF 28 FF ((( C0: FF FF FF FF 28 FF FF FF FF FF 28 FF FF FF FF FF (( D0: 28 FF FF FF FF FF 28 FF FF FF FF FF 28 FF FF FF ((( E0: FF FF 28 FF FF FF FF FF 28 FF FF FF FF FF 28 FF ((( F0: FF FF FF FF 28 FF FF FF FF FF 24 F0 FF 2D FF FE ($- Bytes:$00-01: Track/sector of next bam sector (40/2) 02: Version # ('D') 03: One's complement of version# ($BB) 04-05: Disk ID bytes (same as 40/0 Disk ID) 06: I/O byte bit 7 set - Verify on bit 7 clear - Verify off bit 6 set - Check header CRC bit 6 clear - Don't check header CRC 07: Auto-boot-loader flag (see section at end of document) 08-0F: Reserved for future (set to $00) 10-15: BAM entry for track 1 (track 41, side 1) 16-1B: BAM entry for track 2 (track 42, side 1) ... 46-4B: BAM entry for track 10 (track 50, side 1) ... 82-87: BAM entry for track 20 (track 60, side 1) ... BE-C3: BAM entry for track 30 (track 70, side 1) ... FA-FF: BAM entry for track 40 (track 80, side 1) The BAM entries require some explanation, so lets look at the track 40 entry at bytes $FA-FF ($24 $F0 $FF $2D $FF $FE). The first byte ($24, or 36 decimal) is the number of free sectors on that track. The next five bytes represent the bitmap of which sectors are used/free. Since it is five bytes (8 bits/byte) we have 40 bits of storage. Since this format has 40 sectors/track, the whole five bytes are used. F0: .. .. .. .. .. .. .. .. .. .. 24 F0 FF 2D FF FE ($- The last five bytes of any BAM entry must be viewed in binary to make any sense. We will once again use track 40 as our reference: F0=11110000, FF=11111111, 2D=00101101, FF=11111111, FE=11111110 In order to make any sense from the binary notation, flip the bits around. 111111 11112222 22222233 33333333 Sector 01234567 89012345 67890123 45678901 23456789 -------------------------- -------- -------- 00001111 11111111 10110100 11111111 01111111 Note that if a bit is on (1), the sector is free. Therefore, track 40 has sectors 0-3, 17, 20, 22, 23 and 32 used, all the rest are free. The second BAM (for side 1) contains the entries for tracks 41-80. 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII ----------------------------------------------- ---------------- 00: 00 FF 44 BB 47 42 C0 00 00 00 00 00 00 00 00 00 (.DGB 10: 28 FF FF FF FF FF 28 FF FF FF FF FF 28 FF FF FF ((( 20: FF FF 28 FF FF FF FF FF 28 FF FF FF FF FF 28 FF ((( 30: FF FF FF FF 28 FF FF FF FF FF 28 FF FF FF FF FF (( 40: 28 FF FF FF FF FF 28 FF FF FF FF FF 28 FF FF FF ((( 50: FF FF 28 FF FF FF FF FF 28 FF FF FF FF FF 28 FF ((( 60: FF FF FF FF 28 FF FF FF FF FF 28 FF FF FF FF FF (( 70: 28 FF FF FF FF FF 28 FF FF FF FF FF 28 FF FF FF ((( 80: FF FF 28 FF FF FF FF FF 28 FF FF FF FF FF 28 FF ((( 90: FF FF FF FF 28 FF FF FF FF FF 28 FF FF FF FF FF (( A0: 28 FF FF FF FF FF 28 FF FF FF FF FF 28 FF FF FF ((( B0: FF FF 28 FF FF FF FF FF 28 FF FF FF FF FF 28 FF ((( C0: FF FF FF FF 28 FF FF FF FF FF 28 FF FF FF FF FF (( D0: 28 FF FF FF FF FF 28 FF FF FF FF FF 28 FF FF FF ((( E0: FF FF 28 FF FF FF FF FF 28 FF FF FF FF FF 28 FF ((( F0: FF FF FF FF 28 FF FF FF FF FF 28 FF FF FF FF FF (( It is laid out exactly as the side 0 BAM except for one difference. The track/sector reference for the next sector should be set to $00/$FF, indicating there is no next sector. The directory track should be contained totally on track 40. Sectors 3-39 contain the entries and sector 1 and 2 contain the BAM (Block Availability Map). Sector 0 holds the disk name and ID. The first directory sector is always 40/3, even though the t/s pointer at 40/0 (first two bytes) might point somewhere else. It goes linearly up the sector count, 3-4-5-6-etc. Each sector holds up to eight entries. The first two bytes of the sector ($28/$04) indicate the location of the next track/sector of the directory (40/4). If the track is set to $00, then it is the last sector of the directory. It is possible, however unlikely, that the directory may *not* be competely on track 40. Just follow the chain anyhow. When the directory is done (track=$00), the sector should contain an $FF, meaning the whole sector is allocated. Theactual value doesn't matter as all the entries will be returned anyways. Each directory sector has the following layout: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII ----------------------------------------------- ---------------- 00: 28 04 81 2B 00 53 43 52 45 45 4E 20 20 33 A0 A0 (.+SCREEN3 10: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 02 00 . 20: 00 00 81 2B 01 53 43 52 45 45 4E 20 20 34 A0 A0 +.SCREEN4 30: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 03 00 . 40: 00 00 81 2B 02 53 43 52 45 45 4E 20 20 35 A0 A0 +.SCREEN5 50: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 07 00 . 60: 00 00 81 2B 08 53 43 52 45 45 4E 20 20 36 A0 A0 +.SCREEN6 70: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 08 00 . 80: 00 00 81 2B 14 53 43 52 45 45 4E 20 20 37 A0 A0 +.SCREEN7 90: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 07 00 . A0: 00 00 81 24 00 53 43 52 45 45 4E 20 20 38 A0 A0 $SCREEN8 B0: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 0B 00 . C0: 00 00 82 24 04 46 49 4C 45 34 32 39 33 36 39 30 $.FILE4293690 D0: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 07 00 . E0: 00 00 82 24 06 46 49 4C 45 32 35 37 38 38 31 35 $.FILE2578815 F0: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 05 00 . Bytes: $00-1F: First directory entry 00-01: Track/Sector location of next directory sector 02: File type. Bit 0-3: The actual filetype 000 (0) - DEL 001 (1) - SEQ 010 (2) - PRG 011 (3) - USR 100 (4) - REL 101 (5) - CBM (partition or sub-directory) Values 6-15 are illegal, but if used will produce very strange results. Bit 4: Not used Bit 5: Used only during SAVE-@ replacement Bit 6: Locked flag (Set produces ">" locked files) Bit 7: Closed flag (Not set produces "*", or "splat" files) Typical values for this location are: $00 - Scratched (deleted file entry) 80 - DEL 81 - SEQ 82 - PRG 83 - USR 84 - REL 85 - CBM 03-04: Track/sector location of first sector of file or partition 05-14: 16 character filename (in PETASCII, padded with $A0) 15-16: Track/Sector location of first SUPER SIDE SECTOR block (REL file only) 17: REL file record length (REL file only) 18-1D: Unused (except with GEOS disks) 1C-1D: (Used during an @SAVE or @OPEN, holds the new t/s link) 1E-1F: File or partition size in sectors, low/high byte order ($1E+$1F*256). The approx. file size in bytes is <= #sectors * 254 20-3F: Second dir entry. From now on the first two bytes of each entry in this sector should be $00/$00, as they are unused. 40-5F: Third dir entry 60-7F: Fourth dir entry 80-9F: Fifth dir entry A0-BF: Sixth dir entry C0-DF: Seventh dir entry E0-FF: Eighth dir entry --------------------------------------------------------------------------- *** REL files The REL filetype requires some extra explaining. It was designed to make access to data *anywhere* on the disk very fast. Take a look at this directory entry... 00: 00 FF 84 27 00 41 44 44 49 54 49 4F 4E 41 4C 20 'ADDITIONAL 10: 49 4E 46 4F A0 27 02 FE 00 00 00 00 00 00 D2 0B INFO'.... The third byte ($84) indicates this entry is a REL file and that the three normally empty entries at offset $15, $16 and $17 are now used as they are explained above. It's the track/sector chain that this entry points to, called the SUPER SIDE SECTOR, which is of interest here (in this case, 39/2). The SUPER SIDE SECTOR is very different from the D64 format. If you check the D64 entry for a REL file and do the calculations, you will find that the maximum file size of the REL file is 720 data sectors. With the new SUPER SIDE SECTOR, you can now have 126 groups of these SIDE SECTORS chains, allowing for file sizes up to (theoretically) 90720 sectors, or about 22.15 Megabytes. Here is a dump of the beginning of the SUPER SIDE SECTOR... 00: 27 01 FE 27 01 15 09 03 0F 38 16 4A 1C 00 00 00 '.'.....8.J. 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Bytes:$00-01: Track/sector of first side sector in group 0 02: Always $FE 03-04: Track/sector of first side sector in group 0 (again) ... FD-FE: Track/sector of first side sector in group 125 FF: Unused (likely $00) The side sector layout is the same as the D64/1571. 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ----------------------------------------------- 00: 12 0A 00 FE 15 09 12 0A 0F 0B 0C 0C 09 0D 06 0E 10: 15 07 15 08 15 0A 15 0B 15 0C 15 0D 15 0E 15 0F 20: 15 10 15 11 15 12 15 13 15 14 15 15 15 16 15 17 30: 15 18 15 19 15 1A 15 1B 15 1C 15 1D 15 1E 15 1F 40: 15 20 15 21 15 22 15 23 15 24 15 25 15 26 15 27 50: 14 00 14 01 14 02 14 03 14 04 14 05 14 06 14 07 60: 14 08 14 09 14 0A 14 0B 14 0C 14 0D 14 0E 14 0F 70: 14 10 14 11 14 12 14 13 14 14 14 15 14 16 14 17 80: 14 18 14 19 14 1A 14 1B 14 1C 14 1D 14 1E 14 1F 90: 14 20 14 21 14 22 14 23 14 24 14 25 14 26 14 27 A0: 13 00 13 01 13 02 13 03 13 04 13 05 13 06 13 07 B0: 13 08 13 09 13 0A 13 0B 13 0C 13 0D 13 0E 13 0F C0: 13 10 13 11 13 12 13 13 13 14 13 15 13 16 13 17 D0: 13 18 13 19 13 1A 13 1B 13 1C 13 1D 13 1E 13 1F E0: 13 20 13 21 13 22 13 23 13 24 13 25 13 26 13 27 F0: 12 00 12 01 12 02 12 03 12 04 12 05 12 06 12 07 Bytes: $00: Track location of next side-sector ($00 if last sector) 01: Sector location of next side-sector 02: Side-sector block number (first sector is $00, the next is $01, then $02, etc) 03: REL file RECORD size (from directory entry) 04-0F: Track/sector locations of the six other side-sectors. Note the first entry is this very sector we have listed here. The next is the next t/s listed at the beginning of the sector. All of this information must be correct. If one of these chains is $00/$00, then we have no more side sectors. Also, all of these (up to six) side sectors must have the same values in this range. 10-FF: T/S chains of *each* sector of the data portion. When we get a $00/$00, we are at the end of the file. --------------------------------------------------------------------------- *** 1581 Partitions and Sub-directories At the beginning of this document it was stated that the 1581 can hold 296 entries "at the root level". The 1581 also has the ability to partition areas of the disk. Under the right conditions these can become sub-directories, acting as a small diskette, complete with its own directory and BAM. When you are inside of a sub-directory, no other files except those in that directory are visible, or can be affected. To the 1581, this file will show up as a "CBM" filetype in a directory. All this does is tell the disk that a file, starting at X/Y track/sector and Z sectors large exists. Doing a validate will not harm these files as they have a directory entry, and are fully allocated in the BAM. There are two main uses for partitions. One is to simply allocate a section of the disk to be used for direct-access reads/writes, and lock it away from being overwritten after a VALIDATE. The second is as a sub-directory, basically a small "disk within a disk". In order to use a partition as a sub-directory, it must adhere to the following four rules: 1. If must start on sector 0 2. It's size must be in multiples of 40 sectors 3. It must be a minimum of 120 sectors long (3 tracks) 4. If must not start on or cross track 40, which limits the biggest directory to 1600 sectors (tracks 1-39). This is a dump of a sub-directory entry: 00: 00 FF 85 29 00 50 41 52 54 49 54 49 4F 4E 20 31 )PARTITION1 10: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 40 06 @. It is a partition starting on track 41/0, extends for 1600 sectors, and has been formatted as a sub-directory. Note that when a partition is created, the area being allocated is not touched in any way. If you want it set up as a sub-directory, you must issue the FORMAT command to the 1581 to create the central directory and BAM. Also note that from the directory entry you can't tell whether it is a sub-directory or not, just that it fits the sub-directory parameters. The BAM track for the sub-directory exists on the first track of the partition, and has the same layout as the disk BAM on track 40. The biggest difference is the "disk name" is what what given when the partition was formatted rather than what the actual disk name is. Also, except for the free sectors in the partition area, all other sectors in the BAM will be allocated. If the partition size doesn't match the above rules for a sub-directory, it will simply exist as a "protected" area of the disk, and can't be used a sub-directory. Either way, it still shows up as a "CBM" type in a directory listing. Below is a dump of a 10-sector partition starting on track 5/1, which does not qualify as a sub-directory... 00: 00 00 85 05 01 53 4D 41 4C 4C 50 41 52 54 20 32 ..SMALLPART2 10: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 0A 00 The master BAM shows the entry for this partition on track 5... 00: 28 02 44 BB 43 44 C0 00 00 00 00 00 00 00 00 00 (.DCD 10: 23 C1 FF FF FF FF 28 FF FF FF FF FF 28 FF FF FF #(( 20: FF FF 28 FF FF FF FF FF 1E 01 F8 FF FF FF 28 FF (..( ^^^^^^^^^^^^^^^^^ The breakdown of the BAM shows the allocation for this track, with sectors 1-10 allocated, as it should be. 10000000 00011111 11111111 11111111 11111111 ^ ^ ^ ^ ^ 0 10 20 30 39 Partitions and sub-directories share one very important trait. When created, the sub-directory entry simply has the starting track/sector and the size of the partition in sectors. Partitions are created linearly, meaning if one starts on 30/1 and is of size 15 sectors, then the sector range from 1 through 15 on track 30 will be allocated. If a partition size crosses a track boundary, the allocation will continue on the next track starting on sector 0, and going up. The section allocated will *not* have a track/sector chain like a file would, but rather is dependant on the directory entry to keep it from being overwritten. You can store whatever you want to in the allocated area. --------------------------------------------------------------------------- *** AUTO-BOOT LOADER If byte $07 in the BAM is set, then when the drive is reset (and other circumstances) it will look for a USR file called "COPYRIGHT CBM 86". This file will then be loaded into the drive RAM and executed. The format for this auto-loader file is fairly basic. It starts with a two-byte load address, a size byte, program data, and a checksum at the end. Bytes: 00-01: Load address, low/high format 02: Size of program (SZ) (smaller than 256 bytes) 03-(03+SZ-1): Program data 03+SZ: Checksum byte --------------------------------------------------------------------------- Overall Good/Bad of D81 Files: Good ---- * Supports *all* filenames, even those with $00's in them * Filenames padded with the standard $A0 character * Supports GEOS files * Supports REL files * Allows directory customization * Because it is a random-access device, it supports fast-loaders and random sector access * Cluster slack-space loss is minimized since the file is a larger fixed size * Has a label (description) field * With the inclusion of error bytes, you have support for basic copy-protection * Files on a disk can easily be re-written, as long as there is free blocks Bad --- * Most emulators don't support D81's yet * The format doesn't contain *all* the info from the 1581 disk (no sector header info like ID bytes, checksums). This renders some of the original special-loaders and copy-protection useless. * You don't *really* know the file size of the contained C64 files in bytes, only blocks * It can't store C64s FRZ files (due to FRZ files needing a special flag that a D81 can't store) * Directory limited to 296 files maximum * It is not an expandable filesize, like LNX or T64, but the directory is large enough not to worry about this limitation * Unless most of the space on a D81 disk is used, you do end up with lost space * Cannot have loadable files with the same names * Has no recognizeable file signature (unlike most other formats). The only reliable way to know if a file is a D81 is by its size * It is too easy for people to muck up the standard layout * It is much more difficult to support fully, as you really need to emulate the 1581 DOS (sector interleave, REL support, GEOS interleave) *** F64 (a companion file to certain D64's) *** Document revision 1.1 Created by a program called FCOPY, written by M. Edzes in the early 1990's, these files contain some extra information about the associated D64 files like the low-level disk ID, sector checksum, valid sector flag and header ID. Some of what you are about to read is pure conjecture on the part of the author to explain what these files are. These files appear to be very rare, but are available from a CD called "C64 CD 96", also known as the "Unicorn" CD. They all appear to be the same size, 2051 bytes, and seem to start with the DISK ID from the D64 image. 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII ----------------------------------------------- ---------------- 0000: 30 34 .. .. .. .. .. .. .. .. .. .. .. .. .. .. 04.............. Here the DISK ID is "04", and is likely obtained from the sector header ID for track 18/0 (not the one visible on the BAM sector). Once we take into account the first two bytes, this leaves the remaining 2049 bytes. Dividing this number by 683 (the number of sectors in a standard 35 track D64 image) leaves us a grouping of 3 bytes per sector. Below is a dump of the first few bytes of the F64 files, and we will examine a few of the 3-byte descriptions. 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII ----------------------------------------------- ---------------- 0000: .. .. 2D 07 01 2B 07 8D 2B 07 47 2B 07 AE 2B 07 ..-++G++ 0010: 80 2B 07 C3 2B 07 1C 2B 07 4E 2B 07 EC 2B 07 47 +++N++G 0020: 2B 07 FE 2B 07 5F 2B 07 69 2B 07 F3 2B 07 90 2B ++_+i+++ 0030: 07 22 2B 07 4D 2D 07 01 2D 07 01 2D 07 01 2D 07 "+M---- The first sector has a description of "2D 07 01". Byte: 00 - "2D". This byte likely represents whether the sector data was read or not. This value can be either "2D" (a "-" character, meaning data not valid) or "2B" (a "+" character, meaning data valid). 01 - "07". This is the "data descriptor byte" meaning the sector is OK, and exists. If it was a value other than 07, we have an error 22 ("data block not found"). 02 - "01". This is the checksum for the sector. It is arrived at by XOR'ing all the bytes contained in the sector, from position 00 to position FF. The second sector has a description of "2B 07 8D". From the above layout, this means the sector data is ok, the data header is ok ("07"), and has a checksum of "8D" (calculated and verified from the D64). *** GEOS VLIR (Variable Length Index Record) *** Document revision 1.1 Later on in the life of the C64, an OS called GEOS came out. It was a system much like the many windowing OS's (MAC OS, Windows) in that it used icons, windows, a mouse pointer and resource drivers. In order to contain all the information needed for the windowing system (icon, window position, creation time/date), a new filetype called VLIR was needed. While GEOS files might not be of interest to many of the emulator users, it is likely that these files will be encountered, and knowledge of them would be helpful. Each GEOS file or application is comprised of many separate chains (called RECORDS) for different sections of the app/file. Each RECORD can be loaded in separately and overtop of other ones. Below is a dump of the first directory sector of the GEOS 2.0 disk. Note the first entry seems normal enough, but the rest have additional information in the normally unused section of the entry. 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ----------------------------------------------- 00: 12 04 82 13 00 47 45 4F 53 20 56 32 2E 30 20 45 <- Normal entry 10: 4E 47 4C 2E A0 00 00 00 00 00 00 00 00 00 58 00 20: 00 00 83 02 02 44 45 53 4B 20 54 4F 50 A0 A0 A0 <- First GEOS file. 30: A0 A0 A0 A0 A0 02 0F 01 04 58 08 13 0D 23 78 00 <- Note extra info 40: 00 00 83 0B 13 43 4F 4D 4D 20 31 33 35 31 28 61 from offset $15 to 50: 29 A0 A0 A0 A0 08 0F 00 0A 58 05 09 15 24 03 00 $1D. 60: 00 00 83 0F 0D 4D 50 53 2D 38 30 31 A0 A0 A0 A0 70: A0 A0 A0 A0 A0 0F 05 00 09 56 07 19 01 00 04 00 80: 00 00 83 08 0D 43 4F 4E 46 49 47 55 52 45 A0 A0 90: A0 A0 A0 A0 A0 08 05 01 0E 58 05 1F 0B 31 4E 00 A0: 00 00 83 01 10 50 41 49 4E 54 20 44 52 49 56 45 B0: 52 53 A0 A0 A0 01 08 00 06 57 08 0C 0E 00 12 00 C0: 00 00 83 0B 05 70 72 65 66 65 72 65 6E 63 65 20 D0: 6D 67 72 A0 A0 0B 12 00 05 56 0A 09 13 2D 16 00 E0: 00 00 83 08 11 70 61 64 20 63 6F 6C 6F 72 20 6D F0: 67 72 A0 A0 A0 08 07 00 05 58 05 19 0C 10 16 00 Lets analyze the second entry to see whats all involved with GEOS files. Note, the offset values have been changed to 0 to make referencing easier. 00: 00 00 83 02 02 44 45 53 4B 20 54 4F 50 A0 A0 A0 10: A0 A0 A0 A0 A0 02 0F 01 04 58 08 13 0D 23 78 00 Byte: $02: C64 filetype (see the section on D64 for an explanation) REL files are not allowed. 03-04: Starting track/sector (02/02 from above) of C64 file if GEOS filetype is $00. If GEOS filetype is non-zero, track/sector of single-sector RECORD block 05-14: Filename (in ASCII, padded with $A0, case varies) 15-16: Track/sector location of info block 17: GEOS file structure $00 - Sequential 01 - VLIR file 18: GEOS filetype $00 - Non-GEOS (normal C64 file) 01 - BASIC 02 - Assembler 03 - Data file 04 - System File 05 - Desk Accessory 06 - Application 07 - Application Data (user-created documents) 08 - Font File 09 - Printer Driver 0A - Input Driver 0B - Disk Driver (or Disk Device) 0C - System Boot File 0D - Temporary 0E - Auto-Execute File 0F-FF - Undefined 19: Year (19xx) 1A: Month (1-12) 1B: Day (1-31) 1C: Hour (0-23, military time) 1D: Minute (0-59) 1E-1F: Filesize, in sectors (low/high byte order) If the values at byte $18 is 00 then we have a normal, sequential, C64 file, without an info block. If the value at byte $18 is anything other than 00, we have a GEOS file, be it VLIR or sequential, with an info block. The info block stores items like the ICON, size, load address, file types, description, etc, and is always only 1 sector long. Since there is a fixed space to store information, the ICON height, width and bitmap length must be the same. Here is a sample info block, and layout... 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ----------------------------------------------- 00: 00 FF 03 15 BF FF FF FF 92 49 01 FF FF 01 80 00 10: 1D BF FF DD A0 00 5D BF FF C1 A0 00 5D A1 C6 55 20: A0 29 5D A0 C9 41 A1 09 41 B9 D6 41 A8 00 41 BF 30: FF C1 80 00 1D 9C 00 15 9C 00 15 80 00 1D 80 00 40: 01 FF FF FF 83 04 01 56 19 55 19 75 51 64 65 73 50: 6B 54 6F 70 20 41 4D 20 20 56 32 2E 30 00 00 00 60: 00 50 65 74 65 72 20 53 63 68 65 70 65 72 73 00 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80: 00 00 00 00 00 00 00 00 00 4C 2A 5B 4C 59 5D 4C 90: A7 61 4C 3A 62 AD 8A 84 D0 01 60 20 7E 23 20 9C A0: 55 73 65 20 74 68 65 20 64 65 73 6B 54 6F 70 20 B0: 74 6F 20 6D 61 6E 61 67 65 20 61 6E 64 20 6D 61 C0: 6E 69 70 75 6C 61 74 65 20 79 6F 75 72 20 66 69 D0: 6C 65 73 2E 00 03 20 E3 5C 68 85 FB 20 4F 61 20 E0: 13 61 20 32 61 20 F2 5C A9 0C 20 CC 49 A9 2E 85 F0: 13 A9 F9 85 12 A9 2F 85 15 A9 01 85 14 A9 84 85 Byte: $00-01: Contains $00/$FF since its only 1 sector long 02-04: Information sector ID bytes (03 15 BF). The "03" is likely the bitmap width, and the "15" is likely the bitmap height, but rare exceptions do exist to this! 05-43: Icon bitmap (sprite format, 63 bytes) 44: C64 filetype (same as that from the directory entry) 45: GEOS filetype (same as that from the directory entry) 46: GEOS file structure (same as that from the dir entry) 47-48: Program load address 49-4A: Program end address (only with accessories) 4B-4C: Program start address 4D-60: Class text (terminated with a $00) 61-74: Author (with application data: name of application disk, terminated with a $00. This string may not necessarily be set, or it may contain invalid data) The following GEOS files have authors: 1 - BASIC 2 - Assembler 5 - Desk Accessory 6 - Application 9 - Printer Driver 10 - Input Driver 75-88: If a document, the name of the application that created it. 89-9F: Available for applications, unreserved. A0-FF: Description (terminated with a $00) Note: all the text strings above are in ASCII, not PETASCII. If the file is a VLIR, then the RECORD block is of interest. This single sector is made up of up to 127 track/sector pointers, each of which point to program sections (called RECORDS). VLIR files are comprised of loadable RECORDS (overlays, if you wish to use PC terminology). The first RECORD is what is always loaded first when you run that application. After that, the OS loads whatever RECORD it needs. Here is a partial sample of the RECORD sector... 00: 00 FF 08 00 09 04 09 03 0A 0A 0B 11 0F 11 00 00 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Byte: $00-01: Contains 00/FF since its only 1 sector long 02-03: Starting track/sector (8,0) for the first RECORD 04-05: Starting track/sector (9,4) for the second RECORD 06-07: Starting track/sector (9,3) for the third RECORD 08-09: fourth RECORD (10/10) 0A-0B: fifth RECORD (11/17) 0C-0D: sixth RECORD (15/17) 0E-0F: seventh RECORD (0/0) When a T/S link of $00/$00 is encountered, we are at the end of the RECORD block. If the T/S link is a $00/$FF, then the record is not available. Note that if you add up the sectors so far, we have only used two, one for the INFO sector and one for the RECORD sector. Obviously there are more used, and they are contained in the sector chains from the RECORD sector. Each t/s link in the RECORD sector points to a chain of sectors, the length of which is included in the sector count for the GEOS file. Doing a VALIDATE on a GEOS disk when not in GEOS would de-allocate all these sector chains (and the RECORD sector as well), which would not be good! There are also changes to the BAM sector from a normal D64 file. Looking at the D64 entry from before, we have all the normal information, plus the new information starting at $AB: Bytes:$00-01: Track/Sector location of the first directory sector (should be 18,1, but it doesn't seem to matter) 02: Disk DOS version type $41=1541 03: $2A, DOS version. 04-8F: BAM entries for each track, in groups of four bytes per track, starting on track 1 90-9F: Disk Name (padded with $A0) A0-A1: Filled with $A0 A2-A3: Disk ID A4: Usually $A0 A5-A6: DOS type, usually "2A" A7-AA: Filled with $A0 AB-AC: Border sector trk/ssec (*see below) AD-BC: GEOS ID string ("GEOS format V1.0", in ASCII) BD-DC: Unused (usually $00) DD-FF: Free sector info for tracks 36-70, used on double-sided 1571 disks only! If you want to check to see if a disk is formatted for GEOS, check the string in the BAM sector starting at $AD (offset 173) for the string "GEOS format". If it does not match, the disk is not in GEOS format. This is the way that GEOS itself verifies if a disk is GEOS formatted. Note: GEOS disks contain something called a "border sector" which is also only one sector long, has the same layout as a normal directory sector, and is used for copying files from one disk to another. When you need to copy a file, you drag the icon to the bottom of the screen and the file is moved from its normal location in the directory to the border sector. Since it is only 1 sector, it can hold only 8 entries. On a D64/1541, here is how GEOS allocates blocks as it either saves files or needs blocks for other purposes: Saving files: When there's still at least one free block in the current track, then the next block is searched for starting at the sector which is away from the current one by at least the soft interleave. The exceptions are track 25 and above where the interleave changes to the original interleave _minus one_. When stepping to the next track, the sector where the next block of the files is saved to is computed as following: New sector = (Next track - Previous Track) * 2 + 4 + Soft interleave Getting the Border Sector: When allocating the GEOS border sector, the search starts upwards from sector 19/0 for a free sector and then from sector 1/0 if no free one has been found yet. Getting the first sector for saving a file: Start searching from sector 1/0 and, on the first track that has at least one free sector, you start searching at the sector computed by the form above. Seeing as this is not an emulator format, I will not comment on its relative merits. It is simply another C64 file type. *** Introduction to the various Emulator Formats Compiled by: Peter Schepers Started: August 24, 1996 Last updated: June 8, 1998 --------------------------------------------------------------------------- There are always questions asked regarding the various formats which are commonly used on either the emulators or the real C64. Most often the question involves conversion... "What do I do with LNX files?" or "How do I make these files work on the C64s emulator?". This document is an attempt to explain their internal structure, what to do with them, and some of their respective strengths and weaknesses. Some of what is contained in this document has been compiled from various sources, and I have given the appropriate attributions in the CONCLUDE.TXT file. Some of the information may not be accurate as it may have been taken from other documents, and I have no first-hand experience with it. I will try to make it as thorough as possible, but if there is something wrong, please alert me so I can make the appropriate changes for future releases. So far, this document covers the following emulator types: * D64 (1541 disk representation, with a description of RELATIVE files, and some D64 variants) * X64 (for the X64/Vice emulator) * T64 (Tape images for the C64s emulator) * T64 .FRZ (FRoZen Files, saved emulator sessions) * PC64 (P/S/U/Rxx) * PC64 .C64 (saved emulator sessions) * D71 (1571 disk representation) * D81 (1581 disk representation) * F64 (not an image file, but a companion file to D64's) * N64 (64NET's custom files) * L64 (64LAN's custom files) * C64 (PCLINK's custom files) * CRT (CCS64 ROM cartridge files) * 64x (PC64 ROM files) ...as well as the following native C64 types, some of which are also supported on the various emulators: * 4-file diskpacked ZipCode (or .Z64, 4 or 5 files, #!xxxxx) * 6-file SixPack ZipCode (or .Z64, #!!xxxx) * Filepacked ZipCode (or .Z64, x files, x!xxxxx) * LNX (LyNX) * ARK & SRK (ARKive & compressed ARKive) * LHA & LZH (header description only) * SFX (SelF-eXtracting LHA/LZH) * SDA (Self-Dissolving Archive) * ARC (ARChive) * ZIP (PKZIP) * CKIT (Compression KIT) * CPK * WRA (Wraptor) * LBR (LiBRary, C64 only, not the C128 CP/M .LBR files) * GEOS VLIR (Variable Length Index Record) * CVT (GEOS ConVerT files) * SPY (SPYne) * Binary Also included is a very basic look at some C64 bitmap formats (in BITMAP.TXT), and the saved session layout of the Macintosh-based C64 emulator "Power64" (in POWER64.TXT). Thanks to Peter Weighill for the above info. At the end of the CONCLUDE.TXT document is a BINARY/HEX/Decimal conversion chart, useful when you don't know how to convert the number bases around. It might come in handy when working with and understanding the GCR conversion that the SixPack ZipCode format uses. Right now there are several good utilities available to work with most of the mentioned formats. The first is 64COPY, my own conversion program. The second is Star Commander, by Joe Forster/STA. Included with his program are many smaller utilities such as Star ARK, Star LHA and Star ZIP, which will convert specific formats to D64 images. Peter Schepers, University of Waterloo. Email: schepers@ist.uwaterloo.ca --------------------------------------------------------------------------- Most recent changes: Mar 24/98 - Improved the Sixpack ZipCode topic (ZIPCODE2.TXT) - Added explanation of the .F64 companion file to some D64's - Other small corrections Apr 1/98 - Added SPYne layout. - More small changes. Apr 22/98 - Added 64NET "N64" files - Added 64LAN "L64" files - Updated PKZIP "ZIP" topic - Updated WRA topic - Many corrections/improvements (thanks to Joe Forster/STA!) - Update D64 topic with better explanation about disk errors - Updated D81 with AUTO-BOOT file layout - Renamed all the ZIPCODE files to make more sense... ZIPCODE1 -> ZIP_DISK ZIPCODE2 -> ZIP_SIX ZIPCODE3 -> ZIP_FILE June 2/98 - Added new section to D64, D71, D81, PC64, LNX, T64 and BINARY dealing with the good/bad aspects of the layout - Updated F64 topic - Updated GEOS topic June 8/98 - Added CCS64 ROM cartridge file (CRT) - Added a "document revision" number to each TXT file. This way, version history can be tracked, and you will always know if you have the latest revision. - Added description of PC64 ROM files (64x) --------------------------------------------------------------------------- *** Terms and acronyms Many strange terms have come along with computers in general, and I will not attempt to explain them all, but some of the ones in this document may not be entirely clear. I will attempt to make things a little easier by explaining some of the more common ones. - Short form for a Carriage Return ($0D) symbol. - Short form for a Line Feed ($0A) symbol. ASCII - This is an acronym for "American Standard Code for Information Interchange". The standard is a 7-bit code covering control codes, punctuation, alphanumeric (A to Z, 0 to 9) as well as math and a few other symbols. Since it is a 7-bit code, it ranges from $00 to $7F (0-127). This leaves the top 128-255 definable by the vendor. The PC world has corrupted this standard making it 8-bit. BAM - An acronym for "Block Availability Map". Here is where the disk operating system keeps track of what sectors are allocated (or available) for each track. BLOCK - This refers to sectors which on a logical level are grouped together. On a 1541 disk, it could be a series of sectors linked together in a file, or a partition on a 1581 disk. In the PC world it represents a "cluster" of sectors. Generally if I'm referring to a grouping of sectors thats *not* 256 bytes large, then I talk in blocks. BYTE - A group of 8 bits, the contents of 1 memory location. CHAIN - A series of sectors linked together. One sector will have a pointer to another, and that sector will point to another, until the chain has no more forward pointers. A file stored on a 1541 disk would be considered a chain of sectors, but it also has a directory entry explaining what the chain is for. FILETYPE - In the Commodore world, this would be the kind of file, be it SEQ, REL, PRG, USR, GEOS etc. In the DOS world, this would possibly be the file extension, be it EXE, TXT, DOC. It tells the user what file it is, making usage easier. GCR - An acronym for "Group Code Recording". This is the encoding method Commodore uses to physically store the information on the disks (i.e. 1541). It encodes an 8 bit sequence into a 10 bit sequence so that long repeated sequences of 1's or 0's are avoided. These must be avoided so that the timing of reading/writing to the disk won't become "out of sync". As a user, you would not normally see the GCR information since the drive does all the conversion to normal HEX data before it gives it to you. HIGH/LOW - The bytes here are stored backwards compared to the LOW/HIGH method. See LOW/HIGH for more information. LINK - This is the track/sector values, stored in the first two bytes of a sector, which point to (or "link" to) the t/s location of the next sector. A series of these links comprise a "chain" of sectors. LOW/HIGH - This is how values are stored when they exceed one byte. A good example of this is the sector count of a D64 file. To calculate the actual value, take the second value, multiply it by 256 and add the low value. You will now get the real decimal value. i.e. (HIGH*256)+LOW=result. If you look at is as a HEX value, swap the bytes around and put them together for the 16-bit HEX value. i.e. $FE $03 would be $03FE as a 16-bit HEX value. LSU - This is my own acronym meaning "last sector useage". It is the value stored in byte position $01 (the "sector" value of the t/s link) of the last sector of a file. This value is the offset into the sector where the last byte is stored. It also represents the byte count + 1, since a value of 255 would actually mean only 254 bytes of file data exists (full sector less the 2 bytes for t/s chain). Without reasonable knowledge of the disk layout, this byte can be confusing, and hard to explain. NYBBLE - A grouping of 4 bits (half a byte), either the first or last 4 bits of an 8-bit binary number, or one half of a two-digit hexadecimal number. Typically, a byte will be broken down into two parts, the top 4 bits and the bottom 4 bits. These are referred to as the upper and lower nybble respectively, and are represented by two hexadecimal digits in base 16. PETASCII - (or PETSCII) This is Commodore's version of ASCII (the PET part of the name comes from the first computer to use the code, the PET or Personal Electronic Transactor). Most of the codes from 0-127 are the same as ASCII, but there are differences, especially noticible when converting text from a C64 to a DOS machine. Where ASCII has uppercase characters, PETASCII has lower case ones, and vice versa. Also, the top 128 characters (128 to 255) are quite different from the PC "standard". RLE - An acronym for "Run Length Encoding". This is a simple compression method, employed by most compression programs, and also used by some archive formats (ZipCode, CPK). It encodes sequences (or "runs", hence the name "RUN length...") of the same byte (i.e. 00 00 00 00 00 00) into a smaller string using a shorter code sequence, making the resultant file smaller than the original. This is the simplest form of file compression. SECTOR - It is best described as the method that the drive uses to store the smallest group of bytes physically on the disk. On the 1541 this refers to a group of 256 bytes stored together in a single sector. On a PC disk, this is typically 512 bytes. SIGNATURE - A group of bytes, usually near or at the front of the file, which are used to identify the type of file. i.e. a PC64 file will always have the signature string "C64file" contained at the beginning of the file. TAR - An acronym for "Tape ARchiver", a UNIX application, and method of backing up information. *** LBR (LiBRary, C64 version only) *** Document revision 1.1 There are two different types of LBR files, one for the C64 and one more commonly used by CP/M (in this case on the C128). This explanation only deals with the C64 type. This is a native C64 format, slightly similar in structure to ARK/LNX. There exists a program on the C64 called "Library 10.0" which seems to maintain these archives. From the information in the program (which is written in BASIC with a small ML subroutine), it appears the program was really meant for up/downloading files from BBS's. From looking over the text in Library V7.0, the author appears to be Mike Swanson, or at least the author of that version. The archive starts out with a 3 byte signature ("DWB"), the file size and file types are stored in ASCII with a single space padding their start/end, and all strings and numbers are terminated with a . 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII ----------------------------------------------- ---------------- 0000: 44 57 42 20 39 20 0D 53 55 50 45 52 20 44 4F 53 DWB9SUPERDOS 0010: 0D 50 0D 20 31 35 30 37 20 0D 44 4D 43 20 31 2E P1507DMC1. 0020: 32 2F 47 52 41 46 46 49 54 59 0D 50 0D 20 32 30 2/GRAFFITYP20 0030: 32 34 31 20 0D 42 2E 44 45 4C 54 41 20 5A 41 4B 241B.DELTAZAK 0040: 20 2E 44 4D 43 0D 50 0D 20 32 37 30 32 20 0D 42 .DMCP2702B 0050: 2E 52 4F 43 4B 20 5A 41 4B 31 20 2E 44 4D 43 0D .ROCKZAK1.DMC 0060: 50 0D 20 32 38 38 36 20 0D 49 4E 46 4F 52 4D 41 P2886INFORMA 0070: 54 49 4F 4E 2E 2E 2E 0D 50 0D 20 38 38 34 38 20 TION...P8848 0080: 0D 42 2E 4B 49 44 44 49 4E 47 20 20 20 2E 44 4D B.KIDDING.DM 0090: 43 0D 50 0D 20 32 38 39 31 20 0D 42 2E 47 41 4C CP2891B.GAL 00A0: 57 41 59 20 5A 41 4B 2E 44 4D 43 0D 50 0D 20 32 WAYZAK.DMCP2 00B0: 38 36 30 20 0D 42 2E 41 20 4D 55 53 49 43 20 20 860B.AMUSIC 00C0: 20 2E 44 4D 43 0D 50 0D 20 33 31 33 37 20 0D 47 .DMCP3137G 00D0: 2E 50 41 43 4D 41 4E 49 41 20 20 2E 44 4D 43 0D .PACMANIA.DMC 00E0: 50 0D 20 33 32 36 32 20 0D 01 08 0B 08 00 00 9E P3262 The first 3 bytes are the signature to the file, "DWB", perhaps the true authors initials... 0000: 44 57 42 .. .. .. .. .. .. .. .. .. .. .. .. .. DWB............. Following this is the number of entries in the directory (9). See how it has a space preceeding it, trailing it, and a at the end of the string. 0000: .. .. .. 20 39 20 0D .. .. .. .. .. .. .. .. .. ...9.......... Following this we have the first directory entry. The file is "Super DOS", it is a program file ("P"), and it is 1507 bytes long. The filenames are not stored with any shift-space padding (like most other formats), so the directory entries vary widely in size. The filename does get terminated with a . From my experiments with the Library program, it does *not* support REL files. 0000: .. .. .. .. .. .. .. 53 55 50 45 52 20 44 4F 53 .......SUPERDOS 0010: 0D 50 0D 20 31 35 30 37 20 0D .. .. .. .. .. .. .P.1507....... Following this are the remaining directory entries. 0010: .. .. .. .. .. .. .. .. .. .. 44 4D 43 20 31 2E ..........DMC1. 0020: 32 2F 47 52 41 46 46 49 54 59 0D 50 0D 20 32 30 2/GRAFFITY.P.20 0030: 32 34 31 20 0D .. .. .. .. .. .. .. .. .. .. .. 241............ ... 00C0: .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 47 ...............G 00D0: 2E 50 41 43 4D 41 4E 49 41 20 20 2E 44 4D 43 0D .PACMANIA.DMC. 00E0: 50 0D 20 33 32 36 32 20 0D .. .. .. .. .. .. .. P.3262....... If it is not obvious yet, there is no way to know where the first file's data starts in the archive until the whole directory has been read. The byte following the of the last entry it is the first byte of the first entry. 00E0: .. .. .. .. .. .. .. .. .. 01 08 0B 08 00 00 9E ............. From the starting location of the file file's data, you can now calculate where all the other entries start by using the file size, contained in each directory entry. In this case, the first file starts at $00E9 (offset 233). The second will then start at $06CC (1740). 06C0: .. .. .. .. .. .. .. .. .. .. .. .. 01 08 0B 08 ................. 64COPY supports this format on a read-only basis, allowing you to convert the files contained to another format. --------------------------------------------------------------------------- What it takes to support LBR: Except for a simple layout, and a 3-byte signature to identify the file, a few obvious deficiencies exist in the LBR layout which can make support difficult. Reading LBR files, in order to copy files out, is relatively easy. Once the directory is read we know all the file sizes, and we also know where the first file starts. It is a simple matter to figure out where each file actually starts in the LBR from this information. Writing LBR is more difficult as it would appear that you must know the size of each file *before* you create the LBR header. It would also appear that the whole directory must be created before *any* file copying can take place. When copying files from a D64 to an LBR, you don't know the *exact* file size as they are stored in sectors. You would need to scan the source file, tracing the sectors until the last one to determine its size. Unlike LNX/ARK, the size of the directory is not made to fit blocks of 254 bytes (for easy 1541 usage), and the files are not aligned to 254 byte boundaries. This makes deleting files more difficult as no matter which file gets deleted, the whole file will have to be re-written. The lack of a consistent directory entry size (like D64's 32 bytes) also makes working with LBR inconvenient. Many of the file formats for the C64 and the emulators suffer from this lack of a well-defined layout. It is understandable, however, why formats like LBR (and LNX) create their entries in ASCII rather than binary as it's easier to use BASIC and output a number in ASCII (delimited with a ) than to calculate and output the value in binary format. The last negative for LBR is it doesn't support REL or GEOS files, but thats not so important. *** LHA, LZH, LZS (LHArc compressed files) *** Document revision 1.1 These files are created with LHA on the C64 (or C128), and can present special problems to the typical PC user. The compression used is LH1, an old method used on LZH 1.xx (pre-version 2), so any version of LHA on the PC can uncompress them. However, LHA allows filenames of up to 18 characters long, and DOS doesn't know how to handle them (Windows 95 unLHA utilities will extract the full filename). Usually, some of the files already uncompressed will be overwritten by other files just being uncompressed because the name seems the same to DOS. To LHA however, the filenames are quite different. LHA archives always have a string two bytes into the file ("-L??-") which describe the type of compression used. Over the development life of LHA there have been several different compression algorithms used. The "??" in the "-L??-" can be one of several possibilites, but on the C64 it is likely limited to "H0" (no compression) and "H1". Newer versions of LHA/LZH use other combinations like "H2", "H3", "H4", "H5", "ZS", "Z5", and "Z4". The letters typically used in the compression string come from a combination of the creators initials of the LZ algorithm, Lempel/Ziv, and the author of the LHA program, Haruyasu Yoshizaki. The following is a sample of an LHA header. Note the string to search for at byte $0002: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII ----------------------------------------------- ---------------- 0000: 24 93 2D 6C 68 31 2D 39 02 00 00 16 04 00 00 00 ..-lh1-......... 0010: 08 4C 14 00 00 0E 73 79 73 2E 48 6F 75 73 65 20 ................ 0020: 4D 34 00 53 DE 06 11 1C 12 C4 C8 FA 3A 5B DC CE ................ 0030: B2 FA 38 1E 46 B0 B6 9E 9B 75 7A 49 71 72 B3 53 ................ 0040: 6E 4E B4 A0 BF 5E 95 B3 05 8A 75 D5 6C E3 03 4A ................ 0050: 2C 54 F4 AF 05 18 59 E2 F4 34 4A 0A 28 D4 33 E2 ................ 0060: C4 9D 04 D7 C7 8B 91 66 0E E5 DE 98 3C 92 CC B5 ................ The header layout is fairly basic. The header for each file starts *two* bytes before the "-lh?-" string. The above example has already been trimmed down to start at these two bytes. Each header has the same layout, only the length varies due to the length of the filename. Here is a breakdown of the above example. Bytes: $0000: 24 - Length of header (known as "LEN", not including this and the next byte). If it is zero, we are at the end of the file. 0001: 93 - Header checksum 0002: 2D 6C 68 31 2D - LHA compression type "-LH1-" 0007: 39 02 00 00 - Compressed file size ($00000239) 000B: 16 04 00 00 - Uncompressed file size ($00000416) 000F: 00 08 4C 14 - Time/date stamp 0013: 00 - File attribute 0014: 00 - Header level 00 = non-extended header 01, 02 = extended header 0015: 0E - Length of the following filename 0016: 73 79 73 2E 48 6F 75 - Filename, with a zero and filetype 73 65 20 4D 34 00 53 appended ("SYS.HOUSE M4S"). The name can be up to 18 characters in length. Note the length *includes* the zero and filetype, making the actual filename length 2 bytes shorter. 0024: DE 06 - File data checksum (starts at LEN) 0026: 11 1C 12 C4 C8 FA... - File data (starts at LEN+2) The header checksum at byte $0001 is calculated by adding the bytes in the header from $0002 (LHA compression type) to LEN+1 (File data checksum), without carry. The time/date stamp (bytes $000F-$0012), is broken down as follows: Bytes:$000F-0010: Time of last modification: BITS 0- 4: Seconds divided by 2 (0-58, only even numbers) BITS 5-10: Minutes (0-59) BITS 11-15: Hours (0-23, no AM or PM) Bytes:$0011-0012: Date of last modification: BITS 0- 4: Day (1-31) BITS 5- 9: Month (1-12) BITS 10-15: Year minus 1980 The format of the compressed data is much too complex to get into here. Understanding the layout would require knowledge of Huffman coding and sliding dictionaries, and is nowhere near as simple as ZipCode! The description given in the LHA source code for the different compression modes are as follows: -lh0- no compression, file stored -lh1- 4k sliding dictionary (max 60 bytes) + dynamic Huffman + fixed encoding of position -lh2- 8k sliding dictionary (max 256 bytes) + dynamic Huffman -lh3- 8k sliding dictionary (max 256 bytes) + static Huffman -lh4- 4k sliding dictionary (max 256 bytes) + static Huffman + improved encoding of position and trees -lh5- 8k sliding dictionary (max 256 bytes) + static Huffman + improved encoding of position and trees -lzs- 2k sliding dictionary (max 17 bytes) -lz4- no compression, file stored -lz5- 4k sliding dictionary (max 17 bytes) There are several utilities that you can use to decompress these files, like the already-mentioned LHA on the PC, or Star LHA, one of the many excellent utilities contained in the Star Commander distribution package. If you use Star LHA, keep in mind it needs the program LHA v2.14 (or newer) to extract. If an older version of LHA is used (such as the common version 2.13), then the files being extracted will be corrupt. It will extract the files directly into a D64 archive, so the long C64 filenames will not be lost. To an emulator user there is no use to these files, as their only real usage on a C64 was for storage and transmission benefits. The standard compression program on the PC is PKZIP (or ZIP compatibles), so unless you have some need to send *compressed* files back the C64, there is no use in using LHA. *** LNX (LyNX) *** Document revision 1.1 Written by Will Corley (and subsequently cloned and rewritten by many others like "Willie" or "S.B."'s "Ultimate Lynx"), this format is designed around the sector size of the 1541. It consists of "blocks" of 254 bytes each (256 if we are on a real 1541 or a D64 due to the inclusion of the track/sector info at the beginning of each sector). One word of warning: the Lynx utility "Ultimate Lynx" can sometimes create LNX archives which do *not* have the sector data block-aligned to 254-byte boundaries. If they are not aligned, the files contained within will be corrupt when extracted. When these files are on *any* other format they do not have the track/sector info, and therefore use only 254 bytes/block. Here is a dump of the directory header of one permutation of the layout... 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII ----------------------------------------------- ---------------- 0000: 01 08 5B 08 0A 00 97 35 33 32 38 30 2C 30 3A 97 ..[.53280,0: 0010: 35 33 32 38 31 2C 30 3A 97 36 34 36 2C C2 28 31 53281,0:646,(1 0020: 36 32 29 3A 99 22 93 11 11 11 11 11 11 11 11 22 62):"........" 0030: 3A 99 22 20 20 20 20 20 55 53 45 20 4C 59 4E 58 :"USELYNX 0040: 20 54 4F 20 44 49 53 53 4F 4C 56 45 20 54 48 49 TODISSOLVETHI 0050: 53 20 46 49 4C 45 22 3A 89 31 30 00 00 00 0D 20 SFILE":10. 0060: 31 20 20 2A 4C 59 4E 58 20 58 56 20 20 42 59 20 1*LYNXXVBY 0070: 57 49 4C 4C 20 43 4F 52 4C 45 59 0D 20 34 20 0D WILLCORLEY.4. 0080: 34 21 5A 4F 4E 45 20 4F 46 20 44 2D 2F 41 56 54 4!ZONEOFD-/AVT 0090: 0D 20 37 31 20 0D 50 0D 20 31 36 30 20 0D 31 21 .71.P.160.1! 00A0: 5A 4F 4E 45 20 4F 46 20 44 2D 2F 41 56 54 0D 20 ZONEOFD-/AVT. 00B0: 37 35 20 0D 50 0D 20 31 35 31 20 0D 32 21 5A 4F 75.P.151.2!ZO 00C0: 4E 45 20 4F 46 20 44 2D 2F 41 56 54 0D 20 31 37 NEOFD-/AVT.17 00D0: 30 20 0D 50 0D 20 32 34 39 20 0D 33 21 5A 4F 4E 0.P.249.3!ZON 00E0: 45 20 4F 46 20 44 2D 2F 41 56 54 0D 20 31 35 38 EOFD-/AVT.158 00F0: 20 0D 50 0D 20 31 33 38 20 0D 00 00 00 00 00 04 .P..138. 0100: 1A 00 1A 08 05 08 E0 00 FF C2 0D 85 0F 04 39 03 .....…..9. It starts out with a BASIC program which, when loaded and run, displays the message "Use LYNX to dissolve this file". The actual message and size of the program can change. Usually, its 94 bytes long, from $0000 to $005D. 10 POKE53280,0:POKE53281,0:POKE646,PEEK(162):PRINT" ":PRINT" USE LYNX TO DISSOLVE THIS FILE":GOTO10 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII ----------------------------------------------- ---------------- 0000: 01 08 5B 08 0A 00 97 35 33 32 38 30 2C 30 3A 97 ..[.53280,0: 0010: 35 33 32 38 31 2C 30 3A 97 36 34 36 2C C2 28 31 53281,0:646,(1 0020: 36 32 29 3A 99 22 93 11 11 11 11 11 11 11 11 22 62):"........" 0030: 3A 99 22 20 20 20 20 20 55 53 45 20 4C 59 4E 58 :"USELYNX 0040: 20 54 4F 20 44 49 53 53 4F 4C 56 45 20 54 48 49 TODISSOLVETHI 0050: 53 20 46 49 4C 45 22 3A 89 31 30 00 00 00 .. .. SFILE":10.. Following this is the "signature" of the archive, as well as the size of the directory (in blocks) and the number of directory entries in the archive. These are stored in CBM lower case (ASCII for the most part), it is delimited by after each entry (except the directory block size!), and has spaces on both sides of the numbers. Normally the signature will contain the string "LYNX" somewhere. You will note that the numbers (and filetype) stored in both the LNX signature and the directory entries are unusual in that they are stored in ASCII, not binary (like the D64 entries). The only explanation for this seems to be that the utilities used on the C64 to create them were using the INPUT# and PRINT# routines. These will store numbers as ASCII, not binary, and will truncate with a . 0050: .. .. .. .. .. .. .. .. .. .. .. .. .. .. 0D 20 ................ 0060: 31 20 20 2A 4C 59 4E 58 20 58 56 20 20 42 59 20 1*LYNXXVBY 0070: 57 49 4C 4C 20 43 4F 52 4C 45 59 0D 20 34 20 0D WILLCORLEY.4. Note: some archives have been found which do *NOT* conform to the established LNX header/directory structure. They do not contain spaces after the numbers in the directories, or contain extra spaces in the LNX header. Such files might give trouble Un-Lynxing on a real C64, and they do not appear to have been created by Will Corley's standard "LyNX" program. So in the above example, we have a directory of 1 block (254 bytes) long, the archive was created by "LYNX XV BY WILL CORLEY", and we have 4 entries in the directory. The total directory length is 1 block * 254 bytes=254 bytes. Therefore at byte $00FE, the program data will start. If the directory size was 3 blocks, the data would start at $02FA. I do not know what the maximum size is for either number (dir size/entry total), but it would seem to be that since the 1541 only can store 144 files, these numbers would be limited accordingly. 0080: 34 21 5A 4F 4E 45 20 4F 46 20 44 2D 2F 41 56 54 4!ZONEOFD-/AVT 0090: 0D 20 37 31 20 0D 50 0D 20 31 36 30 20 0D .. .. .71.P.160... This is the first directory entry called "4!ZONE OF D-/AVT". The layout has the filename (in PETASCII, typically padded to 16 characters by shifted-spaces), followed by the size of the file in blocks of 254 bytes, the file type (P, S, R, U), and the LSU byte (see "INTRO.TXT" document for description of "LSU") If the file type is REL, this entry is the RECORD size, and the next entry is the last block size. If the file type is not REL, the next entry will be the next filename. 0090: .. .. .. .. .. .. .. .. .. .. .. .. .. .. 31 21 ..............1! 00A0: 5A 4F 4E 45 20 4F 46 20 44 2D 2F 41 56 54 0D 20 ZONEOFD-/AVT. 00B0: 37 35 20 0D 50 0D 20 31 35 31 20 0D .. .. .. .. 75.P.151..... This is the second directory entry. It follows the same layout as the first. 00B0: .. .. .. .. .. .. .. .. .. .. .. .. 32 21 5A 4F ............2!ZO 00C0: 4E 45 20 4F 46 20 44 2D 2F 41 56 54 0D 20 31 37 NEOFD-/AVT.17 00D0: 30 20 0D 50 0D 20 32 34 39 20 0D 33 21 5A 4F 4E 0.P.249.3!ZON 00E0: 45 20 4F 46 20 44 2D 2F 41 56 54 0D 20 31 35 38 EOFD-/AVT.158 00F0: 20 0D 50 0D 20 31 33 38 20 0D .. .. .. .. .. .. .P.138....... This is the third and fourth entry. 00F0: .. .. .. .. .. .. .. .. .. .. 00 00 00 00 .. .. ............ The remaining bytes are unused, and exist simply as filler to pad the directory so as it takes up to its alloted space (recall it is one block of 254 bytes). Once the directory has ended, the real file information is stored. Since in this example the directory is only 1 block long, the file info starts at byte $00FE... 00F0: .. .. .. .. .. .. .. .. .. .. .. .. .. .. 00 04 ............... 0100: 1A 00 1A 08 05 08 E0 00 FF C2 0D 85 0F 04 39 03 ........9. The files are also stored so that they take up the full multiples of 254 bytes. This does result in a little dead space at the end of each file stored, but its a small price to pay for how easy it is to construct and break up files on a real C64. When a LNX archive is created, a new file is created on the disk containing all the necessary information about the files it is going to contain such as the BASIC program, signature and central directory. The header track/sector link is then pointed to the beginning of the first file. The last sector track/sector link of the first file is then pointed to the start of the second file and so on, until the last file is added. This method makes creating LNX's very quick! The advantage to this method is that *no* files are moved or compressed, they are simply "linked" together by changing the t/s links to create one large file (hence the name LNX). REL file entries are a little more special. The first blocks of the file contain the side sector info, followed by normal program/data. The only usefulness in containing this side-sector info is so that you don't have to allocate them after extracting the file, but just change the t/s links to point to the new records. One disadvantage to its use on the PC is the lack of a better laid out central directory, one that had the same number of bytes used for each entry, like the D64, T64, or ARK, and had a user-definable directory size, also like the D64/T64. That makes it difficult to add files to an existing archive on a PC, but 64COPY and Star Commander can add/delete to LNX files. --------------------------------------------------------------------------- What it takes to support LNX: There are many good points to the LNX format, making them only somewhat difficult to support. They contain a signature, have a provision for multi-block directories, the files and directory are block-aligned to 254 byte boundaries, REL files are handled, and you can store more than 144 files (if you want to). There is one bad point to LNX files and that is the individual directory entry size is not set (like D64's 32 bytes). They are stored in ASCII (like LBR format), making the entry size variable. This makes adding/deleting files difficult in that the directory has to be re-written quite a bit. One other bad thing that has developed over time is that many people have written their own "lynxing" programs, and have deviated from the standard layout. There are many styles of LNX files, earlier versions being somewhat different from the later ones, but more importantly is there are LNX files which don't work with the normal "Will Corley" unLYNXing utilities. --------------------------------------------------------------------------- Overall Good/Bad of LNX Files: Good ---- * Supports the standard 16-char filename, * Filenames padded with the standard $A0 character * Allows for directory customization, as zero-length files are allowed * Expandable central directory * Supports REL files * It is a very well established file format, many utilities available to work with them * Has a file signature * Filenames can have 00's in them(?) Bad --- * There are too many LNX programs out there, too many LNX header variations, and not all of the utilities make compatible LNX archives * Has a very badly laid-out header (ASCII, not binary byte oriented). Each directory entry has a variable length * It is not easy to re-write the header and central directory. With file additions/deletions, it is *usually* necessary to re-write the entire file * Since files are stored in block sizes of 254-bytes, each stored file usually has some extra lost space * Can't store special file attribute bits * Does not store GEOS *** P00/S00/U00/R00 (PC64-native files) *** Document revision 1.1 These files were created for use in the PC64 emulator, written by Wolfgang Lorenz. Each one has the same layout with the filetype being stored in the DOS extension (i.e. Pxx is a PRG, Sxx is a SEQ, Uxx is a USR and Rxx is a relative file), and the header is only 26 bytes long. This is a dump of a Pxx file (PRG)... 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII ----------------------------------------------- ---------------- 0000: 43 36 34 46 69 6C 65 00 43 52 49 53 49 53 20 4D C64File.CRISIS.M 0010: 4F 55 4E 54 41 49 4E 00 00 00 .. .. .. .. .. .. OUNTAIN......... Bytes: $00-06: ASCII string "C64File" 07: Always $00 08-17: Filename in PETASCII, padded with $00 (not $A0, like a D64) 18: Always $00 19: REL file record size ($00 if not a REL file) 1A-??: Program data The 'xx' in the extension of the file is usually 00, except when we have two DOS filenames which would be the same, but the C64 filenames are different! If we have two C64 filenames which are the same, they *cannot* co-exist in the same directory. If we have two files which do convert down to be the same DOS filename, the extension is incremented until an unused one is found (P01, P02, P03, etc). We can have up to 99 different C64 files with the same corresponding DOS names as that's all the extension will hold (from P00 to P99). Each PC64 file only has one entry, there are no multi-file archives allowed. This could result in a large number of these files in a directory, even for only a few programs, as each C64 file will result in a PC64 file entry. The best use for a PC64 file is a single-file program, one which does not load anything else. The DOS filename is generated by an algorithm used inside PC64 when a file needs to be created. It compresses the 16-byte name down to one that fits the DOS 8 character size limitation. One thing which most people might not know is you *musn't* rename the P/S/R/U DOS files. If you do, PC64 won't be able to load them. When PC64 goes searching for files, it takes the 16-byte C64 filename, does its magic to reduce it to 8.3, then looks to see which DOS files match. Remember, there could be several files with the same 8 character name, but the extensions will be P00, P01, P02 etc. If it can't find the 16-byte C64 filename in amongst those that match, it will report a "File not found". I've tried this with the DOS version (PC64 1.20) and it does report an error locating the file, both in the File Manager and the 64 emulator window. --------------------------------------------------------------------------- What it takes to support PC64 files: The biggest benefit to this format is that the layout and usage is fairly simple to implement. With a consistent 26-byte header and a signature, there's very little difficulty in working with them. Also, PC64 files perform best when used on single-file games as they have *no* wasted space. One good design aspect of PC64 files is how REL files are supported. LNX, D64 and ARK all require storage of the side sectors, either preceeding or following the file. R00 does not need to store these, making it more efficient. The biggest drawback to this format is when converting small C64 files (those of only a few sectors), you could waste hard disk space due to a large DOS "slack" area. When DOS stores files of any size, each one takes up a minimum of one cluster, which on small drives may only be 2 kb/cluster, but on vary large disks could be as high as 32 or 64 kb per cluster. An emulator file which is only a few Kb would, on the large disks, only use a small portion of the total cluster, and thus a lot of wasted DOS storage space results. Note, this also applies to normal DOS files as well! Another drawback (not obvious right away) is since some games are made up of a large number of files or varying sizes, it would be best to store each game in a different sub-directory. If you don't, then you might not be sure what files belong to what programs, and if you ever want to give a program to someone else, there would be difficulties re-assembling the program. This makes file management much more user intensive. The D64 format seems to be the best one for multi-file games. The last negative is that GEOS files cannot be put into the P00 format. They must reside on a native D64 disk in order to work. --------------------------------------------------------------------------- Overall Good/Bad of PC64 Files: Good ---- * Has a 16 character filename * Filetype is available in the DOS file extension * Can easily calculate the file size of the C64 file from the DOS file size (DOS size - 26) * Supports 1541 REL files (R00) * Does not need the side sector info for REL support, like LNX and ARK do. * A very simple, easy to support file header * Can have multiple C64 files with the same name in a DOS directory since the file extension will simply change slightly * Due to each P00 being a separate DOS file, the emulators can easily rewrite any P00 file they need to. This can be useful for debugging/cracking etc. This is only an emulator side effect, but its useful Bad --- * Filenames are padded with $00, not the standard $A0 character * No directory customization, as each PC64 file only holds one C64 file * Since the filetype is the DOS extension, no special attribute bits or non-standard file types (DEL) are kept * Depending on the PC64 filesize and the DOS hard disk cluster size, there could be significant cluster slack-space loss, especially noticible with many P00 files * Unless the user keeps the P00 files organized, you can end up with a mass of confusing files in one directory. File management is crucial to keeping a good archive. It is best to keep each multi-file program in separate directories. Each directory entry also takes up space. * Not as widely supported as D64 or T64 * No GEOS file structure support * No labels/description field in the file header * No multi-file support (as it wasn't designed to do this) * Each file contains a separate C64 name, and in order to get a list of all the real C64 names, *each* file must be read individually to get this * Can't rename the DOS P00 file since PC64 depends on the filename being an algorithmic reduction of the C64 filename. Changing it likely will likely render the file useless to PC64 * No 00's allowed in filenames(?) * I don't think PC64/WIN supports the original PC64/DOS files *** C64 (PC64 saved-session image) *** Document revision 1.1 These are files created when you save a C64 window under PC64 (DOS only). It consists of a 64k memory dump, color ram dump, I/O ports, the name of the ROM images you were using at the time, and user-setable options. Typical size is around 69091 bytes. 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ----------------------------------------------- 00000: 43 36 34 49 6D 61 67 65 00 .. .. .. .. .. .. .. C64Image........ ... 00000: .. .. .. .. .. .. .. .. .. 2F 37 00 AA B1 91 B3 00010: 22 22 00 00 4C 00 FF 00 04 00 00 00 00 00 00 19 00020: 16 00 0A 76 A3 00 00 00 00 00 00 76 A3 B3 BD 00 00030: 00 00 00 00 01 08 03 08 03 08 03 08 00 A0 00 00 ... 10000: .. .. .. .. .. .. .. .. .. 0E 0E 0E 0E 0E 0E 0E 10010: 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 10020: 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 10030: 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E ... 10400: .. .. .. .. .. .. .. .. .. 0E 0E 0E 0E 06 06 06 10410: 06 00 00 00 00 00 00 00 00 00 00 C8 00 20 34 37 10420: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 10430: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 10440: 20 20 20 20 20 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E ... Byte: $00000-00008: The signature "C64Image" followed by a $00. Note the varying case of the text. 00009-10008: Main memory of the C64 (64K, $0000-FFFF) 10009-10408: Color memory (1k, $D800-DBFF) 10409-?????: I/O memory and user-selectable options (ROM version, etc). The ????? means the end of the file is not known, since these files can vary in length. Since these files are only supported by PC64 for DOS (*NOT* for Win95), it is not worth getting too much into the layout. I was attempting to decipher the layout of the I/O ports and options area but decided it wasn't worth it. *** 64x (PC64/DOS ROM files) *** Document revision 1.0 These files, used by the PC64 emulator, are simply the BASIC, KERNEL and CHARACTER ROM's in electronic form. There contain no signature, but rather are raw binary dumps of either the ROM's contained in the C64 computer, or other customized ROM's. There are three different files, denoted by the change in the last character of the file extension... 64B - BASIC ROM ('B'), This is the ROM from $A000-BFFF, which contains the BASIC interpreter. It is always 8192 bytes. 64C - CHARACTER ROM ('C') This is the ROM from $D000-DFFF, which contains the character sets. It is always 4096 bytes. 64K - KERNEL ROM ('K'). This is the ROM from $E000-FFFF, which contains all the KERNEL calls and I/O routines. It is always 8192 bytes. *** C64 (PCLINK image files) *** Document revision 1.1 This is another "C64-to-PC" connection program. It was written by Peter Jakab in 1994. With it and a custom interface cable, you could link your C64 and PC together to use the PC's hard disk as a C64 storage device. Files you wanted to be seen would have to be in this ".C64" format. (Note: don't confuse these files with PC64's .C64 saved-session files) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII ----------------------------------------------- ---------------- 00: 38 CD 81 06 50 43 4C 49 4E 4B 20 20 20 00 00 00 8́PCLINK 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 20: 00 00 00 00 01 08 0B 08 00 00 9E 32 30 36 31 00 2061 30: 00 00 78 A2 FB 9A 20 18 E5 20 55 10 A9 00 8D 20 xU Bytes: $00-01: PCLINK file signature ($38 $CD) 02: PRG filetype ($81, *not* $82 as you would expect). No other filetype was supported. 03: Filename length ($06) 04-13: Filename (16 bytes allotted, name padded with $00's) 14-23: Miscellaneous field (16 bytes allotted) - this was never implemented. 24-: File data starts here PCLINK also supports DOS BINARY files if their filename started with a "#". These files would have no header. *** Power 64 RAM Snapshot File (Macintosh) *** Document revision 1.1 These files, similar in nature to PC64's .C64 files, are a complete memory dump of the 64K RAM, color RAM, and all I/O ports and CPU registers. Presently, this format is supported by the Power64 emulator and may be added to future versions of the VICE emulator. The file size is 69888 bytes. The format for RAM Snapshots was adapted from a suggestion by Jouko Valta for the Vice Emulator on Unix systems. * Note: All multi-byte values are stored in big-endian format (high/low) rather than in the little-endian format (low/high) used by the C64, since the Macintosh stores values this way. No sample memory dump is available. Byte: $00000-00005: Magic Header (at present $43, $42, $4D, $64, $00, $00) or "CBM",$64,$00,$00 00006-00007: Reserved (should be $00, $00) 00008-00009: Version major and minor ($01, $00, or 1.0) 0000A: Emulator snapshot ID (Power64 is $2F) 0000B: Snapshot type (presently $00) 0000C-0000D: Offset in bytes (high/low), to RAM image in snapshot. The header size is presently 256 bytes, so the values are $01, $00. 0000E-0000F: RAM image size (in Kbytes, presently $00, $40, or 64 Kbytes) 00010-00011: REU RAM image size (in Kbytes, presently $00, $00) 00012-0001F: Reserved (should be $00, $00) 00020-00025: Configuration bit masks (presently all $00) 00026: I/O RAM size (Power64 value $01) Bit 0: I/O data available (0 = no) 1 and 2: Video Display Controller RAM 00 = none 01 = 16 Kb 10 = 64 Kb 11 = 32 Kb) 00027: CPU's available (Power64 value $01) Bit 0: 6502 1: Z80 2: REC 00028-00029: 6502 program counter (high/low) 0002A-0002C: A, X and Y CPU registers 0002D: 6502 flags register 0002E: 6502 stack pointer (SP) 0002F: 6502 I/O port 00030-0003F: Z80 registers (not used yet, should be $00) 00040-0004F: REC registers (not used yet, should be $00) 00050: C64 kernal ID byte (not used yet) 00051: Kernal patch ID for fastloaders, etc. (not used yet) 00052-00053: Kernal patch version ID (not used) 00054-0007F: Kernal version information (not used yet) 00080-000FF: Miscellaneous info on peripherals (not used yet) 00100-100FF: 64Kb RAM area (size depends on value in 0000E-0000F) 10100-110FF: Contents of the C64 I/O area *** SDA (Self-Dissolving compressed Archive) *** Document revision 1.1 The name stands for "Self-Dissolving Archive", and thats exactly what it does. There is a decompression engine at the beginning of the file called by a BASIC SYS command. It will decompress all the files contained in the archive to whatever device you specify, or disk you select. I have found two somewhat different SDA files, one has a longer decompression header than the other. They would appear to be different revisions of the decompression engine, but they all seem to be self-extracting ARC files. The HEX dump below is a sample of the shorter version of SDA... 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII ----------------------------------------------- ---------------- 0000: 01 08 0D 08 0A 00 9E 28 32 30 36 33 29 00 00 00 ....(2063) which decodes to... 10 SYS(2063) The starting location of the first file in an SDA archive can be calculated given the BASIC header from above. Here's the steps... 1. Get the line number of the BASIC SYS statement (here it's 10, in the longer one its 13) 2. Subtract 6, and multiply by 254 (result 1016, or $03F8) 3. If the first number of the SYS call is a 7 (in our case it's a 2), then subtract 1 from the previous result. If its a 7 indicates it's a C128 archive, a 2 means it's a C64 archive. 4. You now have the starting position into the SDA archive to find the first file. From here on, the file has the same layout as an ARC. See the ARC topic for a better description. The easiest way the decompress these files is to use 64COPY. There is also C code available on the High Voltage CD #2 to allow you to decompress these files on a PC. SDA files can also be decompressed by running it on either a real C64 or an emulator window, and let the file undo itself to a disk image. ARC files are decompressable using the C64 program called ARC 2.50. *** SFX (SelF-eXtracting LHA/LZH compressed files) *** Document revision 1.1 These files are actually LHA archives, except there they have a decompressor program prepended to the file, capable of decompressing on either a C64 or a C128, independant of the load address. The beginning of the file is a BASIC program (with an unusual load address): 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ----------------------------------------------- 00000: 01 1C 28 1C C6 07 97 32 30 2C 30 3A 8B C2 28 32 <-Note load address 00010: 30 29 B2 30 A7 FE 02 30 3A 9E C2 28 34 36 29 AC 00020: 32 35 36 AA 36 36 3A 80 00 3C 1C D0 07 9E C2 28 00030: 34 34 29 AC 32 35 36 AA 36 36 3A 80 00 00 00 .. which when decoded looks like this: 1990 POKE20,0:IFPEEK(20)=0THEN<254><2>0:SYSPEEK(46)*256+66:END 2000 SYSPEEK(44)*256+66:END This was decoded on a C64... the two codes in line 1990, the <254> and <2>0 are not decodable on the C64, but are on the C128. The first line checks for whether it is running on a C64 or a 128. If it is a C64, it will execute the SYS call line 2000, otherwise it executes the SYS on line 1990. Later on in the header, we have the copyright message. Any SFX should have this message. 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII ----------------------------------------------- ---------------- 00D20: .. .. .. .. .. .. .. .. .. .. .. 43 36 34 2F 43 ...........C64/C 00D30: 31 32 38 20 53 45 4C 46 20 45 58 54 52 41 43 54 128 SELF EXTRACT 00D40: 49 4E 47 20 4C 48 41 52 43 48 49 56 45 0D 43 4F ING LHARCHIVE.CO 00D50: 50 59 52 49 47 48 54 20 31 39 39 30 20 2D 20 43 PYRIGHT 1990 - C 00D60: 2E 53 4D 45 45 54 53 0D 54 4F 52 4F 4E 54 4F 2C .SMEETS.TORONTO, 00D70: 43 41 4E 41 44 41 .. .. .. .. .. .. .. .. .. .. CANADA.. At address $0E89 (3721 bytes into the file) you will find the beginning of the LHA archive, denoted by two bytes and the signature '-LH1-'. 00E80: .. .. .. .. .. .. .. .. .. 1E B6 2D 6C 68 31 2D ...........-LH1- *ALL* LHA/LZH archives have this type of signature string in them ('-lhx-', where x is the type of compression used, with C64 archives being 1, and most PC archives being 5). The actual archive starts 2 bytes before this string is found, and goes to the end of the file. If you want to convert them to LHA, you can chop the front end off the file (up to two bytes before the -lhx- string), and rename it to an LHA. It will then be a normal LHA file. Another way to handle SFX's is to extract them with Star LHA. This program handles both LHA and SFX formats, as they are basically the same. Extract them as you would an LHA file (StarLHA -x xxxxxxxx.SFX). For more information on the LHA/LZH layout, refer to the LHA topic. *** SPY (SPYne archives) *** Document revision 1.1 Created by John Iannetta around 1995, these are mostly found in Compuserve's CBM applications forum, but do appear in the COMP.BINARIES.CBM newsgroup as well. It is a self-extracting archive, and does not employ any compression. The word "SPYNE" does not represent any acronym, but is meant to represent a "spine", with files linked together. This format has some similarities to LNX archives in that all the files are simply stored (with no compression), one after the other, and are byte aligned to take up multiples of 254 bytes (256 on a real 1541). This does result in a little dead space at the end of each file stored, but its a small price to pay for how easy it is to construct and break up files on a real C64/1541. SPYne files do not contain a BASIC program (like LNX) at the beginning telling you to "Use XXX to dissolve this file", since SPYne archives are self-extracting, and are meant to be loaded ",8,1" on a real C64. There is no specific signature to determine if the file is actually a SPYne. SPYne archives can store up to 144 files. Each file inside the archive can have up to 65535 blocks. However, the archive itself is limited to (best case) 65519 blocks total (65535 minus 15 blocks for extraction code, and a minimum of 1 block for directory entries, 1-8 entries). Worst case for the archive size is 65502 blocks (15 blocks for extraction and 18 blocks for a directory of 137-144 files). This many not make sense at first, but how can you load a SPYne file which exceeds 258 blocks (the maximum memory of the C64)? SPYne files can be as large as 65535 blocks, and it would seem impossible to work with files this large. The answer is that the SPYne file loads at $02A7, trapping the necessary vectors to prevent it from loading the entire archive, but just the extraction code. Neat trick! The first 15 blocks (up to offset 3809 or $0EE1) of the file contain the self-extracting code. It is an auto-running application, with a load address of $02A7. 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII ----------------------------------------------- ---------------- 0000: A7 02 20 A0 E5 A9 0A 8D 1E D0 A9 16 8D 18 D0 A9 ЩЩ 0010: 04 8D 1F D0 20 44 E5 A9 D8 85 FC A0 00 84 FB A2 D؅ 0020: 04 A9 0D 91 FB C8 D0 FB E6 FC CA D0 F6 20 A5 FF Starting at offset $0EE2 (3810) is the central directory. This address is exactly 15 blocks into the file (15*254=3810). Each directory entry is 32 bytes long, with the last two of these being "filler", and unused. 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII ----------------------------------------------- ---------------- 0EE2: 82 00 00 30 32 2E 44 49 47 49 54 41 4C 20 4D 41 02.DIGITALMA 0EF2: 47 49 43 00 00 00 00 88 18 B5 FF 00 2B 00 00 00 GIC+ 0F02: 82 00 00 30 39 2E 2D 2D 2D 3E 20 42 59 20 3C 2D 09.--->BY<- 0F12: 2D 2D 2D 00 00 00 00 00 7A 44 FF 00 2D 00 00 00 ---zD- 0F22: 82 00 00 30 33 2E 2D 3E 20 46 4F 52 43 45 53 20 03.->FORCES 0F32: 3C 2D 2D 00 00 00 00 11 BE 89 FF 00 20 00 00 00 <-- 0F42: 82 00 00 30 37 2E 2D 3E 20 4F 46 20 45 56 49 4C 07.->OFEVIL 0F52: 20 3C 2D 00 00 00 00 4F 78 11 FF 00 26 00 00 00 <-Ox& 0F62: 82 00 00 30 34 2E 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 04.---------- 0F72: 2D 2D 2D 00 00 00 00 40 58 D2 FF 00 28 00 00 00 ---@X( 0F82: 82 00 00 30 31 2E 20 52 45 4C 45 41 53 45 44 20 01.RELEASED 0F92: 4F 4E A0 00 00 00 00 05 D5 0F FF 00 29 00 00 00 ON) 0FA2: 82 00 00 30 35 2E 20 4A 41 4E 55 41 52 59 20 31 05.JANUARY1 0FB2: 53 54 20 00 00 00 00 F7 FA EC FF 00 24 00 00 00 ST$ 0FC2: 82 00 00 30 38 2E 20 20 20 31 39 39 36 A0 A0 A0 08.1996 0FD2: A0 A0 A0 00 00 00 00 39 71 C8 FF 00 36 00 82 00 9q6 0FE2: 00 30 36 2E 20 28 4D 4F 52 45 20 4C 49 4B 45 29 06.(MORELIKE) 0FF2: A0 00 00 00 00 40 33 CF FF 00 32 00 00 00 82 00 @32 1002: 00 31 30 2E 20 28 31 32 2F 32 38 2F 39 35 21 29 10.(12/28/95!) 1012: A0 00 00 00 00 AD 1C 0F FF 00 2B 00 00 00 82 00 + 1022: 00 44 49 47 49 54 41 4C 20 4E 4F 54 45 A0 A0 A0 DIGITALNOTE 1032: A0 00 00 00 00 49 B0 CB 00 00 14 00 00 00 00 00 I Byte: $00: File type supported values for this location are: $81 - SEQ 82 - PRG 83 - USR 01-02: Undefined (00's for now) 03-12: Filename (padded with $A0's) 13-16: Undefined (00's for now) 17-18: File checksum (in low/hi ghbyte format) 19: LSU byte (see "INTRO.TXT" document for description of "LSU") 1A: Last file marker FF - more files in archive 00 - last file in archive 1B: Set to $00 1C-1D: File sector count (in low/high byte format) 1E-1F: Not used (and not present on a 254-byte boundary) File type support is limited to valid files only. No write-protected, "splat" or DEL files can be archived. Without DEL type support, this means that many "separator" files in the directory cannot be included. REL files are partially supported, as only the data portion is copied, and its filetype is converted to USR format. The checksum at byte offset 17-18 is a simple 16-bit addition (without carry) of the entire file, but does not include the directory entry information. Looking at the above HEX dump, at address $0FE0 a new filename starts. This is two bytes earlier than expected. This occurs because the address $0FE0 is at a "254-byte boundary address", meaning it is divisible by 254, with no remainder. Only in the directory area is this boundary important, and when it happens, the last two "filler" bytes in the directory entry don't exist. SPYne supports two extraction methods, fast and slow. The fast method is destructive in that is just breaks up the archive into sections, only works on a 1541/1571 drive, and has no checksum verification. The slow method should work on any device, is not destructive to the original archive, and uses the checksum in the directory entry to verify the data integrity. File data starts in the next block following the end of the directory. You only know where the first file's data starts once the directory has been completely read. Since the extraction code takes up 15 blocks, and each 8 files take up another block, we can calculate how many blocks into the archive the actual file data starts. If we have 11 files, we have two directory blocks (one full with 8 entries, one partial with 3 entries). Therefore the first file's data starts at block 17 (17*254 = 4318, or $10DE). The second file's starting position can be calculated by adding the block count of the first file (multiplied by 254), and adding this to the first files starting position. *** 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 (?) *** WRA (WRAptor compressed files) *** Document revision 1.1 Written by Bill Lucier (copyright 1995), and distributed by Loadstar (on disk and from the website), this is an uncommon compression format as it is a very recent program. It handles PRG, SEQ, USR and GEOS files, but not REL files. It utilizes a variant of the LZ (Lempel-Ziv) compression algorithm, starting at 9 bits per code. The following is a dump of a sample WRA file. Notice all the filenames are preceeded by the 4-byte signature "FF 42 4C FF", which contains the authors initials "BL". (Note: much of the following explanation is theoretical, as I have not been able to crack the compression method yet.) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII ----------------------------------------------- ---------------- 0000: FF 42 4C FF 50 4F 4F 59 41 4E 00 02 00 82 04 60 BLPOOYAN..` 0010: 80 50 01 16 41 59 0C 14 F0 81 0C 47 49 31 11 40 P..AY...GI1.@ 0020: 9E 4F 2C 90 49 C2 E2 61 3C 82 44 22 94 84 42 C1 O,Ia