diff --git a/Commodore/64LAN.TXT b/Commodore/64LAN.TXT new file mode 100644 index 0000000..85d9aa6 --- /dev/null +++ b/Commodore/64LAN.TXT @@ -0,0 +1,52 @@ + +*** L64 (64LAN container files) +*** Document revision: 1.3 +*** Last updated: March 11, 2004 +*** Compiler/Editor: Peter Schepers +*** Contributors/sources: Markus Mehring + + 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. + diff --git a/Commodore/64NET.TXT b/Commodore/64NET.TXT new file mode 100644 index 0000000..8a7bdbd --- /dev/null +++ b/Commodore/64NET.TXT @@ -0,0 +1,82 @@ + +*** N64 (64NET container files) +*** Document revision: 1.3 +*** Last updated: March 11, 2004 +*** Compiler/Editor: Peter Schepers +*** Contributors/sources: Markus Mehring + + 64NET links your C64 and PC together through a special cable, and +provides the C64 access to many image 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 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". + diff --git a/Commodore/ARC.TXT b/Commodore/ARC.TXT new file mode 100644 index 0000000..843a9af --- /dev/null +++ b/Commodore/ARC.TXT @@ -0,0 +1,59 @@ + +*** ARC (compressed ARChive) +*** Document revision: 1.4 +*** Last updated: March 11, 2004 +*** Compiler/Editor: Peter Schepers +*** Contributors/sources: Chris Smeets (source code) + + 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 contain 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. + + Watch out for "extra" data at the end of the file, typically many $00's. +Some files which exist have this, and it makes reading the contained file +list more difficult. + + 64COPY can unpack ARC files easily, and just hitting return on them will +open the archive. Simply select what files you want to extract, and copy +them out. + diff --git a/Commodore/ARK-SRK.TXT b/Commodore/ARK-SRK.TXT new file mode 100644 index 0000000..019df49 --- /dev/null +++ b/Commodore/ARK-SRK.TXT @@ -0,0 +1,136 @@ + +*** ARK (ARKive containers) +*** SRK (compressed ARKive archives, very rare) +*** Document revision: 1.3 +*** Last updated: March 11, 2004 +*** Compiler/Editor: Peter Schepers +*** Contributors/sources: unknown + + 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 files 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. + diff --git a/Commodore/BINARY.TXT b/Commodore/BINARY.TXT new file mode 100644 index 0000000..04730a7 --- /dev/null +++ b/Commodore/BINARY.TXT @@ -0,0 +1,111 @@ + +*** Binary/Raw files +*** Document revision: 1.3 +*** Last updated: March 11, 2004 +*** Compiler/Editor: Peter Schepers +*** Contributors/sources: none + + 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. + + Two possible file extensions that binary files can use are "BIN" and +"PRG". There is a distinction in the 64 community between these two file +types. A "BIN" (binary) file is one without a load address preceeding the +file data, and a "PRG" (program) file has a load address in the first two +bytes of the file. + + 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-image" 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 image/archive, 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 + diff --git a/Commodore/BITMAP.TXT b/Commodore/BITMAP.TXT new file mode 100644 index 0000000..11fd710 --- /dev/null +++ b/Commodore/BITMAP.TXT @@ -0,0 +1,40 @@ + +*** Standard C64 BITMAP Files (HIRES & HIRES-MULTICOLOR) +*** Document revision: 1.3 +*** Last updated: March 11, 2004 +*** Compiler/Editor: Peter Schepers +*** Contributors/sources: Peter Weighill + + Below is a table to help in the identification of C64 bitmap files. If +you require further information about how bitmaps are displayed then you +should refer to the C64 Programmers Reference Manual. + + To automatically identify the type of file, you need to compare the +length of the file and the Load address. Once you have identified the file +type, you can then use the bitmap, screen and colour offsets to help in the +displaying of the bitmap. + +Format for file 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 + diff --git a/Commodore/C128BOOT.TXT b/Commodore/C128BOOT.TXT new file mode 100644 index 0000000..40b122c --- /dev/null +++ b/Commodore/C128BOOT.TXT @@ -0,0 +1,58 @@ + +*** C128 Auto-boot sector layout +*** Document revision: 1.1 +*** Last updated: March 11, 2004 +*** Compiler/Editor: Peter Schepers +*** Contributors/sources: unknown + + The C128 has the ability to auto-boot a floppy disk that is in the drive +when the system is powered up, but only if track 1 sector 0 contains a +specific signature. Below is a dump of an auto-boot sector with its +signature. + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +0000: 43 42 4D 00 0C 00 02 00 00 A5 D7 C9 80 F0 03 20 CBMɀ +0010: 5F FF A9 05 8D 06 D5 A9 4E 8D 00 FF 4C 00 0C 00 _թNL +0020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +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 00 00 + + Bytes 00-02: Auto-boot signature 'CBM' + 03-04: ??? + 05-06: ??? + 07-08: ??? + 09-1E: Boot code + 1F-FF: ??? + +Below is a disassembly of the machine code contained from 09-1E. + +org = $0c00 + + lda $d7 + cmp #$80 + beq skip1 + jsr $ff5f +skip1 lda #$05 + sta $d506 + lda #$4e + sta $ff00 + jmp $0c00 +.end + + The only document I have found which attempts to explain the layout of +the C128 boot sector doesn't fit at all for the above sector layout. I am +therefore not yet sure of all the details in the above sector. Anyone who +has more info can contact me so I can update this document. + diff --git a/Commodore/C64S_FRZ.TXT b/Commodore/C64S_FRZ.TXT new file mode 100644 index 0000000..3280bfa --- /dev/null +++ b/Commodore/C64S_FRZ.TXT @@ -0,0 +1,55 @@ + +*** FRZ (C64s saved-session FRoZen files) +*** Document revision: 1.3 +*** Last updated: March 11, 2004 +*** Compiler/Editor: Peter Schepers +*** Contributors/sources: Miha Peternel + + 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 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" files, +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. + diff --git a/Commodore/CBMFS b/Commodore/CBMFS new file mode 100644 index 0000000..7960c32 --- /dev/null +++ b/Commodore/CBMFS @@ -0,0 +1,779 @@ + + + +CBMFS - Just Solve the File Format Problem + + + + + + + + + + + + + + + + +
+
+ +
+ + + +

+ CBMFS +

+ + +
+ +
From Just Solve the File Format Problem
+ + +
+ + +
+ Jump to: navigation, + search +
+ + +
+ + + + + + + + + + + + + + + + + +
File Format
NameCBMFS
Ontology + + +
+

The CBM File System was used by disk drives made by Commodore Business Machines for the PET, VIC-20, C64 and C128 range of computers. These drives were called 'intelligent peripherals' meaning the DOS (Disk Operating System) was run in the drive itself, not on the computer the drive was attached to. +

The most popular CBM drive was the 1541, which supported 35 tracks using GCR encoding. A later drive, the 1571 disk, used a double-sided format for twice the space. 3 1/2" disks were later introduced to the Commodore via the 1581 format, which used a variant of CBMFS (see Commodore 1581 filesystem). +

+

Contents

+ +
+

D64 File Format

+

The D64 format is most frequently used to capture 1541 disk images, it consists of a sector-for-sector copy of a 1540/1541 disk. 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. +

+

Physical media

+

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 inner 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   Storage in Bytes
+       -----   -------------   ---------   ----------------
+        1-17        21            357           7820
+       18-24        19            133           7170
+       25-30        18            108           6300
+       31-40(*)     17             85           6020
+                                  ---
+                                  683 (for a 35 track image)
+
+
 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
+
+
 (*)Tracks 36-40 apply to 40-track images only
+
+

CBM DOS Directory Structure

+

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, using a sector interleave of 3. This makes the +chain links go 18/1, 18/4, 18/7 etc. +

Note that you can extend the directory off of track 18, but only when +reading the disk or image. Attempting to write to a directory sector not on +track 18 will cause directory corruption. +

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, max. value 254)
+         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
+
+

Files, on a standard 1541, are stored using an interleave of 10. Assuming a +starting track/sector of 17/0, the chain would run 17/0, 17/10, 17/20, +17/8, 17/18, etc. +

Note: No GEOS entries are listed in the above description. See GEOS VLIR 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 ($00), 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, DOLPHIN and ProLogic 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. Any leftover +bits that refer to sectors that don't exist, like bits 21-23 in the above +example, are set to allocated. +

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)
+
+

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. This can also have error bytes attached like variant #1. +

3. The Commodore 128 allowed for "auto-boot" disks. With this, t/s 1/0 +holds a specific byte sequence which the computer recognizes as boot +code. See the document C128BOOT.TXT for more info. +


+Below is a small chart detailing the standard file sizes of D64 images, +35 or 40 tracks, with or without error bytes. +

+
    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
+
+


+The following table (provided by Wolfgang Moser) outlines the differences +between the standard 1541 DOS and the various "speeder" DOS's that exist. +The 'header 7/8' category is the 'fill bytes' as the end of the sector +header of a real 1541 disk See G64 for a better +explanation of these bytes. +

+
       Disk format             |Tracks|Header 7/8|Dos type|DiskDos
+                               |      |allsechdrs|        |vs.type
+      ============================================================
+       Original CBM DOS v2.6   |  35  | $0f  $0f |  "2A"  |$41/'A'
+      ------------------------------------------------------------
+       SpeedDOS+               |  40  | $0f  $0f |  "2A"  |$41/'A'
+      ------------------------------------------------------------
+       ProfessionalDOS Initial |  35  | $0f  $0f |  "2A"  |$41/'A'
+         (Version 1/Prototype) |  40  | $0f  $0f |  "2A"  |$41/'A'
+      ------------------------------------------------------------
+       ProfDOS Release         |  40  | $0f  $0f |  "4A"  |$41/'A'
+      ------------------------------------------------------------
+       Dolphin-DOS 2.0/3.0     |  35  | $0f  $0f |  "2A"  |$41/'A'
+       Dolphin-DOS 2.0/3.0     |  40  | $0d  $0f |  "2A"  |$41/'A'
+      ------------------------------------------------------------
+       PrologicDOS 1541        |  35  | $0f  $0f |  "2A"  |$41/'A'
+       PrologicDOS 1541        |  40  | $0f  $0f |  "2P"  |$50/'P'
+       ProSpeed 1571 2.0       |  35  | $0f  $0f |  "2A"  |$41/'A'
+       ProSpeed 1571 2.0       |  40  | $0f  $0f |  "2P"  |$50/'P'
+      ------------------------------------------------------------
+
+


+The location of the extra BAM information in sector 18/0, for 40 track +images, will be different depending on what standard the disks have been +formatted with. SPEED DOS stores them from $C0 to $D3, DOLPHIN DOS stores +them from $AC to $BF and PrologicDOS stored them right after the existing +BAM entries from $90-A3. PrologicDOS also moves the disk label and ID +forward from the standard location of $90 to $A4. 64COPY and Star Commander +let you select from several different types of extended disk formats you +want to create/work with. +

All three of the speeder DOS's mentioned above don't alter the standard +sector interleave of 10 for files and 3 for directories. The reason is that +they use a memory cache installed in the drive which reads the entire track +in one pass. This alleviates the need for custom interleave values. They do +seem to alter the algorithm that finds the next available free sector so +that the interleave value can deviate from 10 under certain circumstances, +but I don't know why they would bother. +


+Below is a HEX dump of a Speed DOS BAM sector. Note the location of the +extra BAM info from $C0-D3. +

+
       00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F       ASCII
+       -----------------------------------------------  ----------------
+ 0070: 12 FF FF 03 12 FF FF 03 12 FF FF 03 11 FF FF 01  ????????????????
+ 0080: 11 FF FF 01 11 FF FF 01 11 FF FF 01 11 FF FF 01  ????????????????
+ 0090: A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0  ????????????????
+ 00A0: A0 A0 30 30 A0 32 41 A0 A0 A0 A0 00 00 00 00 00  ??00?2A?????????
+ 00B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ????????????????
+ 00C0: 11 FF FF 01 11 FF FF 01 11 FF FF 01 11 FF FF 01  ????????????????
+ 00D0: 11 FF FF 01 00 00 00 00 00 00 00 00 00 00 00 00  ????????????????
+
+


+Below is a HEX dump of a Dolphin DOS BAM sector. Note the location of the +extra BAM info from $AC-BF. +

+
       00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F       ASCII
+       -----------------------------------------------  ----------------
+ 0070: 12 FF FF 03 12 FF FF 03 12 FF FF 03 11 FF FF 01  ????????????????
+ 0080: 11 FF FF 01 11 FF FF 01 11 FF FF 01 11 FF FF 01  ????????????????
+ 0090: A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0  ????????????????
+ 00A0: A0 A0 30 30 A0 32 41 A0 A0 A0 A0 00 11 FF FF 01  ??00?2A?????????
+ 00B0: 11 FF FF 01 11 FF FF 01 11 FF FF 01 11 FF FF 01  ????????????????
+ 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  ???????????????? 
+
+


+Below is a HEX dump of a PrologicDOS BAM sector. Note that the disk name +and ID are now located at $A4 instead of starting at $90. +

+
       00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F       ASCII
+       -----------------------------------------------  ----------------
+ 0070: 12 FF FF 03 12 FF FF 03 12 FF FF 03 11 FF FF 01  ????????????????
+ 0080: 11 FF FF 01 11 FF FF 01 11 FF FF 01 11 FF FF 01  ????????????????
+ 0090: 11 FF FF 01 11 FF FF 01 11 FF FF 01 11 FF FF 01  ????????????????
+ 00A0: 11 FF FF 01 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0  ????????????????
+ 00B0: A0 A0 A0 A0 A0 A0 30 30 A0 32 50 A0 A0 A0 A0 00  ??????00?2P?????
+ 00C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ????????????????
+ 00ED: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ????????????????
+
+


+

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, whether it's searching for any SYNC mark, any header ID, any valid +header, or reading a sector. +

These first errors are "seek" errors, where the disk controller is simply +reading headers and looking at descriptor bytes, checksums, format ID's and +reporting what errors it sees. These errors do *not* necessarily apply to +the exact sector being looked for. This fact makes duplication of these +errors very unreliable. +

+
   Code  Error  Type   1541 error description
+   ----  -----  ----   ------------------------------
+    03    21    Seek   No SYNC sequence found.
+                       Each  sector  data  block  and  header  block   are
+                       preceeded by SYNC marks. If *no* sync  sequence  is
+                       found within 20 milliseconds (only ~1/10 of a  disk
+                       rotation!) then this error is generated. This error
+                       used to mean the entire track is bad, but  it  does
+                       not have to be the case. Only a small area  of  the
+                       track needs to be without  a  SYNC  mark  and  this
+                       error will be generated.
+                       Converting this error to a D64 is very  problematic
+                       because it depends on where the physical head is on
+                       the disk when a read attempt is made. If it  is  on
+                       valid header/sectors then it  won't  occur.  If  it
+                       happens over an area without SYNC  marks,  it  will
+                       happen.
+    02    20    Seek   Header descriptor byte not found (HEX $08, GCR $52)
+                       Each sector is preceeded by an  8-byte  GCR  header
+                       block, which starts with the value  $52  (GCR).  If
+                       this value is not found  after  90  attempts,  this
+                       error is generated.
+                       Basically, what a track  has  is  SYNC  marks,  and
+                       possibly valid data blocks,  but  no  valid  header
+                       descriptors.
+    09    27    Seek   Checksum error in header block
+                       The  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.
+    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
+                       low-level header of 18/0. If there is  a  mismatch,
+                       this error is generated.
+    02    20    Seek   Header block not found
+                       This error can be reported again when searching for
+                       the correct header block. An image of the header is
+                       built and searched for, but not found after 90 read
+                       attempts.  Note  the  difference  from  the   first
+                       occurance. The first one only searches for a  valid
+                       ID, not the whole header.
+
+

Note that error 20 occurs twice during this phase. The first time is when +a header ID is being searched for, the second is when the proper header +pattern for the sector being searched for is not found. +

From this point on, all the errors apply to the specific sector you are +looking for. If a read passed all the previous checks, then we are at the +sector being searched for. +

Note that the entire sector is read before these errors are detected. +Therefore the data, checksum and off bytes are available. +

+
   Code  Error  Type   1541 error description
+   ----  -----  ----   ------------------------------
+    04    22    Read   Data descriptor byte not found (HEX $07, GCR $55)
+                       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.
+    0F    74    Read   Drive Not Ready (no disk in drive or no device 1)
+
+

These errors only apply when writing to a disk. I don't see the +usefulness of having these as they cannot be present when only *reading* a +disk. +

+
   Code  Error  Type   1541 error description
+   ----  -----  ----   ------------------------------
+    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.
+    0A    28    Write  Write error
+                       In actual fact, this error never occurs, but it  is
+                       included for completeness.
+
+

This is not an error at all, but when gets reported when the read of a +sector is ok. +

+
   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.
+
+

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 reasonably robust, 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 files), since you lose the extra 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. +

Preceeding each sector on a real 1541 disk 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. Some +programs fail to work properly since the D64 doesn't contain these ID's. +These bytes would be 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 D64 +is really what it claims to be. In order to determine if a file is a D64, +you must check the file size. +

(Content taken from D64.TXT in Peter Scheper's excellent compendium of C64 file format information). +

+

Utilities

+ + + + + +
+ + + + + +
+ + +
+ +
+ + +
+ + +
+
Personal tools
+ +
+ + +
+ + +
+
Namespaces
+ +
+ + + + +
+

+

+
Variants
+ +
+ + +
+
+ + +
+
Views
+ +
+ + + + +
+
Actions
+ +
+ + + + + + + +
+
+ + + + + + + + + + + + diff --git a/Commodore/CKIT.TXT b/Commodore/CKIT.TXT new file mode 100644 index 0000000..28d6b16 --- /dev/null +++ b/Commodore/CKIT.TXT @@ -0,0 +1,42 @@ + +*** CKIT (Compression KIT compressed files) +*** Document revision: 1.3 +*** Last updated: March 11, 2004 +*** Compiler/Editor: Peter Schepers +*** Contributors/sources: Paul David Doherty, + Todd Elliott + + 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, Commodore 15xx floppy drives). + + The file extension for single disk files (i.e. when a compressed disk +archive only takes up one archive file) is "C4-". If an compressed archive +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 files, 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-0006 - Original Disk ID + 0007-???? - Compressed data + +Any other information on this format would be greatly appreciated. + diff --git a/Commodore/CPK.TXT b/Commodore/CPK.TXT new file mode 100644 index 0000000..ad9b094 --- /dev/null +++ b/Commodore/CPK.TXT @@ -0,0 +1,102 @@ + +*** CPK +*** Document revision: 1.3 +*** Last updated: March 11, 2004 +*** Compiler/Editor: Peter Schepers +*** Contributors/sources: Andre Fachat + + 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 CPK files, 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 a CPK file can be found 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 CPK file very easy. All you have to do as append the +new filename/data to the container. 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 container starting after the first $00. + + In order to extract *one* specific file, you would need to read the whole +file 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. + diff --git a/Commodore/CRT.TXT b/Commodore/CRT.TXT new file mode 100644 index 0000000..aeae902 --- /dev/null +++ b/Commodore/CRT.TXT @@ -0,0 +1,1201 @@ + +*** CRT - CaRTridge Images (from the CCS64 emulator) +*** Document revision: 1.13 +*** Last updated: June 12, 2007 +*** Compiler/Editor: Peter Schepers +*** Contributors/sources: Per Hakan Sundell, + Markus Brenner + Marco Van Den Heuvel + + 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 various ROM cartridges that exist, such as Action Replay, the +Power cartridge, and the Final Cartridge. + + Normal game cartridges can load into several different memory ranges +($8000-9FFF, $A000-BFFF or $E000-FFFF). Newer utility and freezer +cartridges were less intrusive, hiding themselves until called upon, and +still others used bank-switching techniques to allow much larger ROM's than +normal. Because of these "stealthing" and bank-switching methods, a special +cartridge format was necessary, to let the emulator know where the +cartridge should reside, the control line states to enable it and any +special hardware features it uses. + + Here is a dump of a sample 8K normal cartridge, "Attack Of The Mutant +Camels"... + + 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 40 01 00 00 00 00 01 00 00 00 00 00 00 @ +0020: 41 54 54 41 43 4B 20 4F 46 20 54 48 45 20 4D 55 ATTACKOFTHEMU +0030: 54 41 4E 54 20 43 41 4D 45 4C 53 00 00 00 00 00 TANTCAMELS +0040: 43 48 49 50 00 00 20 10 00 00 00 00 80 00 20 00 CHIP +0050: D3 9B BC FE C3 C2 CD 38 30 EA EA EA A9 01 85 13 ӛ80 +0060: 4C B3 9B A9 08 85 5A 88 D0 FD C6 5A D0 F9 60 D0 LZZ` + + Bytes:$0000-000F - 16-byte cartridge signature "C64 CARTRIDGE" (padded + with space characters) + 0010-0013 - File header length ($00000040, in high/low format, + calculated from offset $0000). The default (also the + minimum) value is $40. Some cartridges exist which + show a value of $00000020 which is wrong. + 0014-0015 - Cartridge version (high/low, presently 01.00) + 0016-0017 - Cartridge hardware type ($0000, high/low) + 0 - Normal cartridge + 1 - Action Replay + 2 - KCS Power Cartridge + 3 - Final Cartridge III + 4 - Simons Basic + 5 - Ocean type 1* + 6 - Expert Cartridge + 7 - Fun Play, Power Play + 8 - Super Games + 9 - Atomic Power + 10 - Epyx Fastload + 11 - Westermann Learning + 12 - Rex Utility + 13 - Final Cartridge I + 14 - Magic Formel + 15 - C64 Game System, System 3 + 16 - WarpSpeed + 17 - Dinamic** + 18 - Zaxxon, Super Zaxxon (SEGA) + 19 - Magic Desk, Domark, HES Australia + 20 - Super Snapshot 5 + 21 - Comal-80 + 22 - Structured Basic + 23 - Ross + 24 - Dela EP64 + 25 - Dela EP7x8 + 26 - Dela EP256 + 27 - Rex EP256 + 0018 - Cartridge port EXROM line status + 0 - inactive + 1 - active + 0019 - Cartridge port GAME line status + 0 - inactive + 1 - active + 001A-001F - Reserved for future use + 0020-003F - 32-byte cartridge name "CCSMON" (uppercase, padded + with null characters) + 0040-xxxx - Cartridge contents (called CHIP PACKETS, as there can + be more than one per CRT file). See below for a + breakdown of the CHIP format. + + (*Note: Ocean type 1 includes Navy Seals, Robocop 2 & 3, Shadow of the + Beast, Toki, Terminator 2 and more) + + (**Note: Dinamic includes Narco Police and more) + + +--------------------------------------------------------------------------- + + +CHIP Contents +------------- + + The following is the contents of the CHIP packet, from position $0040 on +in the CRT file. 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: D3 9B BC FE C3 C2 CD 38 30 EA EA EA A9 01 85 13 ӛ80 +0020: 4C B3 9B A9 08 85 5A 88 D0 FD C6 5A D0 F9 60 D0 LZZ` +0030: F2 60 A9 04 85 49 A9 00 85 48 A2 00 A5 48 9D 40 `IHH@ +0040: 03 A5 49 9D 60 03 A5 48 18 69 28 85 48 A5 49 69 I`Hi(HIi +0050: 00 85 49 E8 E0 18 D0 E4 60 A6 03 A4 02 BD 40 03 I`@ + + Bytes:$0000-0003 - Contained ROM 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) (high/low format) + 0008-0009 - Chip type + 0 - ROM + 1 - RAM, no ROM data + 2 - Flash ROM + 000A-000B - Bank number ($0000 - normal cartridge) + 000C-000D - Starting load address (high/low format) + 000E-000F - ROM image size in bytes (high/low format, typically + $2000 or $4000) + 0010-xxxx - ROM data + + +--------------------------------------------------------------------------- + + + The following is a chart taken from the "Commodore Programmers Reference +Guide". It details the state of various areas of memory depending on the +state of the control lines. + + +Legend: +L - ROML (low) +H - ROMH (high) +G - GAME +E - EXROM + +Addr LHGE LHGE LHGE LHGE LHGE LHGE LHGE LHGE LHGE +Range + 1111 101X 1000 011X 001X 1110 0100 1100 XX01 + default 00X0 Ultimax +------------------------------------------------------------------------- +E000-FFFF Kernal RAM RAM Kernal RAM Kernal Kernal Kernal ROMH(*) +D000-DFFF IO/CHR IO/CHR IO/RAM IO/CHR RAM IO/CHR IO/CHR IO/CHR I/O +C000-CFFF RAM RAM RAM RAM RAM RAM RAM RAM - +A000-BFFF BASIC RAM RAM RAM RAM BASIC ROMH ROMH - +8000-9FFF RAM RAM RAM RAM RAM ROML RAM ROML ROML(*) +4000-7FFF RAM RAM RAM RAM RAM RAM RAM RAM - +1000-3FFF RAM RAM RAM RAM RAM RAM RAM RAM - +0000-0FFF RAM RAM RAM RAM RAM RAM RAM RAM RAM + +(*) Internal memory does not respond to write accesses in these areas + + + From the above chart, the following table can be built. It shows standard +cartridges, either 8K or 16K in size, and the memory ranges they load into. + +Type Size Game EXRom Low Bank High Bank + in K Line Line (ROML) (ROMH) +------------------------------------------------- +Normal 8k hi lo $8000 ---- +Normal 16k lo lo $8000 $A000 +Ultimax 8k lo hi $E000 ---- + + The ROMH and ROML lines are CPU-controlled status lines, used to bank +in/out RAM, ROM or I/O, depending on what is needed at the time. + + Ultimax cartridges typically are situated in the $E000-FFFF (8K) ROM +address range. There are some cartridges which only use 4K of the 8K +allocation. If the cartridge is 16K in size, then it will reside in both +$8000-9FFF and $E000-FFFF. + + +--------------------------------------------------------------------------- + + +Cartridge Specifics +------------------- + +0 - Normal cartridge + + Size - 8Kb + GAME - active (1) + EXROM - inactive (0) + Load address - $8000-9FFF + + 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 40 01 00 00 00 00 01 00 00 00 00 00 00 @ +0020: 41 54 54 41 43 4B 20 4F 46 20 54 48 45 20 4D 55 ATTACKOFTHEMU +0030: 54 41 4E 54 20 43 41 4D 45 4C 53 00 00 00 00 00 TANTCAMELS +0040: 43 48 49 50 00 00 20 10 00 00 00 00 80 00 20 00 CHIP +0050: D3 9B BC FE C3 C2 CD 38 30 EA EA EA A9 01 85 13 ӛ80 + + + The second sample below is a dump of "Music Machine", a 4Kb ULTIMAX + mode cartridge. It is still identified as a "standard cartridge" + according to the ID. + + Normal cartridge + + Size - 4Kb (ULTIMAX mode) + GAME - inactive (0) + EXROM - active (1) + Load address - $F000-F7FF + + 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 40 01 00 00 00 01 00 00 00 00 00 00 00 @ +0020: 4D 55 53 49 43 20 4D 41 43 48 49 4E 45 00 00 00 MUSICMACHINE +0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0040: 43 48 49 50 00 00 10 10 00 00 00 00 F0 00 10 00 CHIP +0050: 3C 66 C3 C3 66 3C FF FF 18 3C 66 7E 66 66 66 00 Bank 0 + $08 -> Bank 1 + $10 -> Bank 2 + $18 -> Bank 3 + $20 -> Bank 4 + $28 -> Bank 5 + $30 -> Bank 6 + $38 -> Bank 7 + $01 -> Bank 8 + $09 -> Bank 9 + $11 -> Bank 10 + $19 -> Bank 11 + $21 -> Bank 12 + $29 -> Bank 13 + $31 -> Bank 14 + $39 -> Bank 15 + + The bank field in the chip headers is set according to the value + written to $DE00. The following bits are used for bank decoding in + $DE00 (0 being the LSB, 3 being the MSB). + + Bit# 76543210 + xx210xx3 + + After copying memory from the ROM banks, the selection program writes + a value of $86 to $DE00. This seems either to reset or disable the + cartridge ROM. + + +=========================================================================== + + +8 - Super Games + + Size - 64Kb (4 banks of 16Kb each) + GAME - inactive (0) + EXROM - inactive (0) + Load address - $8000-BFFF (all modules) + + 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 40 01 00 00 08 00 00 00 00 00 00 00 00 @ +0020: 53 55 50 45 52 20 47 41 4D 45 53 00 00 00 00 00 SUPERGAMES +0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0040: 43 48 49 50 00 00 40 10 00 00 00 00 80 00 40 00 CHIP@@ +0050: 0A 80 0A 80 C3 C2 CD 38 30 00 A9 80 A0 00 85 FB 80 +.... +4050: 43 48 49 50 00 00 40 10 00 00 00 01 80 00 40 00 CHIP@@ +4060: 27 80 A8 80 C3 C2 CD 38 30 00 40 C0 40 C0 40 C0 '80@@@ +.... +8060: 43 48 49 50 00 00 40 10 00 00 00 02 80 00 40 00 CHIP@@ +8070: 00 00 00 49 4D C7 64 47 46 45 F3 48 DC 08 7E 0B IMdGFEH~ +.... +C070: 43 48 49 50 00 00 40 10 00 00 00 03 80 00 40 00 CHIP@@ +C080: D5 F9 F0 C1 D5 F7 F0 BD E8 B5 02 F0 FB C9 05 30 0 + + The SUPER GAMES cartridge uses 4 16Kb banks ($8000-$BFFF) of ROM + memory. Bank selecting is done by writing to $DF00. + + Values for $DF00: + + $00 -> Bank 0 + $01 -> Bank 1 (also value $09 used) + $02 -> Bank 2 + $03 -> Bank 3 + + Bit #2 + 0: ROM $8000-$BFFF + 1: ROM $8000-$9FFF + Bit #3 + 0: ? + 1: if bit #2 AND #3 are on (1) then the module is off + + +=========================================================================== + + +9 - Atomic Power + + Size - 32Kb (4 banks of 8Kb modules) + GAME - inactive (0) + EXROM - inactive (0) + Load address - $8000-9FFF (all modules) + + 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 40 01 00 00 09 00 00 00 00 00 00 00 00 @ +0020: 41 74 6F 6D 69 63 20 50 6F 77 65 72 00 00 00 00 AtomicPower +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 +0050: 09 80 0C 80 C3 C2 CD 38 30 4C 41 80 4C 1E 80 4C 80LALL +.... +2050: 43 48 49 50 00 00 20 10 00 00 00 01 80 00 20 00 CHIP +2060: 09 80 0C 80 C3 C2 CD 38 30 4C 3F 80 4C 91 80 4C 80L?LL +.... +4060: 43 48 49 50 00 00 20 10 00 00 00 02 80 00 20 00 CHIP +4070: EF FC 09 80 C3 C2 CD 38 30 4C 27 80 4C DB 81 4C 80L'LہL +.... +6070: 43 48 49 50 00 00 20 10 00 00 00 03 80 00 20 00 CHIP +6080: 09 80 0C 80 C3 C2 CD 38 30 4C 73 86 4C 30 80 4C 80LsL0L + + +=========================================================================== + + +10 - Epyx Fastload + + Size - 8Kb + GAME - active (1) + EXROM - active (1) + Load address - $8000-9FFF + + 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 40 01 00 00 0A 01 01 00 00 00 00 00 00 @ +0020: 45 50 59 58 20 46 41 53 54 4C 4F 41 44 00 00 00 EPYXFASTLOAD +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 +0050: 30 80 5E FE C3 C2 CD 38 30 20 04 90 4C 38 DF AB 0^80L8߫ + + +=========================================================================== + + +11 - Westermann Learning + + Size - 16Kb + GAME - inactive (0) + EXROM - inactive (0) + Load address - $8000-BFFF + + 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 40 01 00 00 0B 00 00 00 00 00 00 00 00 @ +0020: 57 45 53 54 45 52 4D 41 4E 4E 00 00 00 00 00 00 WESTERMANN +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 40 00 CHIP@ +0050: 09 80 9C 80 C3 C2 CD 38 30 A2 00 8E 16 D0 20 84 80 + + +=========================================================================== + + +12 - Rex Utility + + Size - 8K + GAME - active (1) + EXROM - inactive (0) + Load address - $8000-9FFF + + 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 40 01 00 00 0C 00 01 00 00 00 00 00 00 @ +0020: 52 45 58 00 00 00 00 00 00 00 00 00 00 00 00 00 REX +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 +0050: 08 80 C1 FE C3 C2 CD 38 30 6C 95 E3 20 A3 FD 20 80l + + +=========================================================================== + + +13 - Final Cartridge I + + Size - 16Kb + GAME - active (1) + EXROM - active (1) + Load address - $8000-BFFF + + 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 40 01 00 00 0D 01 01 00 00 00 00 00 00 @ +0020: 54 68 65 20 46 69 6E 61 6C 20 43 61 72 74 72 69 TheFinalCartri +0030: 64 67 65 20 49 00 00 00 00 00 00 00 00 00 00 00 dgeI +0040: 43 48 49 50 00 00 40 10 00 00 00 00 80 00 40 00 CHIP@@ +0050: 80 BA 5E FE C3 C2 CD 38 30 00 A0 A0 20 2D FE 58 ^80-X + + +=========================================================================== + + +14 - Magic Formel + + Size - 64Kb (8 banks of 8Kb) + GAME - Inactive (0) + EXROM - Inactive (0) + Load Address - $E000-FFFF + + 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 40 01 00 00 0E 01 01 00 00 00 00 00 00 @ +0020: 4D 61 67 69 63 20 46 6F 72 6D 65 6C 00 00 00 00 MagicFormel +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 E0 00 20 00 CHIP +0050: 4D 46 30 8D 00 DF 60 8D 01 DF 60 8D 02 DF 60 8D MF0``` +... +2050: 43 48 49 50 00 00 20 10 00 00 00 01 E0 00 20 00 CHIP +2060: 4C 5F E4 8D 00 DF 60 8D 01 DF 60 8D 02 DF 60 8D L_``` +... +4060: 43 48 49 50 00 00 20 10 00 00 00 02 E0 00 20 00 CHIP +4070: 4D 46 32 8D 00 DF 60 8D 01 DF 60 8D 02 DF 60 8D MF2``` +... +6070: 43 48 49 50 00 00 20 10 00 00 00 03 E0 00 20 00 CHIP +6080: 4D 46 33 8D 00 DF 60 8D 01 DF 60 8D 02 DF 60 8D MF3``` +... +8080: 43 48 49 50 00 00 20 10 00 00 00 04 E0 00 20 00 CHIP +8090: 4D 46 34 8D 00 DF 60 8D 01 DF 60 8D 02 DF 60 8D MF4``` +... +A090: 43 48 49 50 00 00 20 10 00 00 00 05 E0 00 20 00 CHIP +A0A0: 4D 46 35 8D 00 DF 60 8D 01 DF 60 8D 02 DF 60 8D MF5``` +... +C0A0: 43 48 49 50 00 00 20 10 00 00 00 06 E0 00 20 00 CHIP +C0B0: 4D 46 36 8D 00 DF 60 8D 01 DF 60 8D 02 DF 60 8D MF6``` +.. +E0B0: 43 48 49 50 00 00 20 10 00 00 00 07 E0 00 20 00 CHIP +E0C0: 4D 46 37 8D 00 DF 60 8D 01 DF 60 8D 02 DF 60 8D MF7``` + + +=========================================================================== + + +15 - C64 Game System, System 3 + + Size - 512Kb (64 banks of 8Kb each) + GAME - inactive (0) + EXROM - active (1) + Load address - $8000-9FFF (all modules) + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +000000: 43 36 34 20 43 41 52 54 52 49 44 47 45 20 20 20 C64CARTRIDGE +000010: 00 00 00 40 01 00 00 0F 00 01 00 00 00 00 00 00 @ +000020: 43 36 34 47 53 20 43 61 72 74 72 69 64 67 65 00 C64GSCartridge +000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +000040: 43 48 49 50 00 00 20 10 00 00 00 00 80 00 20 00 CHIP +000050: 6D 80 C5 80 C3 C2 CD 38 30 4C CB 80 4C 36 84 4C mŀ80LˀL6L +.... +002050: 43 48 49 50 00 00 20 10 00 00 00 01 80 00 20 00 CHIP +002060: 18 D0 A9 FF 8D 15 D0 8D 1D D0 8D 17 D0 A2 07 A9 ЩЍЍТ +.... +004060: 43 48 49 50 00 00 20 10 00 00 00 02 80 00 20 00 CHIP +004070: E0 08 19 21 77 84 52 98 9F 80 A5 21 31 01 31 89 !wR!11 +.... +006070: 43 48 49 50 00 00 20 10 00 00 00 03 80 00 20 00 CHIP +006080: C0 08 1C 1D A0 92 03 03 D8 AA 04 C0 B8 01 40 EA ت@ +.... +07E430: 43 48 49 50 00 00 20 10 00 00 00 3F 80 00 20 00 CHIP? +07E440: 45 20 41 20 42 49 47 20 58 FE 4F 4E 20 54 48 49 EABIGXONTHI + + Here is a list of the known cartridges: + + C64GS 4-in-1 (Commodore) (512 kB) + Last Ninja Remix (System 3) (512 kB) + Myth (System 3) (512 kB) + + ROM memory is organized in 8Kb ($2000) banks located at $8000-$9FFF. + Bank switching is done by writing to address $DE00+X, where X is the + bank number (STA $DE00,X). For instance, to read from bank 3, address + $DE03 is accessed. + + The CRT file contains a string of CHIP blocks, each block with a start + address of $8000, length $2000 and the bank number in the bank field. + In the cartridge header, EXROM ($18) is set to 0, GAME ($19) is set to + 1 to enable the 8 kB ROM configuration. + + +=========================================================================== + + +16 - WarpSpeed + + Size - 16Kb + GAME - inactive (0) + EXROM - inactive (0) + Load address - $8000-BFFF + + 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 40 01 00 00 10 01 01 00 00 00 00 00 00 @ +0020: 57 61 72 70 73 70 65 65 64 00 00 00 00 00 00 00 Warpspeed +0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0040: 43 48 49 50 00 00 40 10 00 00 00 00 80 00 40 00 CHIP@@ +0050: 4C 22 80 4C 22 80 FF 43 42 4D 20 53 E4 20 18 E5 L"L"CBMS + + After RESET or POWER ON, 16kB of Cartridge ROM are visible at + $8000-$BFFF. Additionally, ROM normally located at $9E00-$9FFF is + mirrored into IO1 and IO2 at $DE00-$DFFF. ROM at $8000-$BFFF is + disabled by writing into the IO2 area (typically $DF00) and may be + re-enabled by writing into IO1 ($DE00). However, the $DE00-$DFFF + (IO1/IO2) area itself always remains mapped to cartridge ROM. + + Included with these documents is a WRPSPEED.JPG which is the schematic + of the WarpSpeed cartridge itself. + + +=========================================================================== + + +17 - Dinamic + + Size - 128Kb (16 banks of 8Kb each) + GAME - inactive (0) + EXROM - active (1) + Load address - $8000-9FFF (all modules) + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +000000: 43 36 34 20 43 41 52 54 52 49 44 47 45 20 20 20 C64CARTRIDGE +000010: 00 00 00 40 01 00 00 11 00 01 00 00 00 00 00 00 @ +000020: 4E 61 72 63 6F 20 50 6F 6C 69 63 65 00 00 00 00 NarcoPolice +000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +000040: 43 48 49 50 00 00 20 10 00 00 00 00 80 00 20 00 CHIP +000050: 0B 80 0B 80 C3 C2 CD 38 30 00 00 78 A2 FF 9A D8 80x +.. +002050: 43 48 49 50 00 00 20 10 00 00 00 01 80 00 20 00 CHIP +002060: 1C 8C 1B 8C 16 16 8F 16 16 88 1C 1C 86 1C 1C 89 +.. +004060: 43 48 49 50 00 00 20 10 00 00 00 02 80 00 20 00 CHIP +004070: B6 02 07 08 07 07 00 0A 0A B6 00 05 0A 00 07 07 +.. +01E130: 43 48 49 50 00 00 20 10 00 00 00 0F 80 00 20 00 CHIP +01E140: 00 D5 70 03 F5 70 0F 5F 70 0F F7 70 35 FD F0 37 pp_pp57 + + Here is a list of the known DINAMIC cartridges: + + Narco Police (128 kB) + Satan (128 kB) + + ROM memory is organized in 8Kb ($2000) banks located at $8000-$9FFF. + Bank switching is done by reading from address $DE00+X, where X is the + bank number (LDA $DE00,X). For instance, to read from bank 3, address + $DE03 is accessed. + + The CRT file contains a string of CHIP blocks, each block with a start + address of $8000, length $2000 and the bank number in the bank field. + In the cartridge header, EXROM ($18) is set to 0, GAME ($19) is set to + 1 to enable the 8 kB ROM configuration. + + +=========================================================================== + + +18 - Zaxxon, Super Zaxxon (SEGA) + + Size - 20Kb (3 banks of different sizes) + GAME - active (1) + EXROM - active (1) + Load address - $8000-8FFF (mirrored in $9000-9FFF, module 0, chip U1) + $A000-BFFF (banked modules 1 and 2, chip U2) + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +000000: 43 36 34 20 43 41 52 54 52 49 44 47 45 20 20 20 C64CARTRIDGE +000010: 00 00 00 40 01 00 00 12 00 00 00 00 00 00 00 00 @ +000020: 5A 61 78 78 6F 6E 00 00 00 00 00 00 00 00 00 00 Zaxxon +000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +000040: 43 48 49 50 00 00 10 10 00 00 00 00 80 00 10 00 CHIP +000050: 0D 80 29 80 C3 C2 CD 38 30 78 4C 09 80 78 A9 00 )80xLx +.. +001050: 43 48 49 50 00 00 20 10 00 00 00 00 A0 00 20 00 CHIP +001060: A2 0F BD 00 20 D0 04 CA 10 F8 60 BD 70 20 F0 0D `p +.. +003060: 43 48 49 50 00 00 20 10 00 00 00 01 A0 00 20 00 CHIP +003070: 65 A2 36 A3 E7 A3 CB A4 94 A5 86 A6 5E A7 35 A8 e6ˤ^5 + + The (Super) Zaxxon carts use a 4Kb ($1000) ROM at $8000-$8FFF (mirrored + in $9000-$9FFF) along with two 8Kb ($2000) cartridge banks located at + $A000-$BFFF. One of the two banks is selected by doing a read access to + either the $8000-$8FFF area (bank 0 is selected) or to $9000-$9FFF area + (bank 1 is selected). EXROM ($18 = $00) and GAME ($19 = $00) lines are + always pulled to GND to select the 16 kB ROM configuration. + + The CRT file includes three CHIP blocks: + a) bank = 0, load address = $8000, size = $1000 + b) bank = 0, load address = $A000, size = $2000 + c) bank = 1, load address = $A000, size = $2000 + + +=========================================================================== + + +19. Magic Desk, Domark, HES Australia + + Size - 32Kb, 64Kb or 128Kb sizes (4 to 16 banks of 8Kb each) + GAME - inactive (0) + EXROM - active (1) + Load address (banks 00-15) - $8000-9FFF + + 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 40 01 00 00 13 00 01 00 00 00 00 00 00 @ +0020: 4D 61 67 69 63 20 44 65 73 6B 00 00 00 00 00 00 MagicDesk +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 +0050: 09 80 C6 CA C3 C2 CD 38 30 8E 16 D0 20 A3 FD 20 80 +.. +2050: 43 48 49 50 00 00 20 10 00 00 00 01 80 00 20 00 CHIP +2060: 00 3F 0A 01 00 86 4E 24 28 31 30 29 3A 4A 4F 59 ?N$(10):JOY +.. +4060: 43 48 49 50 00 00 20 10 00 00 00 02 80 00 20 00 CHIP +4070: 00 8B C9 28 4E 24 2C 31 29 B3 B1 22 FF 22 A7 32 (N$,1)""2 +.. +6070: 43 48 49 50 00 00 20 10 00 00 00 03 80 00 20 00 CHIP +6080: AE 01 83 33 2C 37 2C 22 32 29 20 44 45 4C 20 4B 3,7,"2)DELK + + This cartridge type is very similar to the OCEAN cart type: ROM memory + is organized in 8Kb ($2000) banks located at $8000-$9FFF. Bank + switching is done by writing the bank number to $DE00. Deviant from the + Ocean type, bit 8 is cleared for selecting one of the ROM banks. If bit + 8 is set ($DE00 = $80), the GAME/EXROM lines are disabled, turning on + RAM at $8000-$9FFF instead of ROM. + + In the cartridge header, EXROM ($18) is set to 0, GAME ($19) is set to + 1 to indicate the RESET/power-up configuration of 8 kB ROM. + + Here is a list of the known cartridges: + + Ghosbusters (HES Australia) (32 kB) + Magic Desk (Commodore) (32 kB) + Badlands (Domark) (64 kB) + Vindicators (Domark) (64 kB) + Wonderboy (HES Australia) (64 kB) + Cyberball (Domark) (128 kB) + + +=========================================================================== + + +20. Super Snapshot 5 + + Size - 64Kb (4 banks of 16Kb each) + GAME - active (1) + EXROM - active (1) + Load address - $8000-BFFF + + 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 40 01 00 00 14 01 01 00 00 00 00 00 00 @ +0020: 53 75 70 65 72 20 53 6E 61 70 73 68 6F 74 20 35 SuperSnapshot5 +0030: 20 4E 54 53 43 00 00 00 00 00 00 00 00 00 00 00 NTSC +0040: 43 48 49 50 00 00 40 10 00 00 00 00 80 00 40 00 CHIP@@ +0050: 09 80 59 80 C3 C2 CD 38 30 20 03 9F 00 FA F4 20 Y80 +... +4050: 43 48 49 50 00 00 40 10 00 00 00 01 80 00 40 00 CHIP@@ +4060: 79 DE BC FE C3 C2 CD 38 30 A9 05 8D 20 D0 8D 21 y޼80Ѝ! +... +8060: 43 48 49 50 00 00 40 10 00 00 00 02 80 00 40 00 CHIP@@ +8070: 50 DE BC FE C3 C2 CD 38 30 A9 0A 85 6A A9 0D 85 P޼80j +... +C070: 43 48 49 50 00 00 40 10 00 00 00 03 80 00 40 00 CHIP@@ +C080: 50 DE BC FE C3 C2 CD 38 30 85 07 20 1A AD A5 76 P޼80v + + +=========================================================================== + + +21. Comal-80 + + Size - 64Kb (4 banks of 16Kb each) + GAME - active (1) + EXROM - active (1) + Load address - $8000-BFFF + + 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 40 01 00 00 15 01 01 00 00 00 00 00 00 @ +0020: 43 6F 6D 61 6C 20 38 30 00 00 00 00 00 00 00 00 Comal80 +0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0040: 43 48 49 50 00 00 40 10 00 00 00 00 80 00 40 00 CHIP@@ +0050: 87 87 70 CF C3 C2 CD 38 30 4C AA CF 4C 70 CF 4C p80LLpL +... +4050: 43 48 49 50 00 00 40 10 00 00 00 01 80 00 40 00 CHIP@@ +4060: AA CF 70 CF C3 C2 CD 38 30 01 29 01 28 01 2C 04 p80)(, +... +8060: 43 48 49 50 00 00 40 10 00 00 00 02 80 00 40 00 CHIP@@ +8070: AA CF 70 CF C3 C2 CD 38 30 91 92 92 92 92 92 92 p80 +... +C070: 43 48 49 50 00 00 40 10 00 00 00 03 80 00 40 00 CHIP@@ +C080: 7B C8 7E C8 C3 C2 CD 38 30 43 4F 4D 41 4C 80 93 {~80COMAL + + + The Comal-80 Cartridge uses $DE00 for bank selection, and uses 16Kb + banks ($4000) at $8000-$BFFF. There are 4 banks of ROM memory and are + referenced by the following values: + + $80 -> Bank 0 + $81 -> Bank 1 + $82 -> Bank 2 + $83 -> Bank 3 + + +=========================================================================== + + +22. Structured Basic + + Size - 16Kb (2 banks of 8Kb each) + GAME - active (0) + EXROM - active (1) + Load address - $8000-9FFF + + No sample data/file available. + + Any read/write access to $DE00 or $DE01 will switch in bank 0. + Any read/write access to $DE02 will switch in bank 1. + Any read/write access to $DE03 will switch off EXROM. + + +=========================================================================== + + +23. Ross + + Size - 16Kb or 32Kb sizes (1 or 2 banks of 16Kb each) + GAME - active (1) + EXROM - active (1) + Load address - $8000-BFFF + + 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 40 01 00 00 17 00 00 00 00 00 00 00 00 @ +0020: 52 6F 73 73 20 31 34 00 00 00 00 00 00 00 00 00 Ross14 +0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0040: 43 48 49 50 00 00 40 10 00 00 00 00 80 00 40 00 CHIP@@ +0050: 09 80 09 80 C3 C2 CD 38 30 A2 00 BD 20 80 4D 0E 80M +... +4050: 43 48 49 50 00 00 40 10 00 00 00 01 80 00 40 00 CHIP@@ +4060: 3F 5A 4D 4D 50 4D 8D 25 3F 1A 1F 77 3F CD E0 3F ?ZMMPM%?w?? + + Any read access to $DE00 will switch in bank 1 (if cart is 32Kb). + Any read access to $DF00 will switch off EXROM and GAME. + + +=========================================================================== + + +24. Dela EP64 + + Size - 8Kb to 72kb sizes (1 to 9 banks of 8Kb each, + or 1 bank of 8Kb and 1 or 2 banks + of 32Kb each) + GAME - inactive (0) + EXROM - active (1) + Load address - $8000-9FFF + + 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 40 01 00 00 18 00 01 00 00 00 00 00 00 @ +0020: 44 45 4C 41 20 45 50 36 34 00 00 00 00 00 00 00 DELAEP64 +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 +0050: 00 85 5E FE C3 C2 CD 38 30 FF FF FF FF FF FF FF ^80 +... +2050: 43 48 49 50 00 00 80 10 00 00 00 01 80 00 80 00 CHIP +2060: 54 45 53 54 0D 2A 0D 54 45 20 36 34 0D 00 00 00 TEST*TE64 + + This is an eprom cartridge. It has 1 2764 (8Kb) which holds the base + eprom with the base menu, and 2 27256 eproms of which 8Kb parts are + banked into the $8000-9FFF area. + + The bank selecting is done by writing to $DE00. The following bits are + used for bank decoding in $DE00 (0 being the LSB, 3 being the MSB). + + Bit# 76543210 + xx10xx32 + + Any bank value below 4 or above 11 switches in the base bank (bank 0). + + The bit values for each eprom bank are : + + eprom bank 1 : xx00xx01 + eprom bank 2 : xx01xx01 + eprom bank 3 : xx10xx01 + eprom bank 4 : xx11xx01 + eprom bank 5 : xx00xx10 + eprom bank 6 : xx01xx10 + eprom bank 7 : xx10xx10 + eprom bank 8 : xx11xx10 + + Setting bit 7 high will switch off EXROM. + + +========================================================================== + + +25. Dela EP7x8 + + Size - 8Kb to 64kb sizes (1 to 8 banks of 8Kb each) + GAME - inactive (0) + EXROM - active (1) + Load address - $8000-9FFF + + 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 40 01 00 00 19 00 01 00 00 00 00 00 00 @ +0020: 44 45 4C 41 20 45 50 37 78 38 00 00 00 00 00 00 DELAEP7x8 +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 +0050: 09 80 5E FE C3 C2 CD 38 30 78 A2 FF 9A D8 8E 16 ^80x؎ +... +2050: 43 48 49 50 00 00 20 10 00 00 00 01 80 00 20 00 CHIP +2060: 94 83 A0 83 C3 C2 CD 38 30 02 BB 5A 30 5F EE 3D 80Z0_= + + This is an eprom cartridge. It has 8 8Kb banks of which the first holds + the base menu, the other eproms can be banked into the $8000-9FFF area. + + The bank selecting is done by writing to $DE00. Each low bit is used to + bank in the respective eprom. If all bits are high then the EXROM is + switched off. + + The bit values for each eprom bank is: + + eprom bank 1 : 11111110 ($FE) (base eprom) + eprom bank 2 : 11111101 ($FD) + eprom bank 3 : 11111011 ($FB) + eprom bank 4 : 11110111 ($F7) + eprom bank 5 : 11101111 ($EF) + eprom bank 6 : 11011111 ($DF) + eprom bank 7 : 10111111 ($BF) + eprom bank 8 : 01111111 ($7F) + + EXROM off : 11111111 ($FF) + + +========================================================================== + + +26. Dela EP256 + + Size - 8Kb to 262kb sizes (1 to 33 banks of 8Kb each) + GAME - inactive (0) + EXROM - active (1) + Load address - $8000-9FFF + + 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 40 01 00 00 1A 00 01 00 00 00 00 00 00 @ +0020: 44 45 4C 41 20 45 50 32 35 36 00 00 00 00 00 00 DELAEP256 +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 +0050: 00 85 5E FE C3 C2 CD 38 30 93 0D 2B 2B 2B 20 45 ^80+++E +... +2050: 43 48 49 50 00 00 20 10 00 00 00 01 80 00 20 00 CHIP +2060: 09 80 28 80 C3 C2 CD 38 30 78 A2 05 8E 16 D0 20 (80x +... +4060: 43 48 49 50 00 00 20 10 00 00 00 02 80 00 20 00 CHIP +4070: 0B 80 BC FE C3 C2 CD 38 30 DC 10 8E 16 D0 20 87 80 +... +6070: 43 48 49 50 00 00 20 10 00 00 00 03 80 00 20 00 CHIP +6080: 09 80 F6 8E C3 C2 CD 38 30 A2 C8 8E 16 D0 20 .. 80Ȏ. +... +8080: 43 48 49 50 00 00 20 10 00 00 00 04 80 00 20 00 CHIP +8090: 94 83 A0 83 C3 C2 CD 38 30 02 BB 5A 30 5F EE 3D 80Z0_= + + This is an eprom cartridge. It has 33 8Kb banks of which the first + holds the base menu, the other eproms can be banked into the $8000-9FFF + area. + + The bank selecting is done by writing to $DE00. + + The values for the (extra) eprom banks are: + + eprom banks 1- 8 : $38-3F + eprom banks 9-16 : $28-2F + eprom banks 17-24 : $18-1F + eprom banks 25-32 : $08-0F + + Setting bit 7 high will switch off EXROM. + + +========================================================================== + + +27. Rex EP256 + + Size - 8Kb to 262kb sizes (1 bank of 8Kb and 1 to 8 banks of either + 8Kb, 16Kb or 32Kb) + GAME - inactive (0) + EXROM - active (1) + Load address - $8000-9FFF + + 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 40 01 00 00 1B 00 01 00 00 00 00 00 00 @ +0020: 52 45 58 20 45 50 32 35 36 00 00 00 00 00 00 00 REXEP256 +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 +0050: 09 80 C1 FE C3 C2 CD 38 30 20 A3 FD 20 50 FD 20 80P +... +2050: 43 48 49 50 00 00 20 10 00 00 00 01 80 00 20 00 CHIP +2060: 09 80 F2 8F C3 C2 CD 38 30 A2 C8 8E 16 D0 20 A3 80Ȏ +... +4060: 43 48 49 50 00 00 40 10 00 00 00 02 80 00 40 00 CHIP@@ +4070: 09 80 09 80 C3 C2 CD 38 30 58 D8 20 84 FF 20 8A 80X + + This is an eprom cartridge. It has 9 eprom sockets, of which the first + holds the base eprom with the base menu which is an 8Kb eprom, the + other eprom sockets can handle 8Kb, 16Kb or 32Kb eproms, of which 8kb + can be banked into the $8000-9FFF area. + + The bank selecting is done by writing to $DFA0. Bits 2, 1 and 0 + determine which socket is used and bits 5 and 4 are used to select an + 8Kb piece of the eprom. + + The possible values for bits 5 and 4 for the (extra) eprom banks are: + + 8Kb : 3, 2, 1, 0 + + 16Kb bank 0 : 2, 0 + 16Kb bank 1 : 3, 1 + + 32Kb bank 0 : 0 + 32Kb bank 1 : 1 + 32Kb bank 2 : 2 + 32Kb bank 3 : 3 + + Reading from $DFC0 switches off the EXROM. + Reading from $DFE0 switches on the EXROM. + + diff --git a/Commodore/CVT.TXT b/Commodore/CVT.TXT new file mode 100644 index 0000000..3e396bb --- /dev/null +++ b/Commodore/CVT.TXT @@ -0,0 +1,137 @@ + +*** CVT (ConVerT containers) +*** Document revision: 1.3 +*** Last updated: Oct 1, 2007 +*** Compiler/Editor: Peter Schepers +*** Contributors/sources: Joe Forster/STA + + 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 (and record block +for a VLIR) 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-FD: 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 tell 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?$.? + diff --git a/Commodore/D2M-DNP.TXT b/Commodore/D2M-DNP.TXT new file mode 100644 index 0000000..70218c4 --- /dev/null +++ b/Commodore/D2M-DNP.TXT @@ -0,0 +1,689 @@ + +*** D2M (Electronic form of a CMD FD2000 1.56 Mb floppy disk) +*** DNP (Electronic form of a CMD hard Disk Native Partition) +*** Document revision: 1.3 +*** Last updated: Nov 27, 2005 +*** Compiler/Editor: Peter Schepers +*** Contributors/sources: Torsten Hinrichs (sample files), + Malte Munde (sample files), + Wolfgang Moser, + Roberto Muscedere, + Bo Zimmerman (sample DNP files) + + Much of the information contained in this document has been gathered by +dissecting FD2000 floppy images (in D2M format) and DNP hard disk images, +comparing them, and arriving at some well-educated conclusions. Comparisons +to some other disk types (D81, D64) have helped immeasurably. Therefore, +some of the information presented here might not be accurate or complete. + + CMD devices are incredibly compatible. The FD2000 is is backwards +compatible to the Commodore 1581 floppy, contains the JiffyDos fastloader, +and even supports the GEOS OS. Inserting a native-formatted FD2000 floppy +keeps the drive in its native mode support, but inserting a 1581-formatted +disk will put the drive into "1581 compatible" mode. It even supports +"emulated" partitions of 1541, 1571 and 1581 disks on native-formatted +disks. + + The D2M image is considered a "container" image as it contains other +image types like D64, D71, D81 and native partitions as well. The container +nature makes supporting D2M more difficult than other image types. + + The extension DNP was arrived at after discussions between Bo Zimmerman +and this document author. It stands for CM(D) (N)ative (P)artition. +Unfortunately we could not assign it CMD as that would conflict with the +Windows OS CMD interpeter batch files. + + There are several different ways to view the layout of FD2000 floppies. +At the controller level, the disk has 81 tracks (physically numbered 0 to +80), 10 sectors-per-track, 2 disk sides with 1024 bytes per sector. In +Commodore logical terms, it has 81 tracks (1 to 81 logical), 80 +sectors-per-track with 256 bytes per sector, totalling 6480 sectors total. +This makes the disk 1.56Mb in size. The last track (81, image offset +$190000) is reserved and should not be used for data storage. This makes +the file size 1658880 without error bytes attached, or 1665360 bytes with +error bytes attached. + + Seeing as the disk is 6480 sectors large, we need 6480 error bytes +attached to the end of the image for an extended image type. About the only +use for the error bytes is when emulating 1541 or 1571 drive types, and a +bad sector for copy protection is needed. The job codes these error bytes +represent only really apply the 1541 and 1571 drives. + + While it may seem logical to interact with the disk with 81 tracks, it +fails in practice and the reason is simple. Internally, all track & sector +links in the native and emulated partitions (not system) refer to the disk +as a 256 sector/track so you must work with the disk this way. This means +the FD2000 image actually has 26 tracks, 25 for the image and a partial +track 26 (80 sectors only) for the system partition. Coding a proper +support structure for one CMD device image like D2M means that it would +also be easy to make it work for any other image like DNP (except for the +lack of a system partition). + + So, what does it mean when track 2 sector 233 ($02/$E9) is accessed? To +answer this, we need to convert the track and sector numbers into +HEXADECIMAL, because calculating the resulting offset location become very +simple. Taking the example above (track 2 sector 233), convert them to HEX +numbers... + + track 2 -> $02 + sector 233 -> $E9 + + subtract 1 from the track value (because all track references are from 1, +not zero), attach the sector value to the end, and then attach a $00 to the +end... + + ($track-1):$sector:$00 or $01E900. + + This is the offset value into the existing partition to access track 1 +sector 233. + + Additionally, each partition internally always starts from track 1. How +is this possible? Well, the system partition table specifies what offset a +partition starts at (in system blocks), and once inside the partition, all +track references now start at 1. This means *you* must keep track of the +offset where each partition exists once you are inside. As a bonus, this +also means that moving a partition from one disk to another should be very +simple because all the track/sector references and chains are "relative" +and do not have to be adjusted. + + CMD devices like the FD2000 floppy and CMD hard disks contain a "system +partition" (described later) which stores up to 31 user-created partitions +(also called segments), with the types defined below. One of the partitions +will be set as the default so that when the disk is inserted in the floppy, +the default partition will be entered automatically. The first entry is +always set as the "system" entry. + + There are several different types of partitions, which are... + + Type Description Size + ---- --------------------------- ----------------------------------- + 00 No partition 0 + 01 Native partition variable (min 256 512-byte blocks) + 02 Emulated 1541 drive (D64) 342 512-byte blocks (684 sectors) + 03 Emulated 1571 drive (D71) 684 512-byte blocks (1368 sectors) + 04 Emulated 1581 drive (D81) 1600 512-byte blocks (3200 sectors) + 255 System partition (track 81) + + The emulated drive partitions are a direct sector copy of the disk type. +This means the track/sector references are just as a normal disk would be, +even though the FD2000 doesn't normally do things this way. If you were to +sector-by-sector copy the data out from this emulated partition to a new +file, you would have a D64 (or D71/D81) image file in all respects. + + There are two things to watch out for if you intend to copy the data from +emulated partitions out to a real disk. Both the 1541 and the 1571 contain +extra "filler" sectors on the end. The 1541 contains one, and the 1571 +contains two. A partial explanation for this behaviour is that the FD2000 +system partition works with 512-byte blocks, meaning all partitions must be +even numbers (in 256-byte blocks). Therefore the 1541 size is incremented +to the next logical size (684) to make is an even value. The 1571 is simply +a doubling of the 1541 size, even though this means it now contains *two* +extra filler sectors (which are now completely unnecessary). + + For more information on the layout of 1541 (D64), 1571 (D71), 1581 (D81), +GEOS, REL or any of the specific file types on the disks, see the +appropriate documentation which should be included with this one. + + It is the native partition type which is the most powerful to use because +it is capable of so much, being a greatly improved disk format over the +D64. + + + + +The System Partition (D2M/D4M images only) +------------------------------------------ + + Every CMD storage device contains a system partition, but not all the +images do. The D2M and D4M images do contain the system partition, but the +DNP image does not as it is only a copy of the native partition portion +from a CMD hard disk. Therefore this section only refers to the floppy +(D2M) images. + + The system partition exists at track 26 (offset $190000), and is broken +up into several different areas. With only 80 sectors on this track +(instead of the normal 256), there is potentially a lot of information. +However, only sector 5 and 8-11 seem to be used. + + The system partition contains no BAM map. In order to add new partitions, +a pseudo-map would need to be built based on the existing partition entries +starting positions and sizes to know where there is empty space on the disk +for more partitions. + + Sector 5 (offset $190500) holds the DevBlock, the "device information +block". Most of the information here is unknown, but it likely contains +information about the device itself, and possibly which partition is set as +the default. This block should be duplicated as-is when generating a D2M +image file as it does not appear to change across any of the images that +have been seen. + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +190500: 00 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +190510: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +190520: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +190530: FF FF FF FF FF FF FF FF 00 00 FF FF FF FF FF FF +190540: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +190550: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +190560: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +190570: 00 0C FF FF FF FF FF FF FF FF FF FF FF FF FF FF +190580: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +190590: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +1905A0: FF FF FF FF FF FF FF FF 00 80 FF FF FF FF FF FF +1905B0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +1905C0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +1905D0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +1905E0: 00 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 +1905F0: 43 4D 44 20 46 44 20 53 45 52 49 45 53 20 20 20 CMDFDSERIES + + Byte:$00-EF: unknown + F0-FF: Disk identifier string (in ASCII, padded with $20) + + + Sectors 8-11 (offset $190800-190BFF) hold the system partition directory +containing information for as many as 31 separate partitions. The example +below shows the 4 allowed partition types along with the required "SYSTEM" +entry. All partition entries are 32 bytes long but the first two bytes are +not used for the entry. + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +190800: 01 01 FF 00 00 53 59 53 54 45 4D A0 A0 A0 A0 A0 SYSTEM +190810: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 00 00 +190820: 00 00 04 00 00 31 35 38 31 2F 50 41 52 54 49 54 1581/PARTIT +190830: 49 4F 4E A0 A0 00 00 00 00 00 00 00 00 00 06 40 ION@ +190840: 00 00 03 00 00 31 35 37 31 50 41 52 54 49 54 49 1571PARTITI +190850: 4F 4E A0 A0 A0 00 06 40 00 00 00 00 00 00 02 AC ON@ +190860: 00 00 02 00 00 31 35 34 31 50 41 52 54 49 54 49 1541PARTITI +190870: 4F 4E A0 A0 A0 00 08 EC 00 00 00 00 00 00 01 56 ONV +190880: 00 00 01 00 00 4E 41 54 49 56 2D 50 41 52 54 49 NATIV-PARTI +190890: 54 49 4F 4E A0 00 0A 42 00 00 00 00 00 00 02 00 TIONB +1908A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +1908B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +1908C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +1908D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +1908E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +1908F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +190900: 01 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +190910: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +190920: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +190930: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +190940: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +190950: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +190960: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +190970: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +190980: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +190990: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +1909A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +1909B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +1909C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +1909D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +1909E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +1909F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +190A00: 01 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +190A10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +190A20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +190A30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +190A40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +190A50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +190A60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +190A70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +190A80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +190A90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +190AA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +190AB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +190AC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +190AD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +190AE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +190AF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +190B00: 00 FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +190B10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +190B20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +190B30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +190B40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +190B50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +190B60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +190B70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +190B80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +190B90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +190BA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +190BB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +190BC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +190BD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +190BE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +190BF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + + Notice that the chain links are 1/1, 1/2, 1/3, and ends with a $00/$FF. +What is happening here is the drive is using 26/5 as the start of the +system partition, which now make 26/5 appear as logical 1/0. This is an +example of partitions starting at track 1 internally even though they +physically reside elsewhere. Therefore, even though the system partition +starts at 26/5, this is actually logical track/sector 1/0 and you need to +keep track of the starting offset of this partition so that accesses still +start as 26/5. + + The first entry is the root name. This entry must exist first... + +190800: 01 01 FF 00 00 53 59 53 54 45 4D A0 A0 A0 A0 A0 SYSTEM +190810: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 00 00 + + Byte:$00-01: track/sector reference to next partition block + 02: Partition type (255=system partition) + 03-04: unknown, set to $00 + 05-14: root name (16 characters, padded with $A0) + 15-1F: set to $00 + + The next entry is the first partition... + +190820: 00 00 04 00 00 31 35 38 31 2F 50 41 52 54 49 54 1581/PARTIT +190830: 49 4F 4E A0 A0 00 00 00 00 00 00 00 00 00 06 40 ION@ + + Byte:$00-01: not used + 02: Partition type + 00 - No partition + 01 - Native FD2000 partition + 02 - Emulated 1541 disk (D64) + 03 - Emulated 1571 disk (D71) + 04 - Emulated 1581 disk (D81) + 03-04: unknown, set to $00 + 05-14: Partition name (16 bytes, padded with $A0) + 15: unknown, set to $00 + 16-17: Starting offset to partition, in hi/lo format (note that + these blocks are 512-byte blocks) + 18-1D: unknown, set to $00 + 1E-1F: Partition size, in hi/lo format (note that these blocks + are again 512-bytes in size) + + *Note: the "partition size" and "starting offset" values are some other +examples of the oddities of the FD2000 layout. They are counted in 512-byte +sectors, not the standard 256-byte sectors of other Commodore disks. What +this means is you must double the value to get the actual size in 256-byte +sectors. + + In the case of emulated drive partitions, the size is already known, as +it is a sector-for-sector duplicate of the emulated disk. An emulated 1541 +disk will have one extra sector at the end of the image because it is an +odd size (683) and the size must always be even, being multiples of 512 +bytes. + + The third partition example from above ("1571PARTITION") shows a block +offset of $0640 and a block size of $02AC. Since these are in 512-byte +blocks, we need to double them to get the real 256-byte sector values +($0C80 and $0558). This means that this partition starts at file offset +$0C8000, and is $0558 (or 1368) sectors large. The file offset number must +be remembered as all references within the partition must be added to the +above offset value to get the real offset into the D2M image. + + + +Native Partitions (D2M and DNP images) +-------------------------------------- + + All partitions inside of a D2M image must start on a 512 byte boundary, +and end on one as well. The minimum size for a native partition is 256 +system blocks (or 512 sectors in 256-byte sectors). Part of the reason for +the minimum size is the number of blocks that the BAM and other areas +allocate (35 blocks) even before you get a chance to do anything. + + Keep in mind that a DNP image does not contain a system partition but is +only the native partition from a CMD hard disk. It is therefore not +considered a "container" image type. The maximum track size for DNP is 255. +This puts the upper limit on this image at 16,711,680 bytes. To determine +the track size of a DNP image, simply divide the image size by 65536. If +there is any remainder, this means there is a partial track stored at the +top so increment the track size by one. + + The first sector ($01/$00) of a native partition is reserved for the C128 +boot block. CMD designed the drive this way, allocating the first sector +automatically, so the partition HEX dump will start at the next sector, +$01/$01. + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +0000: 01 24 48 00 53 55 42 44 49 52 31 38 A0 A0 A0 A0 $HSUBDIR18 +0010: A0 A0 A0 A0 A0 A0 54 49 A0 31 48 A0 A0 00 00 00 TI1H +0020: 01 23 01 01 01 22 02 00 00 00 00 00 00 00 00 00 #" +0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +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 01 25 47 45 4F %GEO +00B0: 53 20 66 6F 72 6D 61 74 20 56 31 2E 31 00 00 00 SformatV1.1 +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 + + Byte:$00-01: Track/sector reference to root directory block of this + partition ($01/$24). + 02: Disk format type ("H") + 03: unknown, set to $00 + 04-15: Disk name (16 characters, padded with $A0) + 16-17: Disk ID's ("TI") + 18: Set to $A0 + 19: DOS Version ("1") + 1A: Disk format type ("H") + 1B-1C: Set to $A0 + 1D-1F: unknown, set to $00 + 20-21: Track/Sector pointer to present directory header block + 22-23: Track/Sector pointer to parent directory header block + (set to $00/$00 when at the top of the directory) + 24-25: Track/Sector pointer to dir entry in previous directory + (set to $00/$00 when at the top of the directory) + 26: Index pointer to dir entry in parent directory (set to + $00 if at the top of the directory) + 27-AA: unknown, set to $00 + AB-AC: GEOS border sector + AD-BC: GEOS format string (GEOS format Vx.x) + BD-FF: Unknown, set to 00 + + The references at $20 through $26 take a little more explanation. The +track/sector link at $20-$21 points to the header of the present directory. +This way when you are in the directory listing, you know where the header +block is, and it can be accessed to find out how to go back one level, or +change the header name, etc. + + The t/s link at $22-23 points back to the immediately previous directory +(parent entry), allowing you to go backwards up the directory tree one step +at a time. Note that there is no value for a jump back to the top level +directory. This value is known only when you enter the partition. + + The t/s link at $24-25 points to the sector where the entry for the +present directory name exists (one level up), and the value at $26 is the +real index into this sector pointing directly at the name. This entry is +important because if you add extra entries to a directory, forcing the +addition of another sector, the parent entry must be updated with a new +block count. The reference at $24-26 tells you exactly where the parent +entry is. + + If the directory header contains the GEOS format signature at offset $AD, +then the directory is ready for GEOS use. See the GEOS.TXT document for +more explanation of GEOS features. It is not known if children +subdirectories under a parent which is GEOS formatted must also be GEOS +format. However, each directory, regardless of where it is, uses it's own +GEOS border sector if it is formatted for GEOS. + + + The BAM map for a native partition starts at track 1 sector 2 and extends +up to sector 33. Why is it 32 sectors long? A native partition supports up +to 255 tracks (at 256 sectors per track). Doing the math, this makes the +BAM table 8160 bytes long, or approximately 32 sectors. A native partition +inside of a D2M image can only go up to track 25 of 255 due to the physical +size limits of the D2M, so most of the table is unused and filled with +$FF's. However, a DNP image can use up to 255 tracks, so the entire BAM +will be used. + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +000200: 00 00 48 B7 4A 4F C0 00 19 00 00 00 00 00 00 00 HJO +000210: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +000220: 00 00 00 00 0F FF FF FF 00 00 00 00 00 00 00 00 +000230: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +000240: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +000250: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +000260: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +000270: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +000280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +000290: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0002A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0002B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0002C0: 00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 00 @ +0002D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0002E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0002F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + .. +000500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +000510: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +000520: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +000530: 00 00 00 00 00 00 00 07 FF FF FF FF FF FF FF FF +000540: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +000550: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF + + Byte:$00-01: unknown, set to $00 + 02: Disk format type ("H") + 03 1's complement of format type ("H" EOR $FF) + 04-05: Disk ID's ("JO") + 06: unknown (seems to be the same value from the 1581 image, + 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: unknown, set to $00 + 08: Last available track # in partition ($19=#25) + 09-1F: unknown, set to $00 + 20-FF: BAM for tracks 1-7 + + + BAM block Covers tracks + ------------ ------------------------------ + 1 (#01/#02) 01-07 (starts at offset $20) + 2 (#01/#03) 08-15 (starts at offset $00) + 3 (#01/#04) 16-23 '' + 4 (#01/#05) 24-31 '' + ... ... + 30 (#01/#31) 232-239 '' + 31 (#01/#32) 240-247 '' + 32 (#01/#33) 248-255 '' + + Track Offset Range + ----- -------------- + 01 $000220-00023F + 02 $000240-00025F + 03 $000260-00027F + 04 $000280-00029F + .. + 253 $0021A0-0021BF + 254 $0021C0-0021DF + 255 $0021E0-0021FF + + + The BAM bit breakdown is not very complicated. Each track allocation +takes exactly 32 bytes. Looking at the above entry, we can extract the +entry for track 1 (all 256 sectors), which starts at track 1, sector 2, +offset $20 ($000220)... + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +000220: 00 00 00 00 0F FF FF FF 00 00 00 00 00 00 00 00 +000230: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + + Each byte represents 8 sectors. The first series of six bytes are broken +down as follows... + + Byte 0 Byte 1 Byte 2 Byte 3 Byte 4 Byte 5 + 76543210 76543210 76543210 76543210 76543210 76543210 + -------- -------- -------- -------- -------- -------- + 00000000 00000000 00000000 00000000 00001111 11111111 + + + + + Sec 7 Sec 15 Sec 23 Sec 31 Sec 39 Sec 47 + Sec 0 Sec 8 Sec 16 Sec 24 Sec 32 Sec 40 + + Byte #0 covers sector 0-7, #1 covers 8-15 and so on. A '1' bit means the +sector is free, and a '0' bit means the sector is allocated (used). For an +empty partition, sectors 0-34 are always allocated. Note that even though +sector 0 is not used (completely empty), it is still allocated. + + + Looking back to the first sector of the partition block, it had the next +t/s link set as $01/$22 (offset $002200), so here is the dump of that +sector, which is the first directory block. This block is very similar in +layout to a normal disk (D64, etc) containing GEOS files. + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +002200: 01 23 86 01 40 45 43 48 4F 20 48 41 57 4B A0 A0 #@ECHOHAWK +002210: A0 A0 A0 A0 A0 00 00 00 00 60 01 02 15 13 02 00 ` +002220: 00 00 86 02 32 50 4C 55 52 41 4C A0 A0 A0 A0 A0 2PLURAL +002230: A0 A0 A0 A0 A0 00 00 00 00 60 01 02 15 19 02 00 ` +002240: 00 00 86 03 04 52 45 41 43 54 4F 52 A0 A0 A0 A0 REACTOR +002250: A0 A0 A0 A0 A0 00 00 00 00 60 01 02 15 20 04 00 ` +002260: 00 00 86 04 D8 54 48 45 20 54 52 41 49 4E A0 A0 THETRAIN +002270: A0 A0 A0 A0 A0 00 00 00 00 60 01 0A 10 23 03 00 `# +002280: 00 00 86 06 62 49 4E 46 49 4C 54 52 41 54 4F 52 bINFILTRATOR +002290: A0 A0 A0 A0 A0 00 00 00 00 60 01 0A 10 2B 06 00 `+ +0022A0: 00 00 86 08 FE 53 54 4F 4E 45 20 41 47 45 A0 A0 STONEAGE +0022B0: A0 A0 A0 A0 A0 00 00 00 00 60 01 0A 12 04 05 00 ` +0022C0: 00 00 86 0A D6 4E 49 43 4B 20 46 41 4C 44 4F 20 NICKFALDO +0022D0: 47 4F 4C 46 A0 00 00 00 00 60 01 0A 12 09 02 00 GOLF` +0022E0: 00 00 86 0A D8 52 2D 54 59 50 45 A0 A0 A0 A0 A0 R-TYPE +0022F0: A0 A0 A0 A0 A0 00 00 00 00 60 01 0A 12 0D 05 00 ` + + Byte:$00-01: T/S link to next directory block (set to $00/$FF if it's + the last sector of the directory) + 02: Entry type. Typical values for this location are: + $00 - Scratched (deleted file entry) + 80 - DEL file + 81 - SEQ file + 82 - PRG file + 83 - USR file + 84 - REL file + 85 - 1581 partition (only in emulated 1581 disks) + 86 - Native FD2000 subdirectory + Bit:0-3: The actual filetype + 000 (0) - DEL + 001 (1) - SEQ + 010 (2) - PRG + 011 (3) - USR + 100 (4) - REL + 101 (5) - 1581 partition + 110 (6) - FD2000 subdirectory + Values 7-15 are illegal + 4: Not used + 5: Used only during SAVE-@ replacement (?) + 6: Locked flag (if set produces ">" locked files) + 7: Closed flag (Not set produces "*", or "splat" + files) + 03-04: Track/sector location of first sector of entry + 05-14: 16 character filename (in PETASCII, padded with $A0) + 15-16: Starting track/sector of REL super-side-sector info (If + GEOS file, t/s link to info block) + 17: REL record length (if GEOS file, GEOS file structure + descriptor, $00=sequential, $01=VLIR file) + 18: unknown, set to $00 (If GEOS file, GEOS file type + descriptor) + 19-1D: File time/date stamp (seconds are not stored). This is + the same timestamp that GEOS uses. + 19: Year (add 1900 for real year) + 1A: Month (1=JAN, 2=FEB etc) + 1B: Day (#1-#31) + 1C: Hour (24 hour time, #00-#23) + 1D: Minute (#00-#59) + 1E-1F: Size in sectors, low/high byte order ($1E + $1F * 256). + The filesize in bytes is <= #sectors * 254 + 20-3F: Second dir entry. From now on the first two bytes of + each entry in the 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 + + The above "size" at $1E-1F can either be the sector count of the file +entry (file size), or the directory size if it's a directory. If it is a +directory, it counts both the header and directory blocks but not any files +or subsequent subdirectory blocks. This value will increment if any extra +directory blocks that need to be allocated to store more files/directories. + + Directory space is allocated dynamically, so the size will vary depending +on how many entries are in the subdirectory, and how many blocks the whole +directory takes. It might help to think of the native partition directory +structure and capabilities as you would on a MSDOS machine. They are both +dynamic, and appear to support as many subdirectories as disk space allows. +There does not appear to be any limit on how many directory levels deep one +can go. The "xxx blocks free" that would be seen after a directory listing +would apply across the entire partition, as does the BAM for the partition. + + Also note the timestamp on bytes $19-1D. The FD2000 drive has a built-in +real-time clock, allowing for an accurate time/date stamp on file and +directory creation. It is the same stamp that GEOS has used for years. For +more info on GEOS files, read the GEOS.TXT document. + + + Looking back at the first directory block, it had the entry "ECHO HAWK" +set as a subdirectory, with it's T/S location as $01/$40 (offset $004000), +and it's block size as 2. Here is the dump of the first block of that +subdirectory. + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +004000: 01 41 48 00 45 43 48 4F 20 48 41 57 4B A0 A0 A0 AHECHOHAWK +004010: A0 A0 A0 A0 A0 A0 4A 4F A0 31 48 A0 A0 00 00 00 JO1H +004020: 01 40 01 01 01 22 02 00 00 00 00 00 00 00 00 00 @" +004030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +004040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +004050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +004060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +004070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +004080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +004090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0040A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0040B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0040C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0040D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0040E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0040F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + + Byte:$00-01: Track/sector link to next directory block ($01/$41, or + $004100) + 02: Disk format type ("H") + 03: unknown, set to $00 + 04-15: Directory name (16 characters, padded with $A0) + 16-17: Disk ID's ("JO") + 18: Set to $A0 + 19: DOS version ("1") + 1A: Disk format type ("H") + 1B-1C: Set to $A0 + 1D-1F: unknown, set to $00 + 20-21: Track/Sector pointer to present directory header block + ($01/$40, points to itself) + 22-23: Track/Sector pointer to parent directory header block + ($01/$01, points to previous directory) + 24-25: Track/Sector pointer to dir entry in previous directory + ($01/$22) + 26: Index pointer to dir entry in parent directory ($02) + 27-FF: unknown, set to $00 + + Each directory is preceeded by this "header" block, including the root +(from above). This block is necessary because it is the only location which +can hold the "directory" name, and all the track/sector pointers into +various levels of the directory structure. + + + From here, we go to the next block of the directory, holding the actual +file listing, possibly with more subdirectories. This is block #2 (out of +2) of the entry total. The layout and description is the same as the +previous example of the first directory block. + + + + +Creating A D2M Image +-------------------- + + Follow these steps to create a D2M image. These instructions do not +describe how to create a partition entry or subdirectories. For this info, +you will need to read the above information very carefully. + + 1. Create a new file, and write out 6480 256-byte blocks of zero's. + + 2. If you need error bytes, write out another 6480 bytes of $01's. This + is the job code for "no error". + + 3. Copy the DevBlock exactly, as shown previously (located in an existing + image at track 26, sector 5, or offset $190500). + + 4. Create the system partition as described above (track 26, sector + 8-11). + + 5. Make sure the "SYSTEM" entry exists as the first entry in the system + partition. + diff --git a/Commodore/D64.TXT b/Commodore/D64.TXT new file mode 100644 index 0000000..9643de1 --- /dev/null +++ b/Commodore/D64.TXT @@ -0,0 +1,690 @@ + +*** D64 (Electronic form of a physical 1541 disk) +*** Document revision: 1.11 +*** Last updated: Nov 7, 2008 +*** Compiler/Editor: Peter Schepers +*** Contributors/sources: Immers/Neufeld "Inside Commodore DOS" + Wolfgang Moser + +(Note: This document will try to explain the layout of the 1541 disks, as +well as some of the files they contain. However, I do not explain GEOS or +REL files here. See the file GEOS.TXT or REL.TXT for more information on +those file types or disk structure). Special thanks to Wolfgang Moser for +his work on identifying the differences between the various 'Speeder' DOS's +that exist. This information is included in a table later in this document. + + 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 inner 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 Storage in Bytes + ----- ------------- --------- ---------------- + 1-17 21 357 7820 + 18-24 19 133 7170 + 25-30 18 108 6300 + 31-40(*) 17 85 6020 + --- + 683 (for a 35 track image) + + 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 + + (*)Tracks 36-40 apply to 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, using a sector interleave of 3. This makes the +chain links go 18/1, 18/4, 18/7 etc. + + Note that you can extend the directory off of track 18, but only when +reading the disk or image. Attempting to write to a directory sector not on +track 18 will cause directory corruption. See the section below called +Non-Standard & Long Directories. + +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, max. value 254) + 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 + +Files, on a standard 1541, are stored using an interleave of 10. Assuming a +starting track/sector of 17/0, the chain would run 17/0, 17/10, 17/20, +17/8, 17/18, etc. + +Note: No GEOS entries are listed in the above description. See the GEOS.TXT + file for GEOS info. + + +*** Non-Standard & Long Directories + + Most Commdore floppy disk drives use a single dedicated directory track +where all filenames are stored. This limits the number of files stored on a +disk based on the number of sectors on the directory track. There are some +disk images that contain more files than would normally be allowed. This +requires extending the directory off the default directory track by +changing the last directory sector pointer to a new track, allocating the +new sectors in the BAM, and manually placing (or moving existing) file +entries there. The directory of an extended disk can be read and the files +that reside there can be loaded without problems on a real drive. However, +this is still a very dangerous practice as writing to the extended portion +of the directory will cause directory corruption in the non-extended part. +Many of the floppy drives core ROM routines ignore the track value that the +directory is on and assume the default directory track for operations. + + To explain: assume that the directory has been extended from track 18 to +track 19/6 and that the directory is full except for a few slots on 19/6. +When saving a new file, the drive DOS will find an empty file slot at 19/6 +offset $40 and correctly write the filename and a few other things into +this slot. When the file is done being saved the final file information +will be written to 18/6 offset $40 instead of 19/6 causing some directory +corruption to the entry at 18/6. Also, the BAM entries for the sectors +occupied by the new file will not be saved and the new file will be left as +a SPLAT (*) file. + + Attempts to validate the disk will result in those files residing off the +directory track to not be allocated in the BAM, and could also send the +drive into an endless loop. The default directory track is assumed for all +sector reads when validating so if the directory goes to 19/6, then the +validate code will read 18/6 instead. If 18/6 is part of the normal +directory chain then the validate routine will loop endlessly. + + +*** BAM layout + +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 ($00), 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, DOLPHIN and ProLogic 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. Any leftover +bits that refer to sectors that don't exist, like bits 21-23 in the above +example, are set to allocated. + + 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) + + +--------------------------------------------------------------------------- + + +*** 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. This can also have error bytes attached like variant #1. + + 3. The Commodore 128 allowed for "auto-boot" disks. With this, t/s 1/0 + holds a specific byte sequence which the computer recognizes as boot + code. See the document C128BOOT.TXT for more info. + + + Below is a small chart detailing the standard file sizes of D64 images, +35 or 40 tracks, with or without error bytes. + + 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 + + + The following table (provided by Wolfgang Moser) outlines the differences +between the standard 1541 DOS and the various "speeder" DOS's that exist. +The 'header 7/8' category is the 'fill bytes' as the end of the sector +header of a real 1541 disk See the document G64.TXT for a better +explanation of these bytes. + + Disk format |Tracks|Header 7/8|Dos type|DiskDos + | |allsechdrs| |vs.type + ============================================================ + Original CBM DOS v2.6 | 35 | $0f $0f | "2A" |$41/'A' + ------------------------------------------------------------ + *SpeedDOS+ | 40 | $0f $0f | "2A" |$41/'A' + ------------------------------------------------------------ + ProfessionalDOS Initial | 35 | $0f $0f | "2A" |$41/'A' + (Version 1/Prototype) | 40 | $0f $0f | "2A" |$41/'A' + ------------------------------------------------------------ + ProfDOS Release | 40 | $0f $0f | "4A" |$41/'A' + ------------------------------------------------------------ + Dolphin-DOS 2.0/3.0 | 35 | $0f $0f | "2A' |$41/'A' + Dolphin-DOS 2.0/3.0 | 40 | $0d $0f | "2A' |$41/'A' + ------------------------------------------------------------ + PrologicDOS 1541 | 35 | $0f $0f | "2A' |$41/'A' + PrologicDOS 1541 | 40 | $0f $0f | "2P' |$50/'P' + ProSpeed 1571 2.0 | 35 | $0f $0f | "2A' |$41/'A' + ProSpeed 1571 2.0 | 40 | $0f $0f | "2P' |$50/'P' + ------------------------------------------------------------ + +*Note: There are also clones of SpeedDOS that exist, such as RoloDOS and + DigiDOS. Both are just a change of the DOS startup string. + + The location of the extra BAM information in sector 18/0, for 40 track +images, will be different depending on what standard the disks have been +formatted with. SPEED DOS stores them from $C0 to $D3, DOLPHIN DOS stores +them from $AC to $BF and PrologicDOS stored them right after the existing +BAM entries from $90-A3. PrologicDOS also moves the disk label and ID +forward from the standard location of $90 to $A4. 64COPY and Star Commander +let you select from several different types of extended disk formats you +want to create/work with. + + All three of the speeder DOS's mentioned above don't alter the standard +sector interleave of 10 for files and 3 for directories. The reason is that +they use a memory cache installed in the drive which reads the entire track +in one pass. This alleviates the need for custom interleave values. They do +seem to alter the algorithm that finds the next available free sector so +that the interleave value can deviate from 10 under certain circumstances, +but I don't know why they would bother. + + + Below is a HEX dump of a Speed DOS BAM sector. Note the location of the +extra BAM info from $C0-D3. + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +0070: 12 FF FF 03 12 FF FF 03 12 FF FF 03 11 FF FF 01 +0080: 11 FF FF 01 11 FF FF 01 11 FF FF 01 11 FF FF 01 +0090: A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 +00A0: A0 A0 30 30 A0 32 41 A0 A0 A0 A0 00 00 00 00 00 002A +00B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00C0: 11 FF FF 01 11 FF FF 01 11 FF FF 01 11 FF FF 01 +00D0: 11 FF FF 01 00 00 00 00 00 00 00 00 00 00 00 00 + + + Below is a HEX dump of a Dolphin DOS BAM sector. Note the location of the +extra BAM info from $AC-BF. + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +0070: 12 FF FF 03 12 FF FF 03 12 FF FF 03 11 FF FF 01 +0080: 11 FF FF 01 11 FF FF 01 11 FF FF 01 11 FF FF 01 +0090: A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 +00A0: A0 A0 30 30 A0 32 41 A0 A0 A0 A0 00 11 FF FF 01 002A +00B0: 11 FF FF 01 11 FF FF 01 11 FF FF 01 11 FF FF 01 +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 + + + Below is a HEX dump of a PrologicDOS BAM sector. Note that the disk name +and ID are now located at $A4 instead of starting at $90. + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +0070: 12 FF FF 03 12 FF FF 03 12 FF FF 03 11 FF FF 01 +0080: 11 FF FF 01 11 FF FF 01 11 FF FF 01 11 FF FF 01 +0090: 11 FF FF 01 11 FF FF 01 11 FF FF 01 11 FF FF 01 +00A0: 11 FF FF 01 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 +00B0: A0 A0 A0 A0 A0 A0 30 30 A0 32 50 A0 A0 A0 A0 00 002P +00C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00ED: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + + +--------------------------------------------------------------------------- + +*** Error codes + + 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, whether it's searching for any SYNC mark, any header ID, any valid +header, or reading a sector. + + These first errors are "seek" errors, where the disk controller is simply +reading headers and looking at descriptor bytes, checksums, format ID's and +reporting what errors it sees. These errors do *not* necessarily apply to +the exact sector being looked for. This fact makes duplication of these +errors very unreliable. + + Code Error Type 1541 error description + ---- ----- ---- ------------------------------ + 03 21 Seek No SYNC sequence found. + + Each sector data block and header block are + preceeded by SYNC marks. If *no* sync sequence is + found within 20 milliseconds (only ~1/10 of a disk + rotation!) then this error is generated. This error + used to mean the entire track is bad, but it does + not have to be the case. Only a small area of the + track needs to be without a SYNC mark and this + error will be generated. + + Converting this error to a D64 is very problematic + because it depends on where the physical head is on + the disk when a read attempt is made. If it is on + valid header/sectors then it won't occur. If it + happens over an area without SYNC marks, it will + happen. + + + 02 20 Seek Header descriptor byte not found (HEX $08, GCR $52) + + Each sector is preceeded by an 8-byte GCR header + block, which starts with the value $52 (GCR). If + this value is not found after 90 attempts, this + error is generated. + + Basically, what a track has is SYNC marks, and + possibly valid data blocks, but no valid header + descriptors. + + + 09 27 Seek Checksum error in header block + + The 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. + + + 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 + low-level header of 18/0. If there is a mismatch, + this error is generated. + + + 02 20 Seek Header block not found + + This error can be reported again when searching for + the correct header block. An image of the header is + built and searched for, but not found after 90 read + attempts. Note the difference from the first + occurance. The first one only searches for a valid + ID, not the whole header. + + Note that error 20 occurs twice during this phase. The first time is when +a header ID is being searched for, the second is when the proper header +pattern for the sector being searched for is not found. + + + From this point on, all the errors apply to the specific sector you are +looking for. If a read passed all the previous checks, then we are at the +sector being searched for. + + Note that the entire sector is read before these errors are detected. +Therefore the data, checksum and off bytes are available. + + Code Error Type 1541 error description + ---- ----- ---- ------------------------------ + 04 22 Read Data descriptor byte not found (HEX $07, GCR $55) + + 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. + + + 0F 74 Read Drive Not Ready (no disk in drive or no device 1) + + + These errors only apply when writing to a disk. I don't see the +usefulness of having these as they cannot be present when only *reading* a +disk. + + Code Error Type 1541 error description + ---- ----- ---- ------------------------------ + 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. + + + 0A 28 Write Write error + + In actual fact, this error never occurs, but it is + included for completeness. + + + This is not an error at all, but when gets reported when the read of a +sector is ok. + + 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. + + + 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. + + +--------------------------------------------------------------------------- + +*** Supporting D64 files + + The D64 layout is reasonably robust, 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 files), since you lose the extra 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. + + Preceeding each sector on a real 1541 disk 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. Some +programs fail to work properly since the D64 doesn't contain these ID's. +These bytes would be 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 D64 +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 REL and all GEOS files + + * Allows complete directory customization + + * Because it is a random-access device, it supports fast-loaders and + random sector access + + * PC 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. This is by no means a big problem. + + * It is not an expandable filetype, like LNX or T64 + + * Unless most of the space on a D64 disk is used, you do end up with + wasted 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 files, GEOS VLIR files) + diff --git a/Commodore/D71.TXT b/Commodore/D71.TXT new file mode 100644 index 0000000..c9caba4 --- /dev/null +++ b/Commodore/D71.TXT @@ -0,0 +1,420 @@ + +*** D71 (Electronic form of a double-sided 1571 disk) +*** Document revision: 1.5 +*** Last updated: Nov 7, 2008 +*** Compiler/Editor: Peter Schepers +*** Contributors/sources: unknown + + 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 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. + + +*** Non-Standard & Long Directories + + Most Commdore floppy disk drives use a single dedicated directory track +where all filenames are stored. This limits the number of files stored on a +disk based on the number of sectors on the directory track. There are some +disk images that contain more files than would normally be allowed. This +requires extending the directory off the default directory track by +changing the last directory sector pointer to a new track, allocating the +new sectors in the BAM, and manually placing (or moving existing) file +entries there. The directory of an extended disk can be read and the files +that reside there can be loaded without problems on a real drive. However, +this is still a very dangerous practice as writing to the extended portion +of the directory will cause directory corruption in the non-extended part. +Many of the floppy drives core ROM routines ignore the track value that the +directory is on and assume the default directory track for operations. + + To explain: assume that the directory has been extended from track 18 to +track 19/6 and that the directory is full except for a few slots on 19/6. +When saving a new file, the drive DOS will find an empty file slot at 19/6 +offset $40 and correctly write the filename and a few other things into +this slot. When the file is done being saved the final file information +will be written to 18/6 offset $40 instead of 19/6 causing some directory +corruption to the entry at 18/6. Also, the BAM entries for the sectors +occupied by the new file will not be saved and the new file will be left as +a SPLAT (*) file. + + Attempts to validate the disk will result in those files residing off the +directory track to not be allocated in the BAM, and could also send the +drive into an endless loop. The default directory track is assumed for all +sector reads when validating so if the directory goes to 19/6, then the +validate code will read 18/6 instead. If 18/6 is part of the normal +directory chain then the validate routine will loop endlessly. + + +*** Bam layout + + 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 SIDE SECTOR, which is of interest here (in this case, +17/12). If you check the D64 document for a REL file and do the +calculations, you will find that the maximum file size of the REL file is +720 data sectors. + +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 + ---- + * Most emualators support these. + + * 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 + --- + * 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) + diff --git a/Commodore/D80-D82.TXT b/Commodore/D80-D82.TXT new file mode 100644 index 0000000..d786b2b --- /dev/null +++ b/Commodore/D80-D82.TXT @@ -0,0 +1,464 @@ + +*** D80 (Disk image of an 8050 diskette, single-sided) +*** D82 (Disk image of an 8250 diskette, double-sided) +*** Document revision: 1.3 +*** Last updated: Nov 7, 2008 +*** Compiler/Editor: Peter Schepers +*** Contributors/sources: "Complete Commodore Innerspace Anthology" + + This is a sector-for-sector copy of an 8x50 floppy disk. The file size +for an 8050 image is 533248 bytes, and the 8250 image is 1066496 bytes. It +is comprised of 256-byte sectors arranged across 77 tracks (or 154 for an +8250), with a varying number of sectors per track for a total of 2083 +sectors (or 4166 for an 8250). Track counting starts at 1 (not 0) and +sector counting starts at 0 (not 1), therefore a track with 29 sectors will +go from 0 to 28. + + The only sample files I had to work with were those created by the VICE +emulator. I can only assume that the way VICE worked with the image is +correct and all of the image specifics contained herein are based on those +samples. Any deviation from the way that the 8x50 drive actually works is +unfortunate but unavoidable. + + 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 77 being on the inside of the disk (closest to the inner 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 D80 and D82. 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 Range Sectors/track # Sectors + -------------- ------------- --------- + 1-39, 78-116 29 1131 + 40-53, 117-130 27 378 + 54-64, 131-141 25 275 + 65-77, 142-154 23 299 + ---- + Total 2083 (double this for an 8250) + + + Track #Sect #SectorsIn D8x Offset | Track #Sect #SectorsIn D8x Offset + ----- ----- ---------- ---------- | ----- ----- ---------- ---------- + 1 29 0 $000000 | 78 29 2083 $82300 + 2 29 29 1D00 | 79 29 2112 84000 + 3 29 58 3A00 | 80 29 2141 85D00 + 4 29 87 5700 | 81 29 2170 87A00 + 5 29 116 7400 | 82 29 2199 89700 + 6 29 145 9100 | 83 29 2228 8B400 + 7 29 174 AE00 | 84 29 2257 8D100 + 8 29 203 CB00 | 85 29 2286 8EE00 + 9 29 232 E800 | 86 29 2315 90600 + 10 29 261 10500 | 87 29 2344 92800 + 11 29 290 12200 | 88 29 2373 94500 + 12 29 319 13F00 | 89 29 2402 96200 + 13 29 348 15C00 | 90 29 2431 97F00 + 14 29 377 17900 | 91 29 2460 99C00 + 15 29 406 19600 | 92 29 2489 9B900 + 16 29 435 1B300 | 93 29 2518 9D600 + 17 29 464 1D000 | 94 29 2547 9F300 + 18 29 493 1ED00 | 95 29 2576 A1000 + 19 29 522 20A00 | 96 29 2605 A2D00 + 20 29 551 22700 | 97 29 2634 A4A00 + 21 29 580 24400 | 98 29 2663 A6700 + 22 29 609 26100 | 99 29 2692 A8400 + 23 29 638 27E00 | 100 29 2721 AA100 + 24 29 667 29B00 | 101 29 2750 A6E00 + 25 29 696 2B800 | 102 29 2779 ADB00 + 26 29 725 2D500 | 103 29 2808 AF800 + 27 29 754 2F200 | 104 29 2837 B1500 + 28 29 783 30F00 | 105 29 2866 B3200 + 29 29 812 32C00 | 106 29 2895 B4F00 + 30 29 841 34900 | 107 29 2924 B6C00 + 31 29 870 36600 | 108 29 2953 B8900 + 32 29 899 38300 | 109 29 2982 BA600 + 33 29 928 3A000 | 110 29 3011 BC300 + 34 29 957 3BD00 | 111 29 3040 BE000 + 35 29 986 3DA00 | 112 29 3069 BFD00 + 36 29 1015 3F700 | 113 29 3098 C1A00 + 37 29 1044 41400 | 114 29 2137 C3700 + 38 29 1073 43100 | 115 29 3156 C5400 + 39 29 1102 44E00 | 116 29 3185 C7100 + 40 27 1131 46B00 | 117 27 3214 C8E00 + 41 27 1158 48600 | 118 27 3241 CA900 + 42 27 1185 4A100 | 119 27 3268 CC400 + 43 27 1212 4BC00 | 120 27 3295 CDF00 + 44 27 1239 4D700 | 121 27 3322 CFA00 + 45 27 1266 4F200 | 122 27 3349 D1500 + 46 27 1293 50D00 | 123 27 3376 D3000 + 47 27 1320 52800 | 124 27 3403 D4B00 + 48 27 1347 54300 | 125 27 3430 D6600 + 49 27 1374 55E00 | 126 27 3457 D8100 + 50 27 1401 57900 | 127 27 3484 D9C00 + 51 27 1428 59400 | 128 27 3511 DB700 + 52 27 1455 5AF00 | 129 27 3538 DD200 + 53 27 1482 5CA00 | 130 27 3565 DED00 + 54 25 1509 5E500 | 131 25 3592 E0800 + 55 25 1534 5FE00 | 132 25 3617 E2100 + 56 25 1559 61700 | 133 25 3642 E3A00 + 57 25 1584 63000 | 134 25 3667 E5300 + 58 25 1609 64900 | 135 25 3692 E6C00 + 59 25 1634 66200 | 136 25 3717 E8500 + 60 25 1659 67B00 | 137 25 3742 E9E00 + 61 25 1684 69400 | 138 25 3767 E6700 + 62 25 1709 6AD00 | 139 25 3792 ED000 + 63 25 1734 6C600 | 140 25 3817 EE900 + 64 25 1759 6DF00 | 141 25 3842 F0200 + 65 23 1784 6F800 | 142 23 3867 F1B00 + 66 23 1807 70F00 | 143 23 3890 F3200 + 67 23 1830 72600 | 144 23 3913 F4900 + 68 23 1853 73D00 | 145 23 3936 F6000 + 69 23 1876 75400 | 146 23 3959 F7700 + 70 23 1899 76B00 | 147 23 3982 F8E00 + 71 23 1922 78200 | 148 23 4005 FA500 + 72 23 1945 79900 | 149 23 4028 FBC00 + 73 23 1968 7B000 | 150 23 4051 FD300 + 74 23 1991 7C700 | 151 23 4074 FEA00 + 75 23 2014 7DE00 | 152 23 4097 100100 + 76 23 2037 7F500 | 153 23 4120 101800 + 77 23 2060 80C00 | 154 23 4143 102F00 + + The BAM (Block Availability Map) is on track 38. The D80 is only 77 +tracks and so the BAM is contained on 38/0 and 38/3. The D82 contains 154 +tracks and so the BAM is larger and is contained on 38/0, 38/3, 38/6 and +38/9. The BAM interleave is 3. + + The directory is on track 39, with 39/0 contains the header (DOS type, +disk name, disk ID's) and sectors 1-28 contain the directory entries. Both +files and the directory use an interleave of 1. Since the directory is only +28 sectors large (29 less one for the header), and each sector can contain +only 8 entries (32 bytes per entry), the maximum number of directory +entries is 28 * 8 = 224. The first directory sector is always 39/1. It then +follows a chain structure using a sector interleave of 1 making the links +go 39/1, 39/2, 39/3 etc. + + When reading a disk, you start with 39/0 (disk label/ID) which points to +38/0 (BAM0), 38/3 (BAM1), 38/6 (BAM2, D82 only), 38/9 (BAM3, D82 only), and +finally to 39/1 (first dir entry sector). When writing a file to a blank +disk, it will start at 38/1 because 38/0 is already allocated. + + +Below is a dump of the header sector 39/0: + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +00: 26 00 43 00 00 00 73 61 6D 70 6C 65 20 64 38 30 &Csampled80 +10: A0 A0 A0 A0 A0 A0 A0 A0 65 72 A0 32 43 A0 A0 A0 er2C +20: A0 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 + + Byte:$00-01: T/S pointer to first BAM sector (38/0) + 02: $43 'C' is for DOS format version + 03: Reserved + 04-05: Unused + 06-16: Disk name, padded with 0xA0 ("sample d80") + 17: 0xA0 + 18-19: Disk ID bytes "er" + 1A: 0xA0 + 1B-1C: DOS version bytes "2C". + 1D-20: 0xA0 + 21-FF: Unused + + +Below is a dump of the first directory sector, 39/1 + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +00: 27 02 82 26 01 54 45 53 54 A0 A0 A0 A0 A0 A0 A0 '&TEST +10: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 01 00 +20: 00 00 82 26 02 54 45 53 54 32 A0 A0 A0 A0 A0 A0 &TEST2 +30: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 01 00 +40: 00 00 82 26 04 54 45 53 54 33 A0 A0 A0 A0 A0 A0 &TEST3 +50: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 05 00 +60: 00 00 82 26 0B 54 45 53 54 34 A0 A0 A0 A0 A0 A0 &TEST4 +70: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 09 00 +80: 00 00 82 26 14 54 45 53 54 35 A0 A0 A0 A0 A0 A0 &TEST5 +90: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 0C 00 +A0: 00 00 82 28 00 54 45 53 54 36 A0 A0 A0 A0 A0 A0 (TEST6 +B0: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 01 00 +C0: 00 00 82 28 01 54 45 53 54 37 A0 A0 A0 A0 A0 A0 (TEST7 +D0: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 01 00 +E0: 00 00 82 28 02 54 45 53 54 38 A0 A0 A0 A0 A0 A0 (TEST8 +F0: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 01 00 + + The first two bytes of the directory sector ($27/$02) indicate the +location of the next track/sector of the directory (39/2). If the track is +set to $00, then it is the last sector of the directory. + + 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. + 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, max. value 254) + 18-1D: Unused + 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 + + +*** Non-Standard & Long Directories + + Most Commdore floppy disk drives use a single dedicated directory track +where all filenames are stored. This limits the number of files stored on a +disk based on the number of sectors on the directory track. There are some +disk images that contain more files than would normally be allowed. This +requires extending the directory off the default directory track by +changing the last directory sector pointer to a new track, allocating the +new sectors in the BAM, and manually placing (or moving existing) file +entries there. The directory of an extended disk can be read and the files +that reside there can be loaded without problems on a real drive. However, +this is still a very dangerous practice as writing to the extended portion +of the directory will cause directory corruption in the non-extended part. +Many of the floppy drives core ROM routines ignore the track value that the +directory is on and assume the default directory track for operations. + + To explain: assume that the directory has been extended from track 18 to +track 19/6 and that the directory is full except for a few slots on 19/6. +When saving a new file, the drive DOS will find an empty file slot at 19/6 +offset $40 and correctly write the filename and a few other things into +this slot. When the file is done being saved the final file information +will be written to 18/6 offset $40 instead of 19/6 causing some directory +corruption to the entry at 18/6. Also, the BAM entries for the sectors +occupied by the new file will not be saved and the new file will be left as +a SPLAT (*) file. + + Attempts to validate the disk will result in those files residing off the +directory track to not be allocated in the BAM, and could also send the +drive into an endless loop. The default directory track is assumed for all +sector reads when validating so if the directory goes to 19/6, then the +validate code will read 18/6 instead. If 18/6 is part of the normal +directory chain then the validate routine will loop endlessly. + + +*** BAM layout + + The BAM only occupies up to four sectors on track 38, so the rest of the +track is empty and is available for file storage. Below is a dump of the +first BAM block, 38/0. A D80 will only contain two BAM sectors, 38/0 and +38/3. A D82 needs two extra BAM sectors for the extra tracks. Each entry +takes 5 bytes, 1 for the free count on that track, and 4 for the BAM bits. + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +00: 26 03 43 00 01 33 1D FF FF FF 1F 1D FF FF FF 1F &C3 +10: 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D +20: FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF +30: FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF +40: FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF +50: 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F +60: 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D +70: FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF +80: FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF +90: FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF +A0: 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F +B0: 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1B +C0: F6 FF FF 1F 1B FC FF FF 1F 1B FF FF FF 07 1B FF +D0: FF FF 07 1B FF FF FF 07 1B FF FF FF 07 1B FF FF +E0: FF 07 1B FF FF FF 07 1B FF FF FF 07 1B FF FF FF +F0: 07 1B FF FF FF 07 1B FF FF FF 07 1B FF FF FF 07 + + Byte:$00-01: T/S pointer to second BAM sector (38/3) + 02: DOS version byte (0x43='C') + 03: Reserved + 04: Lowest track covered by this BAM (0x01=1) + 05: Highest+1 track covered by this BAM (0x33=51) + 06-0A: BAM for track 1. The first byte shows the "blocks free" for + this track, the remaining 4 show the BAM for the track. + 0B-0F: BAM for track 2 + ... + FB-FF: BAM for track 50 + + + Being bit-based, the BAM entries need some explanation. The first track +entry in the above BAM sector is at offset 06, "1D FF FF FF 1F". The first +number is how many blocks are free on this track ($1D=29) and the remainder +is the bit representation of the usage map for the track. These entries +must be viewed in binary to make any sense. First convert the values to +binary: + + FF=11111111, FF=11111111, FF=11111111, 1F=00011111 + +In order to make any sense from the binary notation, flip the bits around. + + 111111 11112222 222222 + 01234567 89012345 67890123 456789... + -------------------------- --------- + 11111111 11111111 11111111 11111000 + ^ ^ + sector 0 sector 28 + + Since we are on the first track, we have 29 sectors, and only use up to +the bit 28 position. If a bit is on (1), the sector is free. Therefore, +track 1 is clean, all sectors are free. Any leftover bits that refer to +sectors that don't exist, like bits 29-31 in the above example, are set to +allocated. + + + +Second BAM block 38/3, D80 only. + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +00: 27 01 43 00 33 4E 1B FF FF FF 07 1B FF FF FF 07 'C3N +10: 1B FF FF FF 07 19 FF FF FF 01 19 FF FF FF 01 19 +20: FF FF FF 01 19 FF FF FF 01 19 FF FF FF 01 19 FF +30: FF FF 01 19 FF FF FF 01 19 FF FF FF 01 19 FF FF +40: FF 01 19 FF FF FF 01 19 FF FF FF 01 17 FF FF 7F  +50: 00 17 FF FF 7F 00 17 FF FF 7F 00 17 FF FF 7F 00  +60: 17 FF FF 7F 00 17 FF FF 7F 00 17 FF FF 7F 00 17  +70: FF FF 7F 00 17 FF FF 7F 00 17 FF FF 7F 00 17 FF  +80: FF 7F 00 17 FF FF 7F 00 17 FF FF 7F 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 + + Byte:$00-01: T/S pointer to first directory sector (39/1) + 02: DOS version byte (0x43 'C') + 03: Reserved + 04: Lowest track covered by this BAM (0x33=51) + 05: Highest+1 track covered by this BAM (0x43=78) + 06-0A: BAM for track 51. The first byte shows the "blocks free" for + this track, the remaining 4 show the BAM for the track. + 0B-0F: BAM for track 52 + ... + 88-8C: BAM for track 77 + 8D-FF: Not used for an D80 (8050) + + +Second BAM block 38/3, D82 only + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +00: 26 06 43 00 33 65 1B FF FF FF 07 1B FF FF FF 07 &C3e +10: 1B FF FF FF 07 19 FF FF FF 01 19 FF FF FF 01 19 +20: FF FF FF 01 19 FF FF FF 01 19 FF FF FF 01 19 FF +30: FF FF 01 19 FF FF FF 01 19 FF FF FF 01 19 FF FF +40: FF 01 19 FF FF FF 01 19 FF FF FF 01 17 FF FF 7F  +50: 00 17 FF FF 7F 00 17 FF FF 7F 00 17 FF FF 7F 00  +60: 17 FF FF 7F 00 17 FF FF 7F 00 17 FF FF 7F 00 17  +70: FF FF 7F 00 17 FF FF 7F 00 17 FF FF 7F 00 17 FF  +80: FF 7F 00 17 FF FF 7F 00 17 FF FF 7F 00 1D FF FF  +90: FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF +A0: 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F +B0: 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D +C0: FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF +D0: FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF +E0: FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF +F0: 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F + + Byte:$00-01: T/S pointer to second BAM sector (38/6) + 02: DOS version byte (0x43='C') + 03: Reserved + 04: Lowest track covered by this BAM (0x33=51) + 05: Highest+1 track covered by this BAM (0x65=101) + 06-0A: BAM for track 51. The first byte shows the "blocks free" for + this track, the remaining 4 show the BAM for the track. + 0B-0F: BAM for track 52 + ... + FB-FF: BAM for track 100 + + +Third BAM block 38/6, D82 only + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +00: 26 09 43 00 65 97 1D FF FF FF 1F 1D FF FF FF 1F &Ce +10: 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D +20: FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF +30: FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF +40: FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF +50: 1F 1D FF FF FF 1F 1B FF FF FF 07 1B FF FF FF 07 +60: 1B FF FF FF 07 1B FF FF FF 07 1B FF FF FF 07 1B +70: FF FF FF 07 1B FF FF FF 07 1B FF FF FF 07 1B FF +80: FF FF 07 1B FF FF FF 07 1B FF FF FF 07 1B FF FF +90: FF 07 1B FF FF FF 07 1B FF FF FF 07 19 FF FF FF +A0: 01 19 FF FF FF 01 19 FF FF FF 01 19 FF FF FF 01 +B0: 19 FF FF FF 01 19 FF FF FF 01 19 FF FF FF 01 19 +C0: FF FF FF 01 19 FF FF FF 01 19 FF FF FF 01 19 FF +D0: FF FF 01 17 FF FF 7F 00 17 FF FF 7F 00 17 FF FF  +E0: 7F 00 17 FF FF 7F 00 17 FF FF 7F 00 17 FF FF 7F  +F0: 00 17 FF FF 7F 00 17 FF FF 7F 00 17 FF FF 7F 00  + + Byte:$00-01: T/S pointer to fourth BAM sector (38/9) + 02: DOS version byte (0x43='C') + 03: Reserved + 04: Lowest track covered by this BAM (0x65=101) + 05: Highest+1 track covered by this BAM (0x97=151) + 06-0A: BAM for track 101. The first byte shows the "blocks free" + for this track, the remaining 4 show the BAM for the track. + 0B-0F: BAM for track 102 + ... + FB-FF: BAM for track 150 + + +Fourth BAM block 38/9, D82 only + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +00: 27 01 43 00 97 9B 17 FF FF 7F 00 17 FF FF 7F 00 'C +10: 17 FF FF 7F 00 17 FF FF 7F 00 00 00 00 00 00 00  +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 + + Byte:$00-01: T/S pointer to first directory sector (39/1) + 02: DOS version byte (0x43 'C') + 03: Reserved + 04: Lowest track covered by this BAM (0x97=151) + 05: Highest+1 track covered by this BAM (0x9B=155) + 06-0A: BAM for track 151. The first byte shows the "blocks free" for + this track, the remaining 4 show the BAM for the track. + 0B-0F: BAM for track 152 + ... + 15-19: BAM for track 154 + 1A-FF: Not used + + +For more information on file storage, GCR layout, or disk errors see the +D64.TXT and G64.TXT documents. + diff --git a/Commodore/D81.TXT b/Commodore/D81.TXT new file mode 100644 index 0000000..40d8060 --- /dev/null +++ b/Commodore/D81.TXT @@ -0,0 +1,575 @@ + +*** D81 (Electronic form of a physical 1581 disk) +*** Document revision: 1.4 +*** Last updated: Nov 7, 2008 +*** Compiler/Editor: Peter Schepers +*** Contributors/sources: unknown + + 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 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 ($00) + 001 (1) - SEQ ($81) + 010 (2) - PRG ($82) + 011 (3) - USR ($83) + 100 (4) - REL ($84) + 101 (5) - CBM ($85, 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 + + +*** Non-Standard & Long Directories + + Most Commdore floppy disk drives use a single dedicated directory track +where all filenames are stored. This limits the number of files stored on a +disk based on the number of sectors on the directory track. There are some +disk images that contain more files than would normally be allowed. This +requires extending the directory off the default directory track by +changing the last directory sector pointer to a new track, allocating the +new sectors in the BAM, and manually placing (or moving existing) file +entries there. The directory of an extended disk can be read and the files +that reside there can be loaded without problems on a real drive. However, +this is still a very dangerous practice as writing to the extended portion +of the directory will cause directory corruption in the non-extended part. +Many of the floppy drives core ROM routines ignore the track value that the +directory is on and assume the default directory track for operations. + + To explain: assume that the directory has been extended from track 18 to +track 19/6 and that the directory is full except for a few slots on 19/6. +When saving a new file, the drive DOS will find an empty file slot at 19/6 +offset $40 and correctly write the filename and a few other things into +this slot. When the file is done being saved the final file information +will be written to 18/6 offset $40 instead of 19/6 causing some directory +corruption to the entry at 18/6. Also, the BAM entries for the sectors +occupied by the new file will not be saved and the new file will be left as +a SPLAT (*) file. + + Attempts to validate the disk will result in those files residing off the +directory track to not be allocated in the BAM, and could also send the +drive into an endless loop. The default directory track is assumed for all +sector reads when validating so if the directory goes to 19/6, then the +validate code will read 18/6 instead. If 18/6 is part of the normal +directory chain then the validate routine will loop endlessly. + + +*** BAM layout + + 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. + + +--------------------------------------------------------------------------- + +*** 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 + ---- + * Most emulators support them + + * 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 + --- + * 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) + diff --git a/Commodore/DISK.TXT b/Commodore/DISK.TXT new file mode 100644 index 0000000..8635aab --- /dev/null +++ b/Commodore/DISK.TXT @@ -0,0 +1,791 @@ + +*** Disk File Layout (D64, D71, D81) +*** Document revision: 1.3 +*** Last updated: March 11, 2004 +*** Compiler/Editor: Peter Schepers +*** Source: Joe Forster/STA (internal rev 0.10) + +Introduction +------------ + + This document describes how Commodore drives lay out files when saving +them onto the disk. It does not describe how the Commodore disk or the BAM +is laid out or how you can manage it, you can read that in another +document. The description also covers GEOS, which uses its own layout +scheme for saving files onto disks. Note that Commodore 1541, 1571 and 1581 +drives all use the same scheme, but with different parameters. + + The Pascal source below was verified against real disks written by real +drives and proved to lay out files exactly the same way as Commodore drives +and GEOS do. It has been translated into C, as well. These algorithms may +be too complicated for your particular needs because they take so many +parameters into account. Feel free to strip off whatever you don't need. + + Please, note that, while the algorithms simulate the real behavior +exactly, the reason for this behavior is not always fully known. As you +will find below, sometimes we can only assume the reason. If you think +these assumptions are incorrect then, please, tell us. We'll be more than +happy to discuss and, possibly, include it. + + + + +Finding the first block +----------------------- + + Commodore drives, as most floppy drives, have a relatively slow head +movement. To speed up data access, it's certainly a good idea to put the +directory into the center of the disk so that, when moving the head from +the directory area to the actual file data and back, head movement is +minimized. On Commodore disks, the directory is on the central track: this +is track 18 on 1541 disks, track 18 and track 53 (the flip side of track +18) on double-sided 1571 disks, and track 40 on 1581 disks. + + When trying to find a free sector for the first block of the file, the +drive first searches on the track just "below" the directory track, then +the track just "above" the directory track, then 2 below, 2 above, etc., +moving away from the directory track. This assures that the first block of +the file will be as close to the directory track as possible. Again, this +minimizes head movement. + + When a track is found, that contains one or more free sectors, then the +drive simply grabs the first free sector on that track, starting with +sector zero and going upwards, and allocates it for the first block of the +file. + + If there are no free sectors left then you get the '72,DISK FULL,00,00' +error message. If a track is found, whose "number of free sectors" counter +in the BAM is not zero, but the sector allocation bitmap shows no free +sectors then the BAM is damaged. It is highly recommended that you check +the BAM prior to saving files onto the disk, and refuse to do anything if +you find such inconsistensies. The BAM should be repaired, for example with +a validate, first. + + + + +Finding the next block +---------------------- + + There's another algorithm for finding successive sectors for the file. It +is executed each time whenever a new sector is needed to hold file data. +The algorithm makes use of an interesting parameter, the "interleave". +Because transferring data to the host machine is so slow, the drive +shouldn't lay out data of the same file sequentially onto sectors of the +same track. If it wrote the first block of data onto sector zero and then +second block onto sector one etc. then, while it is sending data read from +sector zero to the host machine, the disk would keep spinning and sector +one would leave the read/write head. As soon as the data transmission ends, +the drive would try to read sector one, to get the next block of data, and +it would find that it has to wait about half a revolution for sector one to +appear again under the read/write head. Therefore, data shouldn't be laid +out sequentially but, rather, there should be "holes" between successive +blocks of the same file. Of course, this doesn't mean holes with no data +inside. It only means that data is laid out e.g. onto each even sector: +sector zero, then sector two, four etc. Then the drive will have time, +while sector one, three and five is under the read/write head, to send the +contents of sector zero, two and four to the host machine. When the end of +the track is reached, you start again with odd sectors - after all, a track +is an endless circle - and fill in the holes you made by using every second +sector only. + + The distance of successive blocks is what we call "interleave". On some +disks, physical sectors are laid out in a non-sequential manner, that's a +"hard" interleave. Commodore drives do lay out physical sectors in a +sequential manner but they put data onto them in a non-sequential order, +that's a "soft" interleave. In the example above, we were using a soft +interleave of two, that is, the distance between two successive blocks of +the same file was two sectors. + + The optimal interleave for a disk highly depends on how fast data can be +transmitted to the host machine. For a high transmission rate, the +interleave can be smaller because not much time is needed to transfer the +contents of the current sector, therefore successive sectors may be closer +to each other. For a low transmission rate, such as the default of +Commodore drives, a higher interleave is needed. In particular, 1541 drives +are using an interleave of 10 sectors, 1571 drives use 6 sectors and 1581 +drives use 1 sector, by default. The reason for the latter is that 1581 +drives contain a track cache, they can read in a whole track of data and +then transmit data right from the memory to the host machine, without +having to actually access the disk. In this case, there's no real need for +an interleave, sectors may be laid out in a sequential manner - which +corresponds with an interleave value of one - without any possible +performance penalty. + + So, when the drive finished writing the current block of a file and there +still are free sectors left on the current track, it tries to continue with +the sector that is an "interleave" number of sectors away from the current +one. It adds the interleave to the current sector number. If it runs off +the current track - the sector number becomes invalid - then it subtracts +the number of sectors on the track, which will correct the result. If the +corrected result is not sector zero then it subtracts one more. This is, +most probably, some kind of an empirical optimization, because the gap +between the last and first sector on a track is always a bit longer than +the other gaps. + + If the sector, the drive arrived at this way, is free then it already has +the sector it needs. If it's used, however, then the drive keeps searching +for free sectors, starting from this sector, at steps of one. It searches +towards the end of the track, then wraps back to sector zero and moves +further upwards. As the BAM stated that there are still free sectors on the +current track, it shouldn't arrive back at the sector it started from. If +it does then the BAM is damaged. + + If the current track is already full then the drive moves one track away +from the directory track but keeps the sector number used on the previous +track. If there are some free sectors on this new track then the drive +tries to find a free sector, using the method described in the previous +paragraphs, including adding the interleave to the sector number first. The +reason for this, most probably, is that sectors of the same sector number +are at about the same angle on all tracks. Therefore, when you finished +writing sector zero on a track and move to an adjacent track then you'll, +probably, read sector one as the first sector that arrives under the +read/write head on that track. This means, you can keep adding the +interleave, as if you were still on the same track. + + If, while moving away from the directory track, the algorithm runs off +the disk, it tries again on the other half of the disk. If it stepped off +track one downwards then it tries again with the track just above the +directory track, going upwards. If it stepped off the highest track upwards +then it tries again with the track just below the directory track, going +downwards. Therefore, at least, two tries should be made: on the current +half of the disk and the other half. For some unknown reason, Commodore +1541 drives do three tries, which the algorithm below follows. When jumping +to the other half of the disk, the sector number is zeroed. The reason for +this, probably, is that moving the read/write head to such a great distance +takes away so much time that there's no telling which sector it will read +first, arriving at the destination track, so there's no point keeping the +previous sector number. + + An extra feature of the algorithms below is that you can also save file +data onto free sectors of the directory track. The directory track will be +used only if all other parts of the disk are completely full. Apart from +this, everything above applies to the directory track, as well. + + It's worth mentioning that this "finding the next block" algorithm is +used also for finding the next block for the directory, when extending it. +The only difference is that, in this case, a lower interleave of 3 sectors +is used by 1541 and 1571 drives, by default, because no data transmission +to the host machine is involved while processing the directory data. 1581 +drives, as usual, use an interleave of 1 sector. + + + +--------------------------------------------------------------------------- + + +GEOS +---- + + GEOS works quite differently from the original drive DOS. It starts +saving files on track one and goes upwards until it fills up the last +track. On its way, of course, it skips the directory tracks. Actually, it +uses the same algorithm for finding the first and the next sectors for a +file and even for extending the directory, too. + + Because it has a built-in fast loader, it uses an interleave different +from the original: 8 sectors for 1541 disks. As tests show, it uses the +original interleave of 6 sectors for 1571 disks and 1 sector for 1581 +disks, perhaps, because these drives are fast enough anyway. The same +applies for extending the directory which is, again, handled by the same +algorithm, probably, because directory data has to be transferred to the +host machine as it is processed by the GEOS disk driver rather than the +drive itself. + + GEOS also introduces some kind of a "sector skewing". Unlike on normal +Commodore disks, sectors of the same sector number but on different tracks +are not at the same angle on the disk. As you move away from a certain +track, sector zero also slides away in one direction. The distance, +measured by the difference in the sector number, of sectors at about the +same angle on adjacent tracks is the "skew" value. Again, if this applies +to physical sectors than that's a "hard" skew. For logical sectors - +successive blocks of the same file -, that's a "soft" skew. The skew value +used by GEOS is computed by a relatively complicated formula: "track +distance" * 2 + 4 + "interleave". + + When stepping onto a new track, GEOS tries to save the next block of file +data onto the sector whose sector number is equal to the result of the +above formula. (Strangely enough, the result is not added to the sector +number but rather assigned to, so it might not be a sector skew, after +all.) If this sector is already used then, similarly to the original drive +DOS, GEOS goes through the track sequentially, at steps of one, and +searches for the first free sector after this one. + + + +--------------------------------------------------------------------------- + + +Pascal source +------------- + +{=== Start of Pascal source ==============================================} + +{--- Global variables ---} + +var +{When True, this is a GEOS-formatted disk, therefore, files have to be + saved the GEOS way onto it} + GEOSFormat, +{When True, free sectors on the directory track are also allowed to hold + file data if the disk otherwise gets full} + CopyToDirTrack: Boolean; +{Track number of current block of file} + Track, +{Sector number of current block of file} + Sector, +{Track number of first track (may be above one for subdirectories on 1581 + disks)} + FirstTrack, +{Track number of last track plus one (may be below the physical end of + disk for subdirectories on 1581 disks)} + LastTrack, +{Track number of physically last track plus one} + MaxTrack, +{Track number of directory track} + DirTrack, +{Track number of secondary directory track (for 1571 disks); 255 (a + non-existent track), if not available} + DirTrack2, +{Soft interleave} + Interleave: Byte; + +{--- Support routines ---} + +{Determine if there's, at least, one free sector on a track + Input : Track: the track to check + Output: when True, there's, at least, one free sector on the track} +function IsTrackFree(Track: Byte): Boolean; + +{Determine if a sector is free + Input : Track: the track number of sector to check + Sector: the sector number of sector to check + Output: when True, the sector is free; otherwise used} +function IsSectorFree(Track, Sector: Byte): Boolean; + +{Determine the number of sectors (or the highest valid sector number + plus one) for a track + Input : Track: track number + Output: the number of sectors on the track} +function SectorNum(Track: Byte): Byte; + +{--- Implementation of algorithms ---} + +{Prototype for NextCopyBlock} +function NextCopyBlock: Boolean; + +{Find a sector for the first block of the file, using variables Track and + Sector + Output: when True, a sector was found; otherwise no more sectors left} +function FirstCopyBlock: Boolean; +var + Found: Boolean; + MaxSector, + Distance: Byte; +begin +{We found no free sector yet} + Found := False; +{If this is a GEOS-formatted disk then use the other routine, from track + one upwards} + if GEOSFormat then + begin + Track := 1; + Sector := 0; + Found := NextCopyBlock; + end + else + begin +{If it's a normal disk then we start off with tracks just besides the + directory track} + Distance := 1; +{Search until we find a free block or moved too far from the directory + track} + while not Found and (Distance < 128) do + begin +{Check the track below the directory track first} + Track := DirTrack - Distance; +{If the track is inside the valid range then check if there's a free + sector on it} + if (Track >= FirstTrack) and (Track < LastTrack) then + Found := IsTrackFree(Track); + if not Found then + begin +{If no luck then check the track above the directory track} + Track := DirTrack + Distance; +{If the track is inside the valid range then check if there's a free + sector on it} + if Track < LastTrack then Found := IsTrackFree(Track); + end; +{If no luck either then move one track away from the directory track and + try again} + if not Found then Inc(Distance); + end; +{If the whole disk is full and we're allowed to use the directory track + for file data then try there, too} + if not Found and CopyToDirTrack then + begin + Track := DirTrack; + Found := IsTrackFree(Track); + end; +{If we finally found a track with, at least, one free sector then search + for a free sector in it} + if Found then + begin +{Determine how many sectors there are on that track} + MaxSector := SectorNum(Track); +{Start off with sector zero} + Sector := 0; + repeat +{Check if the current sector is free} + Found := IsSectorFree(Track, Sector); +{If it isn't then go on to the next sector} + if not Found then Inc(Sector); +{Repeat the check until we find a free sector or run off the track} + until Found or (Sector >= MaxSector); + end; + end; +{Return the search result} + FirstCopyBlock := Found; +end; + +{-------------------------------------------------------------------------} + +{Find a sector for the next block of the file, using variables Track and + Sector + Output: when True, a sector was found; otherwise no more sectors left} +function NextCopyBlock: Boolean; +var + Found: Boolean; + Tries, + MaxSector, + CurSector, + CurTrack: Byte; +begin + if (Track = 0) or (Track >= MaxTrack) then + begin +{If we somehow already ran off the disk then there are no more free + sectors left} + NextCopyBlock := False; + end + else + begin +{Set the number of tries to three} + Tries := 3; +{We found no free sector yet} + Found := False; +{Remember the current track number} + CurTrack := Track; +{Keep trying until we find a free sector or run out of tries} + while not Found and (Tries > 0) do + begin +{Get the number of sectors on the current track} + MaxSector := SectorNum(Track); +{If there's, at least, one free sector on the track then get searching} + if IsTrackFree(Track) then + begin +{If this is a non-GEOS disk or we're still on the same track of a + GEOS-formatted disk then...} + if (Track = CurTrack) or not GEOSFormat then + begin +{Move away an "interleave" number of sectors} + Inc(Sector, Interleave); +{Empirical GEOS optimization, get one sector backwards if over track 25} + if GEOSFormat and (Track >= 25) then Dec(Sector); + end + else + begin +{For a different track of a GEOS-formatted disk, use sector skew} + Sector := (Track - CurTrack) shl 1 + 4 + Interleave; + end; +{If we ran off the track then correct the result} + while Sector >= MaxSector do + begin +{Subtract the number of sectors on the track} + Dec(Sector, MaxSector); +{Empirical optimization, get one sector backwards if beyond sector zero} + if (Sector > 0) and not GEOSFormat then Dec(Sector); + end; +{Remember the sector we finally arrived at} + CurSector := Sector; + repeat +{Check if the current sector is free} + Found := IsSectorFree(Track, Sector); +{If it isn't then go to the next sector} + if not Found then Inc(Sector); +{If we ran off the track then wrap around to sector zero} + if Sector >= MaxSector then Sector := 0; +{Keep searching until we find a free sector or arrive back at the + original sector} + until Found or (Sector = CurSector); + end + else + begin +{If the current track is used up completely then...} + if GEOSFormat then + begin +{Move one track upwards on a GEOS-formatted disk} + Inc(Track); +{Skip the directory tracks on the way} + if (Track = DirTrack) or (Track = DirTrack2) then Inc(Track); +{If we ran off the disk then there are no more tries} + if Track = LastTrack then Tries := 0; + end + else + begin +{If we already tried the directory track then there are no more tries} + if Track = DirTrack then + begin + Tries := 0; + end + else + begin + if Track < DirTrack then + begin +{If we're below the directory track then move one track downwards} + Dec(Track); + if Track < FirstTrack then + begin +{If we ran off the disk then step back to the track just above the + directory track and zero the sector number} + Track := DirTrack + 1; + Sector := 0; +{If there are no tracks available above the directory track then there + are no tries left; otherwise just decrease the number of tries} + if Track < LastTrack then Dec(Tries) else Tries := 0; + end; + end + else + begin +{If we're above the directory track then move one track upwards} + Inc(Track); +{Skip the secondary directory track on the way} + if Track = DirTrack2 then Inc(Track); + if Track = LastTrack then + begin +{If we ran off the disk then step back to the track just below the + directory track and zero the sector number} + Track := DirTrack - 1; + Sector := 0; +{If there are no tracks available below the directory track then there + are no tries left; otherwise just decrease the number of tries} + if Track >= FirstTrack then Dec(Tries) else Tries := 0; + end; + end; + end; + end; + end; + if not Found and (Tries = 0) and (Track <> DirTrack) and + CopyToDirTrack then + begin +{If we haven't found any free sector, ran out of tries and haven't tried + the directory track yet, although it's declared as available for file + data, then give the directory track an extra try} + Track := DirTrack; + Inc(Tries); + end; + end; +{Return the search result} + NextCopyBlock := Found; + end; +end; + +{=== End of Pascal source ================================================} + + + +--------------------------------------------------------------------------- + + +C source +-------- + +/* === Start of C source =============================================== */ + +/* Type definitions */ + +#define byte unsigned char +#define boolean unsigned char +#define true (0 == 0) +#define false (0 == 1) + +/* --- Global variables --- */ + +boolean +/* When true, this is a GEOS-formatted disk, therefore, files have to be + saved the GEOS way onto it */ + GEOSFormat, +/* When true, free sectors on the directory track are also allowed to hold + file data if the disk otherwise gets full */ + CopyToDirTrack; +byte +/* Track number of current block of file */ + Track, +/* Sector number of current block of file */ + Sector, +/* Track number of first track (may be above one for subdirectories on 1581 + disks) */ + FirstTrack, +/* Track number of last track plus one (may be below the physical end of + disk for subdirectories on 1581 disks) */ + LastTrack, +/* Track number of physically last track plus one */ + MaxTrack, +/* Track number of directory track */ + DirTrack, +/* Track number of secondary directory track (for 1571 disks); 255 (a + non-existent track), if not available */ + DirTrack2, +/* Soft interleave */ + Interleave; + +/* --- Support routines --- */ + +/* Determine if there's, at least, one free sector on a track + Input : Track: the track to check + Output: when true, there's, at least, one free sector on the track */ +boolean IsTrackFree(byte Track); + +/* Determine if a sector is free + Input : Track: the track number of sector to check + Sector: the sector number of sector to check + Output: when true, the sector is free; otherwise used */ +boolean IsSectorFree(byte Track, byte Sector); + +/* Determine the number of sectors (or the highest valid sector number + plus one) for a track + Input : Track: track number + Output: the number of sectors on the track */ +byte SectorNum(byte Track); + +/* --- Implementation of algorithms --- */ + +/* Prototype for NextCopyBlock() */ +boolean NextCopyBlock(); + +/* Find a sector for the first block of the file, using variables Track and + Sector + Output: when true, a sector was found; otherwise no more sectors left */ +boolean FirstCopyBlock() +{ + boolean Found; + byte MaxSector, + Distance; +/* We found no free sector yet */ + Found = false; +/* If this is a GEOS-formatted disk then use the other routine, from track + one upwards */ + if (GEOSFormat) + { + Track = 1; + Sector = 0; + Found = NextCopyBlock(); + } + else + { +/* If it's a normal disk then we start off with tracks just besides the + directory track */ + Distance = 1; +/* Search until we find a free block or moved too far from the directory + track */ + while (!Found && (Distance < 128)) + { +/* Check the track below the directory track first */ + Track = DirTrack - Distance; +/* If the track is inside the valid range then check if there's a free + sector on it */ + if ((Track >= FirstTrack) && (Track < LastTrack)) + Found = IsTrackFree(Track); + if (!Found) + { +/* If no luck then check the track above the directory track */ + Track = DirTrack + Distance; +/* If the track is inside the valid range then check if there's a free + sector on it */ + if (Track < LastTrack) Found = IsTrackFree(Track); + } +/* If no luck either then move one track away from the directory track and + try again */ + if (!Found) Distance++; + } +/* If the whole disk is full and we're allowed to use the directory track + for file data then try there, too */ + if (!Found && CopyToDirTrack) + { + Track = DirTrack; + Found = IsTrackFree(Track); + } +/* If we finally found a track with, at least, one free sector then search + for a free sector in it */ + if (Found) + { +/* Determine how many sectors there are on that track */ + MaxSector = SectorNum(Track); +/* Start off with sector zero */ + Sector = 0; + do + { +/* Check if the current sector is free */ + Found = IsSectorFree(Track, Sector); +/* If it isn't then go on to the next sector */ + if (!Found) Sector++; +/* Repeat the check until we find a free sector or run off the track */ + } while (!Found && (Sector < MaxSector)); + } + } +/* Return the search result */ + return(Found); +} + +/* --------------------------------------------------------------------- */ + +/* Find a sector for the next block of the file, using variables Track and + Sector + Output: when true, a sector was found; otherwise no more sectors left */ +boolean NextCopyBlock() +{ + boolean Found; + byte Tries, + MaxSector, + CurSector, + CurTrack; + if ((Track == 0) || (Track >= MaxTrack)) + { +/* If we somehow already ran off the disk then there are no more free + sectors left */ + return(false); + } + else + { +/* Set the number of tries to three */ + Tries = 3; +/* We found no free sector yet */ + Found = false; +/* Remember the current track number */ + CurTrack = Track; +/* Keep trying until we find a free sector or run out of tries */ + while (!Found && (Tries > 0)) + { +/* Get the number of sectors on the current track */ + MaxSector = SectorNum(Track); +/* If there's, at least, one free sector on the track then get searching */ + if (IsTrackFree(Track)) + { +/* If this is a non-GEOS disk or we're still on the same track of a + GEOS-formatted disk then... */ + if ((Track == CurTrack) || !GEOSFormat) + { +/* Move away an "interleave" number of sectors */ + Sector += Interleave; +/* Empirical GEOS optimization, get one sector backwards if over track 25 */ + if (GEOSFormat && (Track >= 25)) Sector--; + } + else + { +/* For a different track of a GEOS-formatted disk, use sector skew */ + Sector = ((Track - CurTrack) << 1) + 4 + Interleave; + } +/* If we ran off the track then correct the result */ + while (Sector >= MaxSector) + { +/* Subtract the number of sectors on the track */ + Sector -= MaxSector; +/* Empirical optimization, get one sector backwards if beyond sector zero */ + if ((Sector > 0) && !GEOSFormat) Sector--; + } +/* Remember the sector we finally arrived at */ + CurSector = Sector; + do + { +/* Check if the current sector is free */ + Found = IsSectorFree(Track, Sector); +/* If it isn't then go to the next sector */ + if (!Found) Sector++; +/* If we ran off the track then wrap around to sector zero */ + if (Sector >= MaxSector) Sector = 0; +/* Keep searching until we find a free sector or arrive back at the + original sector */ + } while (!Found && (Sector != CurSector)); + } + else + { +/* If the current track is used up completely then... */ + if (GEOSFormat) + { +/* Move one track upwards on a GEOS-formatted disk */ + Track++; +/* Skip the directory tracks on the way */ + if ((Track == DirTrack) || (Track == DirTrack2)) Track++; +/* If we ran off the disk then there are no more tries */ + if (Track == LastTrack) Tries = 0; + } + else + { +/* If we already tried the directory track then there are no more tries */ + if (Track == DirTrack) + { + Tries = 0; + } + else + { + if (Track < DirTrack) + { +/* If we're below the directory track then move one track downwards */ + Track--; + if (Track < FirstTrack) + { +/* If we ran off the disk then step back to the track just above the + directory track and zero the sector number */ + Track = DirTrack + 1; + Sector = 0; +/* If there are no tracks available above the directory track then there + are no tries left; otherwise just decrease the number of tries */ + if (Track < LastTrack) Tries--; else Tries = 0; + } + } + else + { +/* If we're above the directory track then move one track upwards */ + Track++; +/* Skip the secondary directory track on the way */ + if (Track == DirTrack2) Track++; + if (Track == LastTrack) + { +/* If we ran off the disk then step back to the track just below the + directory track and zero the sector number */ + Track = DirTrack - 1; + Sector = 0; +/* If there are no tracks available below the directory track then there + are no tries left; otherwise just decrease the number of tries */ + if (Track >= FirstTrack) Tries--; else Tries = 0; + } + } + } + } + } + if (!Found && (Tries == 0) && (Track != DirTrack) && CopyToDirTrack) + { +/* If we haven't found any free sector, ran out of tries and haven't tried + the directory track yet, although it's declared as available for file + data, then give the directory track an extra try */ + Track = DirTrack; + Tries++; + } + } +/* Return the search result */ + return(Found); + } +} + +/* === End of C source ================================================= */ + +History: + 2000-05-05 0.01 Initial internal release + 2000-05-08 0.02 New: Translated the Pascal source to C + New: Separated text into numbered sections + Mod: Changed wording to make it more understandable + 2000-06-29 0.03 Fix: Fixed a couple of typos + 2000-07-28 0.04 Mod: Changed some wording again + 2000-11-05 0.05 Fix: Fixed some syntactical errors in the C source + 2001-02-22 0.10 Fix: Fixed some typos + Fix: Bytes, booleans are unsigned chars in C source + diff --git a/Commodore/F64.TXT b/Commodore/F64.TXT new file mode 100644 index 0000000..3158242 --- /dev/null +++ b/Commodore/F64.TXT @@ -0,0 +1,196 @@ + +*** F64 (a companion file to certain D64's) +*** Document revision: 1.6 +*** Last updated: March 19, 2004 +*** Compiler/Editor: Peter Schepers +*** Contributors/sources: Christian Link, + Joe Forster/STA + + Created by a program called FCOPY-PC, written by M. Edzes in the early +1990's and based on a hack of the 1541 copy program called FCOPY III +written by Thomas Templemann, these files contain some extra information +about the associated D64 files like the low-level disk ID, sector checksum, +valid sector flag and sector header ID. These files are very rare, and are +only found on a CD called "C64 CD 96", also known as the "Unicorn" CD +available from the Whiz-zards group. + + Some of what you are about to read is pure conjecture on the part of the +author to explain what these files are. Some of the explanation regarding +this file description comes from documentation provided by Joe Forster/STA, +and much of it comes from the experiments that the author of these +documents has conducted. + + They all appear to be the same size, 2051 bytes, and seem to start with +the DISK ID from the D64 image. The F64 definition only encompasses +standard 35-track disk images. No consideration was made for 40-track +images. + + 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 is the sector status code, representing whether the + sector is ok, empty, or contains an error. This value can be + one of the following characters (excluding the quotes) + "+-?HLICFSP". The number in brackets following the "error xx" + is the value used for a D64 error block. + + '+' (0x2B) : The sector is ok (D64 code 1) + + '-' (0x2D) : The sector is ok (D64 code 1), but is empty + (contains the $xx $01 $01... format pattern) + + '?' (0x3F) : The sector cannot be found. No evidence that it + exists at all. Convert this to 'H' error 20 (D64 + code 2) + + 'H' (0x48) : Error 20 (D64 code 2). No header ID can be found + for the sector. + + 'L' (0x4C) : Error 21 (D64 code 3). There is no SYNC mark on + the track. + + 'I' (0x49) : Error 22 (D64 code 4). The data descriptor byte + (byte $01) has an incorrect value. This error + will also come with a invalid value for byte $01. + + 'C' (0x43) : Error 23 (D64 code 5). The data block checksum is + wrong. This error will also come with an + incorrect value for byte $02. + + 'F' (0x46) : Means a "killer track" (whole track filled with + SYNC marks). Only one sample disk has this error + on it. + + 'H' (0x48) : Error 27 (D64 code 9). The sector header checksum + is wrong. Note that 'H' also represents Error 20. + + 'S' (0x53) : Unknown. No sample files exist and the source + code doesn't explain it. Possibly a "verify" + error, which isn't useful here. + + 'P' (0x50) : Unknown. No sample files exist, and the source + code doesn't explain it. Possibly another + "verify" error, which isn't useful here. + + 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 data block checksum for the sector. It is + arrived at by XOR'ing all 256 data bytes, 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). + + One aspect that is unknown is the nature of the sector data when no data +is sent. Only three codes send valid sector data ('+', 'C' and 'I'). The +rest send an "empty" sector (filled with $01). However, the first byte is +not always $4B as it would be with a standard 1541 format. I've seen $01, +$41 (A) and $4B (K). If they represent something, I don't know. + + The two bytes following the F64 code should be incorporated back into +sector when an attempt is made to convert an F64/D64 image to a GCR-based +image (G64, ZipCode Sixpack). However, not all is understood about how to +actually do that because they have not been fully decoded yet. The 'I' and +'C' codes are easy as the ID and checksum values can be used to construct +the data portion. However, constructing the header (for error code 'H') +from the two bytes is more difficult as they always seem to be ID $07 and +checksum $01. + + It is important to note that error 29 cannot be represented by F64, and +this is a serious limitation. There is no way to do so because the +individual sector ID's are not stored in the F64 file. Not only that but +the original program FCOPY III that FCOPY-PC is based on doesn't detect +them either. FCOPY III simply reads the header, if possible, and copies it +to a destination disk. No checking of the header ID's was done (because +track 18/0 is not read prior to copying the disk). Error 29 is actually a +valid header since there is both a header ID and a valid checksum. + + Also important is the dual nature of the 'H' header error code for both +error 20 and 27. In tests that were conducted using both single-sector and +full-track errors of 20 and 27, it is somewhat possible to tell the +difference on full-track errors only. Full track error 20 always puts an +'H' code on sector 0, and '?' codes for the rest of the track. +Single-sector error 20's are always an 'H'. Full-track error 27s always +have the 'H' code _not_ on sector 0, and the rest of the track filled with +'?' codes. This is by no means a definitive way to tell them apart, but +simply based on observation. + +----- + + Below are the notes that I took regarding the error codes as my +investigation proceeded. It might prove to be an interesting read. + + + + According to the FCOPY source code, these errors have valid sector data +sent: + + + : Sector is OK (no errors) and read intact. It doesn't have to match + the BAM entry and it sometimes exists when the sector is filled with + 0x01, appearing to be empty. + + C : Error 23 "Bad Data Checksum". Always with a ID 7 and a bad data + checksum value. Use the data ID and the checksum when constructing a + sector destined for GCR, + + I : Error 22 "Data ID not found". Both the ID and checksum values can be + anything and the sector doesn't always seem to have any useful data + in it. Source code says "header chksum" bad. + + According to the source code, these errors have no valid sector data sent +(sends an empty sector, xx 01 01 01...): + + - : Sector has no data in it (xx 01 01) but it doesn't always mean the + sector is not used and it doesn't have to match the BAM. You do not + have to use the values in the ID and checksum bytes as they are + valid. + + H : Error 20 "Header ID not found" & Error 27 "Bad Header Checksum". + Always with an ID 7 and a checksum of 1. Source simply says "bad + header". Didn't find the 0x52 header ID or because there's a bad + checksum the contents of the header are unreliable and discarded. + Error 27 covers the entire track, but error 20 can exist on one + sector. When an entire track of error 20 occurs, the 'H' error is on + the first sector. When an entire track of 27 occurs, 'H' is somewhere + else (typically sector 3-4) + + L : Error 21 "No SYNC mark found". Always on sector 0, and preceeds an + entire track of '?'. Is with ID 7 and checksum 1) + + ? : No sector header/data could be read, no evidence that the sector + existed. Doesn't have to fill a track. Is typically with ID 7 and + checksum 1. Recommend to change this to an error 20, except when with + an 'L' or 'F' code. + + F : Always on sector 0 and preceeds an entire track of '?'. Looks very + similar to L (Disk1932 from the CD 64CD96 is the only sample of 'F' + errors). This could be a 'killer track' + + S : Haven't seen it yet. Source only refers to it. Might be a "verify" + error + + P : Haven't seen it yet. Source only refers to it. Might be a "verify" + error + diff --git a/Commodore/F64.html b/Commodore/F64.html new file mode 100644 index 0000000..920949b --- /dev/null +++ b/Commodore/F64.html @@ -0,0 +1,404 @@ + + + + + + + + + + +Decoding the F64 Filetype + + + + + + + + + + + + + +
+ +

64Copy Central

+ +
+ + + + + + + +
+ +

Decoding the F64 filetype

+ +
+ +

Written by Peter Schepers on March 12, 2004 - Last updated Oct 4, 2007

+ +

Some History

+ +

Already several years ago (likely around 2000) I was asked to include F64 error conversion in 64COPY. The trouble was that F64’s were very rare, and at that time I had no samples of them. They were only available from one specific CD called C64CD96, or the Unicorn CD. It was compiled by the Whiz-zards from the Netherlands using a program called FCOPY-PC which required special cabling between a PC, C64 and the 1541. Needless to say it didn’t seem too critical to try to include the conversion since only one source of them existed. However, the CD holds over 5500 D64 images, and all of them have an F64 file. 

+ +

I contacted Joe Forster/STA to inquire if he had any experience with F64. He did not, but immediately acquired the software and set out looking over the code. We exchanged a few emails, and came up with a few educated guesses about some of the layout, but much of it was still a mystery. Joe wrote up the F64Check program (available from his site) to aid in the discovery of the layout.

+ +

One 64COPY user (and I wish I could remember who it was) sent me the C64CD96 CD to help me in the decoding. After writing my own CheckF64 routine, I isolated all the disk images with errors, especially the ones with ‘L’, ‘F’ and ‘H’.

+ +

The F64 format was likely developed by the Whiz-zards as an extension to the D64 format. The error byte version of the D64 was not likely in wide use then, so they came up with their own. They hacked the FCOPY-III copying software so that all it did was read an entire disk, and send the sector data and the on-screen C64 error codes (along with two extra bytes) back the PC. It sounded like a good idea, but there were some big limitations to this approach:

+ +
    + +
  • FCOPY III can’t detect an error 29, and therefore neither does FCOPY-PC
  • + +
  • It doesn’t differentiate between error 20 (bad ID) and 27 (bad checksum, both header errors)
  • + +
+ +

Error 29 requires that you know the master ID’s of the disk you are reading but FCOPY-III doesn’t read them from track 18 before copying the disk. Error 20 and 27 are both header errors, so there wasn’t a need to show them differently. FCOPY-III simply wrote out the headers and sectors as it had read them. So while it reported that “an error” had occurred while reading a track/sector by writing an error code to the C64 screen, what made the error (the header itself) special was hidden in the header or sector data. The Whiz-zards didn’t take this into account and so it is hard to know what error to use (27 or 20) when the ‘H’ code is encountered.

+ +

The layout of the F64 file is deceptively simple. There’s 2 bytes at the beginning of the file which are the master disk format ID’s and then each sector has a 3-byte description: an error byte and two others which appear to be the low-level data block ID and data block checksum. The hard part was to understand what the error code meant, if the two bytes following the error code changed depending on the error code, and how to recombine the codes to produce a reasonably accurate destination file.

+ +

 

+ +

Some Time Later

+ +

Around January 2004 I started the daunting task of writing the conversion code which would handle most of the remaining formats that 64COPY was not converting yet, specifically between the GCR formats, as well as the F64/D64 combination. Doing this required that the F64 error bytes be understood. I checked Joe’s website, acquired the latest version of his F64 documentation, but I didn’t agree with it as some of the error codes and the errors they were assigned to didn’t make sense with some of my early experiments.

+ +

On Wolfgang Moser’s site is contained source code for various hacked editions of FCOPY, and FCOPY-PC. They are not very well commented, but they certainly helped. Pouring over them helped link the ‘L’ and ‘F’ errors together, and they also commented on the ‘P’ and ‘S’ codes, but that was all I could get out of them. I never worked with 1541 drive code at the level that FCOPY does, so I didn’t fully understand what the code was doing.

+ +

At this point I realized I would need to construct the setup necessary for using Markus Brenner’s MNIB utility, Joe Forsters/STA Star Commander and the Whiz-zards FCOPY-PC. I would have to pull my C64 out of mothballs, build all the cables, install parallel ports in my 1541’s (all three of them, just to be safe), and acquire all the software that would be needed to fulfill this task. I went to Joe’s page again, downloaded all the utilities I thought I would need, and also printed off all the cable building documents I would need. His site is an invaluable resource!

+ +

Installing the parallel port in a 1541 is not too hard if you know how to solder, follow good ESD (electro-static discharge) procedures and have access to the needed parts. Being a 20-year veteran hardware technician made things easier, and the ports were neatly installed in a few hours. The book The Complete Commodore Innerspace Anthology from the publisher of Transactor magazine is also a very handy reference when needing to check on anything Commodore, and in this case checking the chip pinouts in the drive to make sure I was soldering to the right pins on the VIA.

+ +

Building the FCOPY-PC cable is a little more difficult in that it needs more components (3 connectors, two cables and 4 resistors) but it was easily done. Building the XEP1541 parallel cable from the PC to the 1541 that MNIB and Star Commander needed to be able to read disks was the most difficult, but still doable. Star Commander doesn’t require this cable, but it definitely works much faster with it. The XEP cable requires a few specialized Schottky barrier rectifier diodes, but any reputable electronics supply shop can get them. Otherwise, simply buy the cable from Joe’s site. Building the parallel cable from the C64 to the 1541 that FCOPY-PC and FCOPY-III need can be the most difficult because you need a user port connector, not something readily available anymore. I managed to pull one off of an old C64 user-port cartridge I had kept all these years.

+ +

One word of warning: the documentation that comes with FCOPY-PC for building the parallel cable (from the 1541 drive to the C64) is wrong. Do not use it, as it connects to the incorrect pins on the VIA in the drive! Joe’s Star Commander site documents the proper way to build a parallel port into the drive, including the correct pins on the VIA, and how to build a cable to the PC.

+ +

After getting all the cables built, getting all the software together and finding my stash of original C64 disks, I was ready to roll. I shut down my home PC (a Pentium 3, 800Mhz Intel CPU with ASUS CUSL2 board), hooked up the XE1541 parallel cable to the drive, and started Star Commander. It didn’t work! It kind-of talked to the drive, but would hang all the time. I pulled out my X1541 cable that I had built several years ago… it didn’t work, same problem. Frustration was setting in.

+ +

I checked the configuration settings for Star Commander, I changed the parallel port modes (SPP, ECP, EPP), but nothing worked. I spent several hours diagnosing and checking but nothing could talk to the drive properly. Even MNIB didn’t work, although it claimed to see the drive and the parallel cable. Joe’s XEP1541 documentation does mention that the parallel port on some mainboards won’t work with this cable, and you need the XA1541 or XAP1541 cable instead. I didn’t want to build another cable as the XAP variant requires some very specialized transistors. I decided that using another machine would be easier. I borrowed a Pentium 233Mhz and it worked fine! Things were finally getting somewhere. (Someday, maybe, I will build the XAP cable and test it, or try to find out why my mainboard doesn’t like the XEP and X cables.)

+ +

I MNIB’d all the sample disks I had, and created a 1541 disk with the FCOPY software for the C64. Using the VICE C64 emulator, I typed in the sample programs from the book Inside Commodore DOS by Immers/Neufeld for creating errors on a 1541 floppy disk. (I will put this floppy image on-line at another time as I’ve not completely debugged the programs). I figured these programs would prove invaluable as I could create all the errors I need and see what the FCOPY-PC error codes would be.

+ +

Things look like they are going good, right? Nope. Now my C64 proved to be very unstable, and it would crash after only a few minutes of operation. FCOPY would start copying for at most a track and then crash. As I used to be a Commodore-authorized service depot, I still had my C64 diagnostic setup (user-port connection, diagnostic cartridge and port connectors). It also would hang after a few minutes with no errors found. I attempted to find another C64 to work with but they are rare, and the surplus/thrift stores in my area didn’t have anything anymore. Frustration level is starting to rise again! I realized I would have to fix my C64 before I could continue.

+ +

Once again, I went digging through my parts drawers to find my stash of C64 chips. I started to replace them one by one… 6510, 6581, PAL. Things improved a bit, but the machine would stil hang after about 4 minutes. FCOPY-PC worked a little better (it read a few tracks), but still hung. I finally changed the VIC-II chip and now the system worked!!! Time to go to work!

+ +

I started FCOPY’ing all my disks, and was surprised at how many errors they had. Using a parallel connection to the drive was a joy as tracks can be read at an amazing rate! It took a few minutes before I realized that the 1541 I was using was badly out of alignment as disks that I knew were ok were full of various errors. My second drive didn’t work at all (red LED stays on), but my third one worked great. I re-copied the disks and started getting some good results. I also MNIB’d the disks for comparison. The error codes were starting to make sense. I was also very glad that I hadn’t sold all of Commodore equipment as I had planned to a few months before.

+ +

Now I needed a floppy disk that had an established error pattern. I formatted a clean 1541 disk, ran the error-creation programs I had typed in earlier and created an error disk. I copied it with FCOPY-PC and watched the error pattern. It appeared I had finally established the errors for ‘+’, ‘L’, ‘I’, ‘C’ and somewhat for ‘H’, but I still didn’t know what ‘F’ was, nor ‘P’ and ‘S’. I had also mistakenly assigned the ‘-‘ code to error 29 as the only two sectors on my “created” disk with the ‘-‘ code did have error 29 assigned to them.

+ +

I started to write up the changes to my F64.TXT document, but I realized I had made a mistake assigning error 29 to the ‘-‘ code. Many F64 files had ‘-‘ errors and they couldn’t possibly all be error 29! After playing with FCOPY III, the program that FCOPY-PC is based on, I came to the conclusion that error 29 is not detected. An analysis of the sector data being sent back revealed that the ‘-‘ code actually refers to a sector that is filled with $01, like a standard 1541 clean-formatted disk. When this code occurs, very little data is sent back to the C64. This is almost a form of “compression”, allowing FCOPY to copy an entire disk into C64 memory (no disk swaps), provided that most of the disk is empty.

+ +

I also noticed that one of my sample disks had an ‘F’ error that covered several tracks but I still didn’t know what it was. I MNIB’d the disk, and on the ‘F’ tracks MNIB reported ‘Fexact match’ (a very strange response), but the MNIB output was the same for an ‘L’ track. I started wondering if this was a killer track, one that has all SYNC marks, but MNIB wasn’t outputting the correct track data.

+ +

On March 19, 2004 I modified one of the error creation programs to generate a killer track (all SYNC) instead of generating an error 21 (no SYNC). I ran it on a clean formatted disk and used both FCOPY-III and MNIB to read the disk. It confirms that the 'F' code is indeed the killer track error code. This means that my original theory regarding this code was right and I believe this finally ends my investigation of the F64 format.

+ +

 

+ +

Where Things Were Left Off

+ +

This is the condition I have left things. I have basically decoded all the errors except ‘P’ and ‘S’. I don’t believe they are read-error codes, but instead are related to verification when writing the destination disk, and are therefore not applicable.

+ +

One thing has always bothered me from when I first encountered the F64 file, and I wonder if anyone can answer it: Why the severe lack of documentation about the F64 format in the first place? Why would a cracking group like the Whiz-zards take the time to create an elaborate cable setup and application suite to create a special auxiliary file for D64’s and create/sell a CD with over 5500 D64 images on it without actually documenting how to use the F64 file, especially for emulator authors? And why would they not see the inherent limitations of using FCOPY III in the first place with respect to error 29 and 20/27? These limitations should have been addressed.

+ +

I hope I haven’t put anyone to sleep with the length of this write-up, but F64 proved to be one of the most difficult formats to decode, and it is still not entirely understood. As time and sample disks allow, I will attempt to find out even more. My FORMATS.ZIP archive contains the new write-up, or you can view it from here.

+ +

 

+ +

Below is the chart I now use to decode F64 files.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Error Code
Description
+
Sector ok and has data
-
Sector ok, but empty (filled with $01)
C
Error 23 “data checksum” (use the second and third bytes to reconstruct the sector)
L
Error 21 “track has no SYNC mark”
I
Error 22 “data ID missing” (use the second and third bytes to reconstruct the sector)
H
Error 20/27 “Header ID missing” or “Bad header checksum”
F
Killer track (full of SYNC)
S
???, likely a verify error
P
???, likely a verify error
+ +

 

+ +

Update, June 8, 2004

+ +

A user from the Netherlands (Tijs Haeyen?) emailed me after reading this page, wondering why I had gone through all the trouble when I could have simply created a D64/F64 image set with the errors that I want to test, written them to a floppy, then analysed the floppy with MNIB. I didn't understand at first what he meant as how could I write the disk when I couldn't create it, but he proceeded to remind me that the FCOPY-PC utility has the menu option to write out a D64/F64 pair back to a disk. Duh! I didn't even see this option. I could generate an F64 file replete with errors and things likely would have been so much easier. However, I haven't taken up the advice yet.

+ +

 

+ +

Update, Oct 4, 2007

+ +

I received a letter from a member of the Whiz-zards (Guido Gouweloos aka 'Unicorn') from the Netherlands in late 2005 detailing some of the history of FCopy-PC and partially answering my questions. I tried mailing this person with more questions but have never heard back since. I will now include this email (edited) as it fleshes out the history and development of FCopy-PC. His email doesn't fully answer all my questions, at least not to the depth I would like, but it's all I have. My questions that he tackled are in italics:

+ +

"Hi Peter, I just came over your article about F64 files and FCopyPC. My name is Guido Gouweloos, Unicorn of The Whiz-Zards Association. Nice to see you article and all the time you put in this little piece of software that I designed a long way back.

+ +

I'd like to give you some history about FcopyPC. In the first place you should know I only had the idea of the program, I designed the basic functionality and I tested the program (PC and C64). Marco Edzes (Merlin of TWA) adapted FCopy and wrote the C++ PC software. I wrote some tools for F64 and D64 files, but I doubt everything was on the C64CD96 (the disc I compiled). At least I wrote a little program that's not on c64cd96 to display the full F64 on screen. I used the program to make another c64cd, but I never finished that one.

+ +

Somewhere in 1993, I got the idea to copy all my C64 disks to PC/Amiga, only to have that done before the dics would fade away under the influence of magnetic fields etc. I started copying my discs using a transfer program on the Amiga. If I am right this came with one of the commercial c64 emulator packages available. This hooked up a 1541 to an Amiga. This program was very slow (took 10-20 minutes per disk side). I did some hundreds of disks with that program, that also locked up the drive from time to time. And also disks with errors did not work after all. (Also disks without errors sometimes did not work). I did not have Star Commander at that time, and I am not sure if it was out then.

+ +

In that time a still had contact with an old TWA (The Whiz-zards Association) member that was the hardware guru: Marco Edzes. I knew him still from our C64 days (that mostly are from 1984 to 1989). I also knew he made his own 256KB C64 back in the 80's. And I knew he made an adaption of one of the Fcopy programs especially for this 256KB C64. The Fcopy program could read a disk at once, switching between the 64KB banks to put all disk-data in memory, and write back the disk afterwards. He also made a Fcopy version for 2 disk drives (both parallel if I am correct). This is on the c64cd96 too, called 'Double Fcopy'. I think sources are all on the D64 files somewhere.

+ +

I discussed the idea with Marco about a Fcopy program that could do disk transfers to a PC and back. Fcopy looked like a good start, because of the way it handles error copying. Marco thought this way a nice thing to built and he started making it. After a short time he came over to my house with the first version and cable. I started copying and it seemed to work OK. The first version of FcopyPC did not split into 2 separate files. If I remember right I wrote some kind of little tool to extract a D64 from this first file format.

+ +

I transferred around 100 disks from C64 to PC and back, just to test the copy program. Some disks did not seem to work. This was caused by the diskID that was read by the drive on disk insert/reading of the disk. This ID was gone after the copy. Marco fixed this and also made the new version split the files into D64 and F64 at once. The F64 file is just a header, with the diskID, followed by all the data that was generated by Fcopy at the time of read (screen display and some codes per sector). This data was used to transfer the disk back to C64 the way Fcopy would write a disk the original Fcopy Way. So the F64 structure is just a header + ID + dump of the codes Fcopy keeps in memory during copy.

+ +

Why the severe lack of documentation about the F64 format in the first place?

+ +

The only documented versions of Fcopy are the TWA versions. Maybe some guys adapted this over the years, I don't know. As far as I know Marco is the only one who documented some of the source code to make his 256KB version (and Double Fcopy).

+ +

D64 was not enough to store information in (diskID for example could be different than the Track 18 ID). All extra data Fcopy needed/generated was put into a single file called F64.

+ +

Why would a cracking group like the Whiz-zards take the time to create an elaborate cable setup and application suite to create a special auxiliary file for D64's and create/sell a CD with over 5500 D64 images on it without actually documenting how to use the F64 file, especially for emulator authors?

+ +

I described the reason earlier. FCopyPC was built to copy over 1500 disks (3000 disk sides) on a fast and easy way to PC and back to C64. It was nice to have the D64 to run them in an emulator. But them main reason for the program was speed and the trust of having a good copy both ways. Since almost all of my old disks were copied with Fcopy, Copy 1.5 or 15sec copy. most of the un-copyable errors you talk about would have been destroyed already by the first copy from c64 to c64 disks. Fcopy was the best choice for that time, also because Marco had a lot of knowledge about the program (and all sources available). To be honest: I don't even know what c64 disk-to-disk copy programs have been used after 1989.

+ +

I remember contacting one or two of the emulator guys back then, about implementing the diskID that some programs need (or just need to be cracked better). I also told them the ID was in the F64 files I generated. They were not interested back then.

+ +

...and why would they not see the inherent limitations of using FCOPY III in the first place with respect to error 29 and 20/27? These limitations should have been addressed.

+ +

I guess this was just because we didn't know. Both Marco and I stopped with the C64 around 1989. We were used to FcopyPC back then, and we figured that would be the best and easiest way to go for a parallel tranfer program. Then again, all my disks were from before 1990 and already copied with Fcopy on the C64. I also did put all my 72 tapes (60 minutes per tape) back to disk and transferred them top PC. (Disk 2250 en up on the C64CD96). No errors on those disks.

+ +

I was programming some small games for Amiga in 1993, and did my study Higher Computer Science. Marco was also doing some kind of electronics study and even went a year to the UK, just after he made the FcopyPC program.

+ +

What I don't understand is the cable description on the CD is being wrong. Several people built the cable, never got complaints from them. Anyway Marco designed and built it for me, he also made the schematics description that's on the CD.

+ +

Hope some of your questions have been solved. I think it's just funny to see the FcopyPC program still being around on then internet. Wondering if anyone is using it anyway. If you have any questions feel free to ask. Although I can tell you more about the story around the creation, than the technical detailt.

+ +

Regards, + + Guido."

+ +

Back to top

+ +
+ +

Email the author: Peter Schepers | Last updated: Oct 4, 2007

+ +
+ +
+ + + + + + + +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + diff --git a/Commodore/G64.TXT b/Commodore/G64.TXT new file mode 100644 index 0000000..fb44dab --- /dev/null +++ b/Commodore/G64.TXT @@ -0,0 +1,473 @@ + +*** G64 (raw GCR binary representation of a 1541 diskette) +*** Document revision: 1.9 +*** Last updated: Feb 19, 2008 +*** Compiler/Editor: Peter Schepers +*** Contributors/sources: Markus Brenner, + Immers/Neufeld "Inside Commodore DOS", + Wolfgang Moser + + This format was defined in 1998 as a cooperative effort between several +emulator people, mainly Per Hakan Sundell (author of the CCS64 C64 +emulator), Andreas Boose (of the VICE CBM emulator team) and Joe +Forster/STA (the author of Star Commander). It was the first real +cooperative attempt to create a format for the emulator community which +removed almost all of the drawbacks of the other existing image formats, +primarily D64. The G64 format is not specifically designed to hold only +1541 images, but they are presently the only G64 images in existance and +why this document only refers to the 1541 and D64's. + + The intention behind G64 is not to replace the widely used D64 format, as +D64 works fine with the vast majority of disks in existence. It is intended +for those small percentage of programs which demand to work with the 1541 +drive in a non-standard way, such as reading or writing data in a custom +format. The best example is with speeder software such as Action Cartridge +in "warp save" mode or Vorpal and V-MAX which write track/sector data in +another format other than standard GCR. The other obvious example is +copy-protected software which looks for some specific data on a track, like +the disk ID, which is not stored in a standard D64 image. + + One protection method that G64 has trouble emulating is data alignment +between tracks. Some protection methods rely on data being in exact +positions when the head is stepped from one track to another. Imagine two +concentric circles representing the data tracks, with a drive head reading +data from one track, stepping over to the other track and expecting to find +some specific data where it is now. Unless you can read track data from a +1541 so it is aligned with the previous track, write it into the G64 +appropriately, and also read the resulting G64 data with this alignment in +mind, the protection check will likely fail. Other methods like weak bits +are also hard to emulate. + + G64 has a deceptively simply layout for what it is capable of doing. We +have a signature, version byte, some predefined size values, and a series +of offsets to the track data and speed zones. It is what's contained in the +track data areas and speed zones which is really at the heart of this +format. + + Each track data area is simply the raw stream of GCR data, just what the +read head would see when a diskette is rotating past it. How the data gets +interpreted is up to the program trying to access the disk. Because the +data is stored in such a low-level manner, just about anything can be done. +Most tracks will be in the standard format with with SYNC markers, GAP, +header, data blocks and checksums. The arrangement of the data when it is +in a standard GCR sector layout is covered at the end of this document. It +is the tracks that don't follow the standard which are the reason for G64's +existance and the hardest to decode. + + Below is a dump of the header, broken down into its various parts. +Following that is a breakdown of the track offset and speed zone offset +areas, as they demand much more explanation. + + +Addr 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII +---- ----------------------------------------------- ---------------- +0000: 47 43 52 2D 31 35 34 31 00 54 F8 1E .. .. .. .. GCR-1541T.... + + Bytes: $0000-0007: File signature "GCR-1541" + 0008: G64 version (presently only $00 defined) + 0009: Number of tracks in image (usually $54, decimal 84) + 000A-000B: Maximum track size in bytes in LO/HI format + + Now, why are there 84 tracks defined when a normal D64 disk only has 35 +tracks? By definition, an image of a 1541 must include all the tracks that +a real 1541 can access, which is at most 42 tracks and 42 half tracks. Even +though using more than 35 tracks is not typical, it was important to define +this format from the start with what the 1541 is capable of doing, and not +just what it typically does. Some 1541 drives may have problems reading +past track 40, and pushing the head past track 42 might be somewhat +hazardous to the health of the drive as the head could get stuck. + + The typical value seen for the maximum track size is 7928. This is the +value used for 1541 images which use standard GCR encoding. This value is +determined by the fastest write speed possible (speed zone 0), coupled with +the average rotation speed of the disk (300 rpm), and assuming normal +Commodore GCR data formatting. After some math, the answer that actually +comes up is 7692 bytes. Allowing for a slower disk rotation of -3%, , which +would allow more data to be written, and some rounding, 7928 bytes per +track was arrived at. + + Even though it might appear so, it is very important to know that this +maximum track size value is not a fixed or hard-coded value. This value +depends on the what the original disk was and the GCR encoding used. +Non-1541 images such as SFD1001 or 8050 will result in different, likely +larger, track sizes. Also, disks with non-standard GCR encoding like those +using V-MAX can result in tracks exceeding 8000 bytes. + + Since it is a flexible format in both track count and track byte size, +file sizes can vary greatly. However, given a few constants like 42 tracks +with no halftracks, a consistent track size of 7928 bytes and no speed +offset entries, the typical file size will be 333744 bytes. + + In my investigation using MNIB (a utility by Markus Brenner that allows +you to nibble a 1541 diskette to the PC in G64 format) on a cleanly +formatted 1541 disk (using the built-in 1541 format command), I saw the +following numbers, compared with the defaults that MNIB uses: + + Track Range Avg Size MNIB + (bytes) Size + ----------- -------- ---- + 1-17 ~7720 7692 + 18-24 ~7165 7142 + 25-30 ~6690 6666 + 31- ~6270 6250 + + Note that the first size number (7720) is larger than previously +mentioned track size of 7692. Why? Likely the drive that I used to create +and nibble the clean disk was rotating a little bit slower than 300 RPM +(~299 RPM), so more data than normal was stored on each track. I calculated +the percentage difference between my numbers and the established benchmark +of 7692, multiplied all my numbers by this factor, and arrived at the +following chart: + + Track Range Size MNIB + (bytes) Size + ----------- ------- ---- + 1-17 7692 7692 + 18-24 7139 7142 + 25-30 6666 6666 + 31- 6247 6250 + + See how close the real numbers come to what MNIB uses? I can attribute +the differences of a few bytes to my own rounding errors. Therefore I +conclude that the numbers MNIB uses can be taken as the standard that all +1541-compatible G64 tracks should be created with. + + All of the above calculations are shown here to establish a safe +benchmark to create G64 images in the event that someday we can copy them +back to a real 1541 disk. If the G64 track size was too large, it might +happen that the track cannot be written back out. By using the above MNIB +track size numbers, this problem should be alleviated. + + Below is a dump of the first section of a G64 file, showing the offsets +to the data portion for each track and half-track entry. + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +0000: .. .. .. .. .. .. .. .. .. .. .. .. AC 02 00 00 ............ +0010: 00 00 00 00 A6 21 00 00 00 00 00 00 A0 40 00 00 !@ +0020: 00 00 00 00 9A 5F 00 00 00 00 00 00 94 7E 00 00 _~ +0030: 00 00 00 00 8E 9D 00 00 00 00 00 00 88 BC 00 00 +0040: 00 00 00 00 82 DB 00 00 00 00 00 00 7C FA 00 00 | +0050: 00 00 00 00 76 19 01 00 00 00 00 00 70 38 01 00 vp8 +0060: 00 00 00 00 6A 57 01 00 00 00 00 00 64 76 01 00 jWdv +0070: 00 00 00 00 5E 95 01 00 00 00 00 00 58 B4 01 00 ^X +0080: 00 00 00 00 52 D3 01 00 00 00 00 00 4C F2 01 00 RL +0090: 00 00 00 00 46 11 02 00 00 00 00 00 40 30 02 00 F@0 +00A0: 00 00 00 00 3A 4F 02 00 00 00 00 00 34 6E 02 00 :O4n +00B0: 00 00 00 00 2E 8D 02 00 00 00 00 00 28 AC 02 00 .( +00C0: 00 00 00 00 22 CB 02 00 00 00 00 00 1C EA 02 00 " +00D0: 00 00 00 00 16 09 03 00 00 00 00 00 10 28 03 00 ( +00E0: 00 00 00 00 0A 47 03 00 00 00 00 00 04 66 03 00 Gf +00F0: 00 00 00 00 FE 84 03 00 00 00 00 00 F8 A3 03 00 +0100: 00 00 00 00 F2 C2 03 00 00 00 00 00 EC E1 03 00 +0110: 00 00 00 00 E6 00 04 00 00 00 00 00 E0 1F 04 00 +0120: 00 00 00 00 DA 3E 04 00 00 00 00 00 D4 5D 04 00 >] +0130: 00 00 00 00 CE 7C 04 00 00 00 00 00 C8 9B 04 00 |ț +0140: 00 00 00 00 C2 BA 04 00 00 00 00 00 BC D9 04 00 º +0150: 00 00 00 00 B6 F8 04 00 00 00 00 00 .. .. .. .. ..... + + Bytes: $000C-000F: Offset to stored track 1.0 ($000002AC, in LO/HI + format, see below for more) + 0010-0013: Offset to stored track 1.5 ($00000000) + 0014-0017: Offset to stored track 2.0 ($000021A6) + ... + 0154-0157: Offset to stored track 42.0 ($0004F8B6) + 0158-015B: Offset to stored track 42.5 ($00000000) + + The track offsets rquire some explanation. When one is set to all 0's, no +track data exists for this entry. If there is a value, it is an absolute +reference into the file (starting from the beginning of the file). + + If an image stored here only contains 35 tracks (e.g. a standard 1541 +disk), then all the offset values for track 35.5 and higher will be set to +0. This can be used to detect the maximum track count when converting to a +D64 image. Since D64's cannot hold over 40 tracks, and typically only have +35, some information will be lost when converting a G64. + + From the track 1.0 entry we see it is set for $000002AC. Going to that +file offset, here is what we see... + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +02A0: .. .. .. .. .. .. .. .. .. .. .. .. 0C 1E FF FF ............ +02B0: FF FF FF 52 54 B5 29 4B 7A 5E 95 55 55 55 55 55 RT)Kz^UUUUU +02C0: 55 55 55 55 55 55 FF FF FF FF FF 55 D4 A5 29 4A UUUUUUUԥ)J +02D0: 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 R)JR)JR)JR + + Bytes: $02AC-02AD: Actual size of stored track (7692 or $1E0C, in LO/HI + format) + 02AE-02AE+$1E0C: Track data + + Following the track data is filler bytes. In this case, there are 368 +bytes of unused space. This space can contain anything, but for the sake of +those wishing to compress these images for storage, they should all be set +to the same value. In the sample I used, these are all set to $FF. + + Below is a dump of the end of the track 1.0 data area. Note the actual +track data ends at address $20B9, with the rest of the block being unused, +and set to $FF. + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +1FE0: 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 R)JR)JR)JR +1FF0: 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 )JR)JR)JR +2000: A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 )JR)JR)JR +2010: 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 )JR)JR)JR) +2020: 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A JR)JR)JR)J +2030: 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 UUUUUUUUUUUUUUUU +2040: 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 UUUUUUUUUUUUUUUU +2050: 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 UUUUUUUUUUUUUUUU +2060: 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 UUUUUUUUUUUUUUUU +2070: 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 UUUUUUUUUUUUUUUU +2080: 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 UUUUUUUUUUUUUUUU +2090: 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 UUUUUUUUUUUUUUUU +20A0: 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 UUUUUUUUUUUUUUUU +20B0: 55 55 55 55 55 55 55 55 55 55 FF FF FF FF FF FF UUUUUUUUUU +20C0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +20D0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +20E0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +20F0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +2100: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +2110: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +2120: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +2130: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +2140: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +2150: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +2160: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +2170: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +2180: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +2190: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF +21A0: FF FF FF FF FF FF .. .. .. .. .. .. .. .. .. .. .......... + + + Now we can look at the speed zone area. Below is a dump of the speed zone +offsets. + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +0150: .. .. .. .. .. .. .. .. .. .. .. .. 03 00 00 00 ............ +0160: 00 00 00 00 03 00 00 00 00 00 00 00 03 00 00 00 +0170: 00 00 00 00 03 00 00 00 00 00 00 00 03 00 00 00 +0180: 00 00 00 00 03 00 00 00 00 00 00 00 03 00 00 00 +0190: 00 00 00 00 03 00 00 00 00 00 00 00 03 00 00 00 +01A0: 00 00 00 00 03 00 00 00 00 00 00 00 03 00 00 00 +01B0: 00 00 00 00 03 00 00 00 00 00 00 00 03 00 00 00 +01C0: 00 00 00 00 03 00 00 00 00 00 00 00 03 00 00 00 +01D0: 00 00 00 00 03 00 00 00 00 00 00 00 03 00 00 00 +01E0: 00 00 00 00 02 00 00 00 00 00 00 00 02 00 00 00 +01F0: 00 00 00 00 02 00 00 00 00 00 00 00 02 00 00 00 +0200: 00 00 00 00 02 00 00 00 00 00 00 00 02 00 00 00 +0210: 00 00 00 00 02 00 00 00 00 00 00 00 01 00 00 00 +0220: 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00 +0230: 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00 +0240: 00 00 00 00 01 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 .. .. .. .. .... + + Bytes: $015C-015F: Speed zone entry for track 1 ($03, in LO/HI format, + see below for more) + 0160-0163: Speed zone entry for track 1.5 ($03) + ... + 02A4-02A7: Speed zone entry for track 42 ($00) + 02A8-02AB: Speed zone entry for track 42.5 ($00) + + Starting at $02AC is the first track entry (from above, it is the first +entry for track 1.0) + + The speed offset entries can be a little more complex. The 1541 has four +speed zones defined, which means the drive can write data at four distinct +speeds. On a normal 1541 disk, these zones are as follows: + + Track Range Storage in Bytes Speed Zone + ----------- ---------------- ---------- + 1-17 7820 3 (slowest writing speed) + 18-24 7170 2 + 25-30 6300 1 + 31-4x 6020 0 (fastest writing speed) + + + Note that you can, through custom programming of the 1541, change the +speed zone of any track to something different (change the 3 to a 0) and +write data differently. + + From the above speed zone sample, all the zones use 4-byte entries in +lo-hi format. If the value of the entry is less than 4, then there is no +speed offset block for the track and the value is applied to the whole +track. If the value is greater than 4 then we have an actual file offset +referencing a speed zone block for the track. + + In the above example shown, there were no offsets defined, so no speed +zone block dump can be shown. However, I can define what should be there. +You will have a block of data, 1982 bytes long. Each byte is encoded to +represent the speed of 4 bytes in the track offset area, and is broken down +as follows: + + Speed entry $FF: in binary %11111111 + + + 4'th byte speed (binary 11, 3 dec) + 3'rd byte speed (binary 11, 3 dec) + 2'nd byte speed (binary 11, 3 dec) + 1'st byte speed (binary 11, 3 dec) + + It was very smart of the designers of the G64 format to allow for two +speed zone settings, one in the offset block and another defining the speed +on a per-byte basis. If you are working with a normal disk, where each +track is one constant speed, then you don't need the extra blocks of +information hanging around the image, wasting space. + + + What may not be obvious is the flexibility of this format to add tracks +and speed offset zones at will. If a program decides to write a track out +with varying speeds, and no speed offset exist, a new block will be created +by appending it to the end of the image, and the offset pointer for that +track set to point to the new block. If a track has no offset yet, meaning +it doesn't exist (like a half-track), and one needs to be added, the same +procedure applies. The location of the actual track or speed zone data is +not important, meaning they do not have to be in linear order since they +are all referenced by the offsets at the beginning of the image. + + + + +Analysing the GCR data stream +----------------------------- + + Since the information stored in the track data area is in GCR format, it +is not as simple to analyse as a normal 256-byte sector would be. Here is a +dump of a portion of the GCR data, and what to look for... + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +0000: 0C 1E FF FF FF FF FF 52 54 B5 29 4B 7A 5E 95 55 RT)Kz^U +0010: 55 55 55 55 55 55 55 55 55 55 FF FF FF FF FF 55 UUUUUUUUUUU +0020: D4 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 ԥ)JR)JR)JR +0030: A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 )JR)JR)JR +0040: 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 )JR)JR)JR) +0050: 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A JR)JR)JR)J +0060: 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 R)JR)JR)JR +0070: 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 )JR)JR)JR +0080: A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 )JR)JR)JR +0090: 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 )JR)JR)JR) +00A0: 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A JR)JR)JR)J +00B0: 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 R)JR)JR)JR +00C0: 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 )JR)JR)JR +00D0: A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 )JR)JR)JR +00E0: 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 )JR)JR)JR) +00F0: 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A JR)JR)JR)J +0100: 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 R)JR)JR)JR +0110: 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 )JR)JR)JR +0120: A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 )JR)JR)JR +0130: 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 )JR)JR)JR) +0140: 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A JR)JR)JR)J +0150: 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 R)JR)JR)JR +0160: 94 A5 29 4A 55 55 55 55 55 55 FF FF FF FF FF 52 )JUUUUUUR +0170: 54 A5 2D 4B 7A 5E 95 55 55 55 55 55 55 55 55 55 T-Kz^UUUUUUUUU +0180: 55 55 FF FF FF FF FF 55 D4 A5 29 4A 52 94 A5 29 UUUԥ)JR) +0190: 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A JR)JR)JR)J +01A0: 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 R)JR)JR)JR +01B0: 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 )JR)JR)JR +01C0: A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 )JR)JR)JR + + We need to establish a marker by which one can start to interpret the +data. Always look for a group of at least 10 1-bits (two 'F's in a row and +a bit more), as they establish the SYNC mark. The 1541 actually writes out +a SYNC mark of 40 'on' bits (10 'F's in a row). Note that there are 2 +groups of SYNC marks quite close together, one for the sector header and +one for the sector data. In the above example, there is 2 groups of "FF FF +FF FF FF". The first one is the header SYNC and the second one is the data +SYNC. + + An important point here: some documentation refers to the minimum SYNC +mark as being at least 12 bits wide, and claims that one of that size is +still not entirely reliable. Thus Commodore chose to use 40 bits for the +SYNC mark, making it impossible for the drive read electronics to miss. + + If the GCR data is not in the standard sector layout, then anything goes +for interpreting the data. If no standard SYNC mark can be found, then +there is no simple way to extract any useful data. + + + Here's the layout of a standard low-level pattern on a 1541 disk. Use the +above example to follow along. + + 1. Header sync FF FF FF FF FF (40 'on' bits, not GCR encoded) + 2. Header info 52 54 B5 29 4B 7A 5E 95 55 55 (10 GCR bytes) + 3. Header gap 55 55 55 55 55 55 55 55 55 (9 bytes, never read) + 4. Data sync FF FF FF FF FF (40 'on' bits, not GCR encoded) + 5. Data bloc 55...4A (325 GCR bytes) + 6. Tail gap 55 55 55 55...55 55 (4 to 19 bytes, never read) + 1. Header sync (SYNC for the next sector) + + + The 10 header info bytes (#2) are GCR encoded and must be decoded down to +it's normal 8 bytes to be understood. Once decoded, its breakdown is as +follows: + + Byte $00 - header block ID ($08) + 01 - header block checksum (EOR of $02-$05) + 02 - Sector# of data block + 03 - Track# of data block + 04 - Format ID byte # + 05 - Format ID byte #1 + 06-07 - $0F ("off" bytes) + + The header gap (#3) is 8 bytes on an early model 1540/1541, but 9 bytes +on a later model 1541 and 4040. The 1541 doesn't read the header gap, but +simply waits it out to write out the sector data. When sector data is +written, the SYNC mark is re-written as well. + + There is some controversy over the header gap (#3). Most people assume it +to be 9 bytes of 0x55 characters, but the early 1540/1541 drives used only +8. This caused an write incompatability with the existing 4040 disks of the +day. In 1541 ROM revision 901225-3 this error was fixed, and now all drives +write out 9 of the 0x55 characters for the gap. The book "Inside Commodore +DOS" by Immers/Neufeld documents the write incompatibilty and what +corruption happens at a low level when writing to a disk with a header gap +of 8 bytes on a disk that normally expects a gap of 9 bytes. + + The tail gap (#6) is the unused space between the end of one data block +and the start of the next. It will vary in size depending on what track you +are on, how fast the drive that created the disk was rotating at, and what +program was used to format the disk. The stock 1541 format code is supposed +to determine how big a track is and divide up the extra unused space into +each tail gap. However, many disks will show a much larger tail gap between +the last sector and sector 0. In tests that the author conducted on a real +1541 disk, gap sizes of 8 to 19 bytes were seen. + + + The 325 byte data block (#5) is GCR encoded and must be decoded to its +normal 260 bytes to be understood. For comparison, ZipCode Sixpack uses a +326 byte GCR sector (why?), but the last byte (when properly rearranged) is +not used. The data block is made up of the following: + + Byte $00 - data block ID ($07) + 01-100 - 256 bytes sector data + 101 - data block checksum (EOR of $01-100) + 102-103 - $00 ("off" bytes, to make the sector size a multiple of 5) + + + The most reliable way to read G64 track data is to read it as bits, not +bytes as there is no way to be sure that all the data is byte-aligned. This +simulates the way a 1541 drive reads data as well as the head only reads +bits as well. The starting location of the track data is know, as well as +the track size so the boundaries of the track limits (start and end) are +obtainable. + + What follows is a very simply point-form list of how to read data, +finding sync marks, header blocks and sector blocks. + + 1. Search for SYNC (at least 10 or more 1 bits) + 2. Check for header id after SYNC (GCR 0x52) + 3. If header, read the remaining 9 header bytes + 4. Decode header and get sector value + 5. Search for SYNC again + 6. Check for data id after SYNC (GCR 0x55). + 7. If data, read and store with previous header. + 8. Have we finished reading the track... stop + 9. Start over + diff --git a/Commodore/GEOS.TXT b/Commodore/GEOS.TXT new file mode 100644 index 0000000..907c003 --- /dev/null +++ b/Commodore/GEOS.TXT @@ -0,0 +1,304 @@ + +*** GEOS VLIR (Variable Length Index Record) +*** Document revision: 1.4 +*** Last updated: Nov 27, 2005 +*** Compiler/Editor: Peter Schepers +*** Contributors/sources: Paul David Doherty, + Andreas Varga, + Joe Forster/STA + + Later on in the life of the C64, the GEOS OS came out. It was a system +much like many other 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 and directory +changes were made. 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. + + There are actually two types of GEOS files, VLIR and SEQuential. Don't +confuse the GEOS SEQuential type with that of the standard D64 SEQ file. +They are related, but not the same. VLIR are described in more detail +following this paragraph. GEOS SEQuential files are all non-VLIR files, +including normal PRG, USR and SEQ types. + + GEOS files usually have an entity attached called an INFO block. It +contains ICON info, author, file description, load address etc. However, +just because an INFO block does not exist for a given file, does not mean +that the file is not a GEOS file. + + Each GEOS VLIR 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 what's 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 (1900 + value) + 1A: Month (1-12, $01 to $0C) + 1B: Day (1-31, $01 to $1F) + 1C: Hour (0-23, $00 to $17) in military format + 1D: Minute (0-59, $00 to $3B) + 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. + + One big addition to the directory is the TIME STAMP contained at $19-$1D. +The year is simply the number 1900 plus whatever is stored at that location +so the year 2005 would have a $69 (105 decimal) stored there. The rest of +the values are limited as described above. + + + 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 ASCII + ----------------------------------------------- ---------------- +00: 00 FF 03 15 BF 3F 83 F8 40 44 04 8E 38 E2 B5 93 ?@D8ⵓ +10: 59 AA 92 A9 B5 93 59 AA 92 A9 BF 93 F9 B1 93 19 YY +20: 8E 10 E1 BB 93 B9 B5 93 59 AA 92 A9 B5 93 59 AE ồYY +30: 92 E9 B1 93 19 80 10 01 BF 93 F9 FF D7 FD 80 38 鱓8 +40: 03 FF FF FF 83 05 00 00 2E D9 54 00 2E 50 68 6F .T.Pho +50: 74 6F 20 4D 67 72 20 20 20 56 32 2E 31 00 00 00 toMgrV2.1 +60: 00 43 68 72 69 73 20 48 61 77 6C 65 79 00 00 00 ChrisHawley +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 53 61 76 65 20 70 68 Saveph +90: 6F 74 6F 20 69 6D 61 67 65 73 20 69 6E 20 61 20 otoimagesina +A0: 53 61 76 65 20 70 68 6F 74 6F 20 69 6D 61 67 65 Savephotoimage +B0: 73 20 69 6E 20 61 20 70 68 6F 74 6F 20 61 6C 62 sinaphotoalb +C0: 75 6D 20 66 6F 72 20 6C 61 74 65 72 20 75 73 65 umforlateruse +D0: 20 69 6E 20 67 65 6F 57 72 69 74 65 20 6F 72 20 ingeoWriteor +E0: 67 65 6F 50 61 69 6E 74 2E 00 02 85 06 85 07 85 geoPaint. +F0: 08 85 09 85 16 A9 04 85 11 A9 00 85 10 4C 2F C2 L/ + + 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! + + + Below is the dump of a BAM sector from a GEOS-formatted D64 image and +there are some changes for GEOS. We have all the typical data (forward t/s +pointer to 18/1, DOS type, disk name/id) but we also have the GEOS-format +signature from $AB-BC. From observation, any GEOS-formatted disk will have +the GEOS signature written in the same place (offset $AB) in the sector +that contains the disk name/ID. + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +00: 12 01 41 00 13 FE DF 1F 0A 69 29 0D 15 FF FF 1F Ai) +10: 0C 96 D6 16 01 00 00 10 00 00 00 00 11 FD BD 1D +20: 15 FF FF 1F 0C 96 D6 16 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 0F FC FD 05 00 00 00 00 +50: 00 00 00 00 06 05 05 05 01 00 40 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 01 00 02 00 11 FF FF 01 +90: 41 70 70 6C 69 63 61 74 69 6F 6E 73 A0 A0 A0 A0 Applications +A0: A0 A0 4A 44 A0 32 41 A0 A0 A0 A0 13 08 47 45 4F JD2AGEO +B0: 53 20 66 6F 72 6D 61 74 20 56 31 2E 30 50 BD 1E SformatV1.0P +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 18 2D 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 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/sec (see below) + AD-BC: GEOS ID string ("GEOS format V1.x", in ASCII) + BD-DC: Unused (usually $00) + DD-FF: Free sector info for tracks 36-70, used on double-sided + 1571 disks only! + + The first two bytes at $AB/$AC ($13 $08) are the track/sector location of +the BORDER SECTOR, which is 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 only hold 8 +entries. + + + 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. + + + 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. + + + +How to detect if a file is GEOS +------------------------------- + +1. Check the bottom 3 bits of the D64 file type (byte position $02 of the + directory entry). If it is not 0, 1 or 2 (but 3 or higher, REL and + above), the file cannot be GEOS. + +2. Check the FILE STRUCTURE and FILE TYPE bytes (byte position $23 and $24 + respectively). If they are both $00, then the file is not GEOS, but is a + normal D64 filetype (no INFO block either). + +3. Check the FILE STRUCTURE byte (position $23). If it is anything other + than $00 or $01, then the file is not GEOS (as those are the only legal + values). + +4. If you've reached this point, and everything looks ok, then the file is + GEOS. Now, if the FILE STRUCTURE byte (position $23) is a $01, then the + file is a GEOS VLIR, otherwise it is a GEOS SEQ. + +5. Check the FILE TYPE byte (position $24). If it is non-zero, then there + is likely an INFO block attached. Check the track/sector pointer at + position $21/22 to see if they are valid numbers (track within the specs + of the disk and sector in range for the track value). If they look good, + then the info block exists. + diff --git a/Commodore/INTRO.TXT b/Commodore/INTRO.TXT new file mode 100644 index 0000000..063ecf4 --- /dev/null +++ b/Commodore/INTRO.TXT @@ -0,0 +1,277 @@ + +*** Introduction to the various Emulator File Formats + +*** Compiled by: Peter Schepers +*** Started: August 24, 1996 +*** Last updated: Nov 7, 2008 + +--------------------------------------------------------------------------- + + There are always questions asked regarding the various file 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?". These documents attempt to +explain their internal structure, what to do with them, and some of their +respective strengths and weaknesses. + + These documents were compiled and written in an attempt to unify all the +other smaller files dealing with Commodore file types that are floating +about the net, or that exist with other programs. They are by no means +exhaustive (even though they look like it), but attempts will be made to +keep them up-to-date, and correct anything which is wrong. If you spot +something that needs correcting please make sure to email the author so +that corrections can be made for future releases... the address is +contained later in this document. + + Some of the information contained in these documents may not be accurate +as it could have been taken from inaccurate sources, and I have no +first-hand experience with said format. However, use these, pass them +around, upload them, whatever. Just be sure to leave them INTACT, don't +remove bits. + + I have attempted to categorize the filetypes involved using three basic +categories: IMAGES, ARCHIVES and CONTAINERS. The definitions for each of +these categories can be found at the bottom of this document. + + Also, plenty of good information can 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. + + + So far, this document covers the following files: + + * D64 images (1541 disks and some variants) + * X64 images (for the X64/Vice emulator) + * T64 containers (for the C64s emulator) + * T64 .FRZ (FRoZen Files, saved emulator sessions for C64s) + * PC64 containers (P/S/U/Rxx) + * PC64 .C64 (saved emulator sessions for PC64) + * D71 images (1571 disks) + * D81 images (1581 disks) + * D80 (8050) & D82 (8250) floppy images + * G64 images (GCR copy of a 1541 disk) + * D2M images (FD2000 disks) + * DNP images (CMD hard disk native partitions) + * 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 images (CCS64 ROM cartridges) + * 64x (PC64 ROM files) + * TAP images (for CCS64, sampled cassette tapes) + * VSF VICE snapshots (saved-emulator sessions for VICE) + * WAV Audio RIFF files for the PC + + ...as well as the following native C64 types, some of which are also + supported on the various emulators: + + * Extensive disk file layout (how files are stored on 1541/71/81 disks) + * 4-file diskpacked ZipCode archives (or .Z64, 4 or 5 files, #!xxxxx) + * 6-file SixPack ZipCode images (or .Z64, #!!xxxx) + * Filepacked ZipCode archives (or .Z64, x files, x!xxxxx) + * LNX containers (LyNX) + * ARK containers & SRK archives (ARKive & compressed ARKive) + * LHA & LZH archives (header description only) + * SFX archives (SelF-eXtracting LHA/LZH) + * SDA archives (Self-Dissolving Archive) + * ARC archives (ARChive) + * ZIP archives (PKZIP) + * CKIT archives (Compression KIT) + * CPK containers + * WRA & WR3 archives (Wraptor, version 1 to 3) + * LBR containers (LiBRary, C64 only, not the C128 CP/M .LBR files) + * GEOS VLIR files (Variable Length Index Record) + * REL files (RELative) + * CVT files (GEOS ConVerT) + * SPY containers (SPYne) + * C128 Boot Sector layout + * Binary & PRG (PRoGram, with load address) + + Also included is a very basic look at some C64 graphic 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. + + Joe Forster/STA has written up a description of how the various Commodore +drives (1541/1571/1581) allocate sectors and directory entries when saving +files (under normal mode and under GEOS). It is included as DISK.TXT + + 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: + +Jun 2/04 - Changes to the D2M.TXT document. + +Nov 27/05 - Renamed D2M to D2M-DNP.TXT & extensively updated + - Updated GEOS.TXT + - Updated D80-D82.TXT + - Updated CRT.TXT with new CRT types 19-23 + +Feb 21/06 - Updated CRT.TXT with new CRT types 24-27 + +Jun 12/07 - Updated CRT.TXT with sample CRT's for types 24-27 + +Oct 1/07 - Updated VICE_FRZ.TXT with info about the bogus ".S64" snapshot + file extension from the UnQuill package. + - Updated D81.TXT doc + - Updated D71.TXT doc + - Updated G64.TXT doc + - Updated CVT.TXT doc + +Feb 19/08 - Updated G64.TXT, removed erroneous odd/even tail gap info. + - Updated D64.TXT with other SpeedDOS clone names + +Nov 7/08 - Updated D64, D71, D81 & D80/D82 with extra explanation of + oversize directory track images, which contain more files than + normal. + +--------------------------------------------------------------------------- + +*** 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. + + ARCHIVE - A file format which contains other files, and in which + compression is an integral part of the design. Some examples + are ZIP, SRK, SDA, ARC, LHA, WRA. + + 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 a 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. + + CONTAINER - A file format which simply contains other files, and no + compression takes place. Some examples are T64, P00, SPY, + ARK, LNX. + + 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 most of the + 5.25" disks (i.e. 1541). It encodes an 8 bit sequence (2 4-bit + nybbles) into a 10 bit sequence (2 5-bit nybbles) 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. + + IMAGE - A file format which is a PC equivalent of a physical Commodore + media. Some examples are D64 (1541), D71 (1571), D81 (1581), D2M + (FD2000), X64. + + 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. + + LSB/MSB - See LOW/HIGH. + + 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 file 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. + diff --git a/Commodore/LBR.TXT b/Commodore/LBR.TXT new file mode 100644 index 0000000..dce86f4 --- /dev/null +++ b/Commodore/LBR.TXT @@ -0,0 +1,125 @@ + +*** LBR (LiBRary containers, C64 version only) +*** Document revision: 1.3 +*** Last updated: March 11, 2004 +*** Compiler/Editor: Peter Schepers +*** Contributors/samples: Joe Forster/STA + + 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 containers. 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 container 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 container 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. + diff --git a/Commodore/LHA.TXT b/Commodore/LHA.TXT new file mode 100644 index 0000000..6b24394 --- /dev/null +++ b/Commodore/LHA.TXT @@ -0,0 +1,119 @@ + +*** LHA, LZH, LZS (LHArc compressed files) +*** Document revision: 1.3 +*** Last updated: March 11, 2004 +*** Compiler/Editor: Peter Schepers +*** Contributors/samples: Joe Forster/STA, net documents + + 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 image, 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. + diff --git a/Commodore/LNX.TXT b/Commodore/LNX.TXT new file mode 100644 index 0000000..4b0de42 --- /dev/null +++ b/Commodore/LNX.TXT @@ -0,0 +1,226 @@ + +*** LNX (LyNX containers) +*** Document revision: 1.3 +*** Last updated: March 11, 2004 +*** Compiler/Editor: Peter Schepers +*** Contributors/sources: Marko Makela + + 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 containers 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 container, as well as the size +of the directory (in blocks) and the number of directory entries in the +container. 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 files 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 file 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 an LNX file 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 +container 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 it only somewhat +difficult to support. LNX files 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 containers + + * 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 + diff --git a/Commodore/PC64.TXT b/Commodore/PC64.TXT new file mode 100644 index 0000000..e420346 --- /dev/null +++ b/Commodore/PC64.TXT @@ -0,0 +1,225 @@ + +*** P00/S00/U00/R00 (Container files for the PC64 emulator) +*** Document revision: 1.4 +*** Last updated: March 11, 2004 +*** Compiler/Editor: Peter Schepers +*** Contributors/sources: Wolfgang Lorenz + + 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 (x01, x02, x03, up to x99). 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 containers +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 PC64 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 kb per cluster. +Any 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. + + 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 PC64 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) + + * Efficiently supports 1541 REL files (R00) i.e. no side-sector info + needed (unlike LNX and ARK) + + * 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 not really an intentional *file* design + benefit but only an emulator side effect. However it could be 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 + (write-protect) or non-standard file types (DEL) are kept + + * 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, + especially with PC64 files. It is best to keep each multi-file program + in separate directories. However, each DOS directory entry used for + organisational purposes also takes up space. + + * Not yet as widely supported as D64 or T64 + + * No GEOS VLIR file structure support + + * No labels/description field in the file header + + * No multi-file support (since 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, as this is the truncation character + + * I don't think PC64/WIN supports the original PC64/DOS files + + * Depending on the PC64 filesize and the DOS hard disk cluster size, + there could be significant cluster slack-space loss, especially + noticible with many average-size P00 files + + This last detail is the most insidious, and the most difficult to + explain. The easiest way to check it out is the following: + + 1. Generate P00 files from games in other images like D64 files + (multi-file games of course). + + 2. Figure out how many clusters *each* file takes based on the + present cluster size (this is the more difficult part), for the + whole directory of P00 files. Multiply the resulting cluster count + by the cluster size. This is the *actual* useage in hard drive + space that the P00 files take. + + 3. Total up, in bytes, the whole P00 directory. + + 4. Divide the number from (3) into (2) (and multiply by 100) to get + the percentage efficiency. Subtract this number from 100 to get + the %-Loss. + + + From some experiments I did, I came up with some example %-loss charts, + one for P00 and one for D64 based on cluster sizes from 32k (large hard + disk) down to 512 bytes (floppy disk). + + + + 100 P00 files, totalling 1,829,629 bytes. + + Cluster Actual + Size Usage %-Loss + ------- --------- ------ + 32k 3,899,392 53.1% + 16k 2,719,744 32.7% + 8k 2,285,568 19.9% + 4k 2,068,480 11.5% + 2k 1,943,552 6.0% + 1k 1,886,208 3.0% + 512 1,854,976 1.4% + + Given what would seem to be average hard disk sizes, I would estimate + the %-loss for P00 files to be around 20-40%. When you have a large + number of P00 files, you are wasting a lot of hard disk space. + + + + 12 D64 files, totalling 2,098,176 bytes (these were used to + generate the above 100 P00 files). Note that these D64 files were + *not* necessarily full, but it is assumed that they are used to + capacity. If they are not, then the %-Loss must be increased. + + Cluster Actual + Size Usage %-Loss + ------- --------- ------ + 32k 2,359,296 11.1% + 16k 2,162,688 3.0% + 8k 2,162,688 3.0% + 4k 2,113,536 0.7% + 2k 2,113,536 0.7% + 1k 2,101,248 0.2% + 512 2,101,248 0.2% + + + From the above charts, it becomes clear that D64, regardless of hard + disk size, is *much* more efficient at storing files (average of 1-3% + loss, assuming the files are full). In fact, almost *any* other + filetype (T64, LNX, ARK) will be more efficient than P00 since they + are usually much larger than a single cluster. + diff --git a/Commodore/PC64_FRZ.TXT b/Commodore/PC64_FRZ.TXT new file mode 100644 index 0000000..ccff206 --- /dev/null +++ b/Commodore/PC64_FRZ.TXT @@ -0,0 +1,46 @@ + +*** C64 (PC64 saved-session file) +*** Document revision: 1.4 +*** Last updated: March 11, 2004 +*** Compiler/Editor: Peter Schepers +*** Contributors/sources: Wolfgang Lorenz + + 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 ROMs 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. + diff --git a/Commodore/PC64_ROM.TXT b/Commodore/PC64_ROM.TXT new file mode 100644 index 0000000..03f3863 --- /dev/null +++ b/Commodore/PC64_ROM.TXT @@ -0,0 +1,22 @@ + +*** 64x (PC64/DOS ROM files) +*** Document revision: 1.1 +*** Last updated: March 11, 2004 +*** Compiler/Editor: Peter Schepers +*** Contributors/sources: Wolfgang Lorenz + + 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. + diff --git a/Commodore/PCLINK.TXT b/Commodore/PCLINK.TXT new file mode 100644 index 0000000..9699e77 --- /dev/null +++ b/Commodore/PCLINK.TXT @@ -0,0 +1,32 @@ + +*** C64 (PCLINK container files) +*** Document revision: 1.3 +*** Last updated: March 11, 2004 +*** Compiler/Editor: Peter Schepers +*** Contributors/sources: Markus Mehring + + 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. + diff --git a/Commodore/PCVIC.TXT b/Commodore/PCVIC.TXT new file mode 100644 index 0000000..408d444 --- /dev/null +++ b/Commodore/PCVIC.TXT @@ -0,0 +1,107 @@ + +*** PCV (PCVIC VIC-20 emulator saved-session files) +*** Document revision: 1.1 +*** Last updated: March 11, 2004 +*** Compiler/Editor: Peter Schepers +*** Contributors/sources: unknown + + This is another snapshot file, generated by the PCVIC VIC-20 emulator, +written by BW Van Schooten. This description is based on the version 1.0 of +the PCVIC emulator. + + Bytes: $0000-0015 - PCVIC signature string "PCVIC system snapshot", with + a zero terminator + 0016-0017 - Version#, minor (0-99)/major (0-255). + 0018-0019 - Size of register state block (not including this size + value) + 001A-XXXX - Register state block, contains system register values + and memory expansion settings. + XXXX-MMMM - Byte-run compression of VIC memory. This excludes + the standard ROM areas $8000-8FFF and $C000-CFFF + (END-1)-END - Two-byte checksum of the data from $0016 to the end + of the MMMM section. + + Here is most of the contents of the register state block: + + Byte: $00-01 - 6502 X register in low byte, high byte set to 0 + 02-03 - 6502 Y register in low byte, high byte set to 0 + 04-05 - 6502 SP (stack pointer) in low byte, high byte set to 1 + 06 - Unused + 07 - 6502 auxiliary flags. Bits 2-5 are bits 2-5 of the CPU + flag register. All other bits set to 0. + + 08-09 - Scanline + 0-263 - NTSC + 0-311 - PAL + + 0A - VIA1 IFR register + 0B - VIA1 IER register + 0C - VIA2 IFR register + 0D - VIA2 IER register + 0E - VIA1 IRB port + 0F - VIA1 ORB port + 10 - VIA1 IRA port + 11 - VIA1 ORA port + 12 - VIA2 IRB port + 13 - VIA2 ORB port + 14 - VIA2 IRA port + 15 - VIA2 ORA port + + 16 - Timer Status. 1=Active, 0=Inactive + Bit: 0 - VIA1 Timer 1 + 1 - VIA1 Timer 2 + 2 - VIA2 Timer 1 + 3 - VIA2 Timer 2 + 4-7 - Future expansion, set to 0 + 17 - VIA1 Timer 2 Latch + 18 - VIA2 Timer 2 Latch + 19 - VIA1 Timer 2 Timer + 1A - VIA2 Timer 2 Timer + + 1B - NMI Flank. + 0 - NMI was low since last time NMI was sampled + 1 - NMI was high since last time NMI was sampled + 1C - Memory configuration. If bit set, area is RAM. If bit + clear, area is either ROM or unavailable. Each bit + represents an 8Kb block of RAM. + Bit: 0 - $0000-1FFF* + 1 - 2000-3FFF + 2 - 4000-5FFF + 3 - 6000-7FFF + 4 - (always set to 0, ROM) + 5 - A000-BFFF + 6 - (always set to 0, ROM) + 7 - (always set to 0, ROM) + *Note: The areas 0000-03ff and 1000-2000 are + considered to be always occupied by RAM. For an + unexpanded Vic, all blocks are set to 0. Setting only + the low block (bit 0) it to 1 results in 3K RAM + expansion. + 1D-1E - 6502 PC (program counter) register + 1F-20 - 6502 main flags + Bit: 00 - Don't care + 01 - Don't care + 02 - Don't care + 03 - Don't care + 04 - Don't care + 05 - Don't care + 06 - Zero flag + 07 - Sign flag + 08 - Carry flag + 09 - Set to 0 + 10 - Set to 0 + 11 - Set to 0 + 12 - Set to 0 + 13 - Set to 0 + 14 - Overlfow flag + 15 - Set to 0 + 21 - 6502 A register + 22 - Scan count. CPU cylce count within scan line. + 0 - End of scan line + 129 (NTSC) or 131 (PAL) - Start of scan line + 23 - END of register state block. + + The rest of the file consists of the RAM and I/O areas. These are +byterun compressed, and require source code to decode properly, which I +will not get into here. + diff --git a/Commodore/PHAUZEH.TXT b/Commodore/PHAUZEH.TXT new file mode 100644 index 0000000..f769fba --- /dev/null +++ b/Commodore/PHAUZEH.TXT @@ -0,0 +1,138 @@ + +*** S20 (Phau Zeh VIC-20 emulator saved-session files) +*** Document revision: 1.2 +*** Last updated: March 11, 2004 +*** Compiler/Editor: Peter Schepers +*** Contributors/sources: unknown + + This file is created when you save a session in the Phau Zeh VIC-20 +emulator (written by Arne Bockholdt). Like all emulator saved-session, it +contains all zero-page RAM, CPU registers, RAM and I/O registers. In order +for the Phau Zeh emulator to recognize its saved-sessions, it must be saved +with the "S20" extension. + + This document is based on the 0.9.5 revision of the S20 layout, so the +actual 1.0 release might be different. The minimum S20 file size is 9286 +bytes (based on an un-enpanded VIC-20) and the largest is 36934 bytes +(based on a fully-expanded VIC-20). + + Bytes: $0000-000E - S20 signature string "VIC-20 SNAPSHOT" + 000F - S20 revision + $01 - version 0.9.5 + 00, 02-FF - Reserved + 0010 - Machine + $00 - Original VIC-20 + 01 - Phau Zeh + 02 - V20 + 03 - Mac VIC-20 emulator + 04-FF - Future Expansion (set to $00) + 0011 - Miscellaneous Info. If Byte $16 is set to 1 (Phau + Zeh emu), it is sub-version of the emulator. + With $16 set to 1: + $01 - PZL + 02 - PZW + 00, 03-FF - Future expansion (set to $00) + 0012-0013 - Future Expansion (set to $00) + 0014-0015 - Memory areas saved (in HI-LO format). The bit will + be set if the memory area is saved, clear if not. + Each bit of this word represents a 4Kb area of + memory. The ROM memory locations should always be + clear (not saved), and positions 1 and 9 must always + be set and saved. + Bit: 00 - RAM $0400-0FFF (only 3Kb for this one) + 01 - RAM $1000-1FFF + 02 - RAM $2000-2FFF + ... + 15 - RAM $F000-FFFF + 0016-0017 - VIC-20 ROM memory (in HI-LO format). The bit will be + set if the ROM area is saved, clear if not. Each bit + represents 4Kb of ROM. VIC-20 ROM memory locations + should be set to 1, and setting bits 0 and 1 on + would make no sense as ROM can't exist in those + areas. + Bit: 00 - ROM $0000-0FFF + 01 - ROM $1000-1FFF + 02 - ROM $2000-2FFF + ... + 15 - ROM $F000-FFFF + 0018 - RAM expansion installed + $00 - No expansion + 03 - 3Kb installed + 08 - 8Kb installed + 10 - 16Kb installed + 18 - 24Kb installed + All other values invalid (future expansion) + 0019 - Future expansion (set to $00) + + 001A-001B - 6502 Instruction Pointer (HI-LO format) + 001C - 6502 Flag register + Bit 0 - Carry Flag + 1 - Zero Flag + 2 - Interrupt Flag + 3 - Decimal Flag + 4 - Break Flag + 5 - Always set to 1 + 6 - Overflow Flag + 7 - Sign Flag + 001D - 6502 Stack Pointer + 001E - 6502 A Register + 001F - 6502 X Register + 0020 - 6502 Y Register + 0021 - NMI status + Bit 0 - Set if NMI info valid, clear otherwise + 7 - Clear if NMI low, set if NMI high + All other bits unused. + + 0022-0023 - VIA1 Timer 1 Value (HI-LO format) + 0024-0025 - VIA1 Timer 1 Latch (HI-LO format) + 0026-0027 - VIA1 Timer 2 Value (HI-LO format) + 0028 - VIA1 Timer 2 Latch + 0029-002A - VIA2 Timer 1 Value (HI-LO format) + 002B-002C - VIA2 Timer 1 Latch (HI-LO format) + 002D-002E - VIA2 Timer 2 Value (HI-LO format) + 002F - VIA2 Timer 2 Latch + 0030 - Set Interrupt Flag Status bits. 0 = don't set flag, + 1 = set flag. + Bit 0 - VIA1 Timer 1 + 1 - VIA1 Timer 2 + 2 - VIA2 Timer 1 + 3 - VIA2 Timer 2 + All other bits clear (future expansion) + 0031 - Future Expansion (set to $00) + 0032 - VIA Port Register Status. Tells emulator which + registers are saved in the file. + $00 - Nothing saved (not recommended) + 01 - IR ports saved to the following 4 bytes + 02 - OR ports saved to the following 4 bytes + 03-FF - Future expansion + 0033 - VIA1 IRA or ORA (depends on the value in $0032) + 0034 - VIA1 IRB or ORB (depends on the value in $0032) + 0035 - VIA2 IRA or ORA (depends on the value in $0032) + 0036 - VIA2 IRB or ORB (depends on the value in $0032) + 0037-003A - Future expansion (set to $00) + + 003B - Video Mode + $00 - PAL (6561) + 01 - NTSC (6560) + 02-FF - Reserved + 003C-003D - Current scanline + PAL: 0-311 + NTSC: 0-260 + 003E - Cycles since last scanline change. This is the + number of cycles passed since the lasy scanline was + drawn, or the scanline counter was incremented. + PAL: 0-70 + NTSC: 0-64 + 003F-0042 - Future expansion (set to $00) + + 0043-0442 - Zero Page RAM $0000-03FF (must be in file) + + 0443-1042 - RAM locations $0400-0FFF contents (optional, only + when $0014-0015 bit 0 is set) + 1043-2042 + (or)0443-1442 - RAM locations $1000-1FFF (must be in file) + ... - (4Kb RAM blocks continue, depending on the bit + pattern set in $0014-0015) + + (END-2)-END - Last three bytes set to $FF. + diff --git a/Commodore/POWER64.TXT b/Commodore/POWER64.TXT new file mode 100644 index 0000000..311ba49 --- /dev/null +++ b/Commodore/POWER64.TXT @@ -0,0 +1,62 @@ + +*** Power 64 RAM Snapshot File (C64 emulator on Apple Power Macintosh) +*** Document revision: 1.2 +*** Last updated: March 11, 2004 +*** Compiler/Editor: Peter Schepers +*** Contributors/sources: Peter Weighill + + 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 + diff --git a/Commodore/REL.TXT b/Commodore/REL.TXT new file mode 100644 index 0000000..09a26a4 --- /dev/null +++ b/Commodore/REL.TXT @@ -0,0 +1,110 @@ + +*** REL (RELative file layout) +*** Document revision: 1.1 +*** Last updated: March 11, 2004 +*** Compiler/Editor: Peter Schepers +*** Contributors/sources: Immers/Neufeld "Inside Commodore DOS" + + This is a filetype native to CBM drive (random access) devices. On the +surface it seems similar to all other filetypes, especially SEQ, but was +designed to make access to data *anywhere* in the file very fast. + + We start by examining a REL file 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. + + Bit:$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, max. value 254) + 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 + + 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 that sector... + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +0000: 0C 13 00 FE 11 0C 0C 13 06 09 00 00 00 00 00 00 +0010: 11 02 11 0D 11 03 11 0E 11 04 11 0F 11 05 11 10 +0020: 11 06 11 11 11 07 11 12 11 08 11 13 11 09 11 14 +0030: 11 0A 11 0B 10 00 10 0A 10 14 10 08 10 12 10 06 +0040: 10 10 10 04 10 0E 10 02 10 0C 10 01 10 0B 10 03 +0050: 10 0D 10 05 10 0F 10 07 10 11 10 09 10 13 0F 07 +0060: 0F 11 0F 05 0F 0F 0F 03 0F 0D 0F 01 0F 0B 0F 00 +0070: 0F 0A 0F 14 0F 08 0F 12 0F 06 0F 10 0F 04 0F 0E +0080: 0F 02 0F 0C 0F 09 0F 13 0E 07 0E 11 0E 05 0E 0F +0090: 0E 03 0E 0D 0E 01 0E 0B 0E 00 0E 0A 0E 14 0E 08 +00A0: 0E 12 0E 06 0E 10 0E 04 0E 0E 0E 02 0E 0C 0E 09 +00B0: 0E 13 0D 07 0D 11 0D 05 0D 0F 0D 03 0D 0D 0D 01 +00C0: 0D 0B 0D 00 0D 0A 0D 14 0D 08 0D 12 0D 06 0D 10 +00D0: 0D 04 0D 0E 0D 02 0D 0C 0D 09 0D 13 0C 07 0C 11 +00E0: 0C 05 0C 0F 0C 03 0C 0D 0C 01 0C 0B 0C 00 0C 0A +00F0: 0C 14 0C 08 0C 12 0C 06 0C 10 0C 04 0C 0E 0C 02 + + 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, max. value 254) + 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 chain. + + If the speed advantage regarding this type file file isn't obvious yet, +consider the following scenario... If we need to access record 4000, its +only a couple of calculations to see how many bytes into the file it is... + + 4000 * "record length" (254) = byte offset + + Once we know this, we can calculate how many sectors into the file the + record is... + + byte offset / 254 = # of sectors into REL file + + The divisor value "254" in the above formula is the number of bytes +useable in each sector (256 bytes less the 2 bytes used for the forward t/s +pointer) and has no relation to the "max REL record length". + + 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. + diff --git a/Commodore/SDA.TXT b/Commodore/SDA.TXT new file mode 100644 index 0000000..7a938a8 --- /dev/null +++ b/Commodore/SDA.TXT @@ -0,0 +1,60 @@ + +*** SDA (Self-Dissolving compressed Archive) +*** Document revision: 1.4 +*** Last updated: March 11, 2004 +*** Compiler/Editor: Peter Schepers +*** Contributors/sources: Chris Smeets (source code) + + 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, likely version 1 and version 2 +files, but they all seem to be self-extracting ARC files. There are also +different revisions of the version 2 header, where the newer ones allow for +the decompression of more compressed ARC formats. 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. 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. + + There are some exceptions to the above, expecially with the C128 versions +of files. If the first numeric value of the SYS call is a 7, we have a C128 +file. If this is the case, you can assume that the line number value is 15, +rather than using the line number in the BASIC header. Some files I've seen +don't have the proper value for the line number. + + 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. + diff --git a/Commodore/SFX.TXT b/Commodore/SFX.TXT new file mode 100644 index 0000000..883d1a7 --- /dev/null +++ b/Commodore/SFX.TXT @@ -0,0 +1,67 @@ + +*** SFX (SelF-eXtracting LHA/LZH compressed files) +*** Document revision: 1.3 +*** Last updated: March 11, 2004 +*** Compiler/Editor: Peter Schepers +*** Contributors/sources: Chris Smeets + + 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.. + + I have seen two different versions of the header, one which is 3711 bytes +long, and the other standard one which is 3721 bytes long. The only way to +tell them apart is to examine the byte value at offset $0067 into the file. +If it is $CE, then we have the 3721 byte header. If it is $C4, then it is +the shorter 3711 byte header. Notice that the difference between the two +values is 10, the same as the header difference. + + Typically, at address $0E89 (3721 bytes into the file) or at $0E7F (3711 +bytes in) 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. + diff --git a/Commodore/SIDPLAY.TXT b/Commodore/SIDPLAY.TXT new file mode 100644 index 0000000..5cdc320 --- /dev/null +++ b/Commodore/SIDPLAY.TXT @@ -0,0 +1,510 @@ + +*** SID/PSID (Various SIDPlay / PlaySID Formats) +*** Document revision: 1.2 +*** Last updated: March 15, 2004 +*** Compiler/Editor: Peter Schepers +*** Contributors/sources: LaLa, + Peter Weighill + + The data files used by SIDPLAY contain binary C64 data and music player +machine code. Both, the programmer on the C64 and this emulator need +information on how to access the code inside the binary file. That means, +information like the memory location to load the file to, the number of +tunes, the starting address of the executable code and its subroutines. +This specific information has to be delivered in either a separate file - +which is often called info file - or in form of a header in the single +binary data file. A standalone C64 data file without a header or without a +corresponding info file is considered invalid. + + It is recommended that you get accustomed to one-file sidtunes with the +*.sid extension. For raw C64 binary files the extension .c64 or .prg is +preferred in order to be able to assign a .sid extension to the additional +info file. + +Supported and merely used file formats are: + + PlaySID single-file-format (widely known as PSID) + + PlaySID info-file-format (Raw C64 binary file plus Amiga Workbench icon + tooltype file .INFO) + + SIDPLAY info-file-format (Raw C64 binary file plus SIDPLAY ASCII text + info file, previously .SID) + + C64 Sidplayer format (.MUS/.STR) + + Raw data or PSID files have appeared as *.data, *.psid or psid.*. + + +DAT files + + The .DAT file name extension has been introduced by the early versions of +SIDPLAY/DOS. It has never been used to specify a file format. Its main use +has been in assigning a unique file name extension to any sidtune file, but +especially raw C64 data files, and allowing to use .SID for additional info +files. + + +INFO files + + These are Amiga Workbench tooltype icons containing binary graphics data +and ASCII text information strings. They have been used by PlaySID and are +supported by SIDPLAY. Their file name extension normally is .info or .INF. +This is a two-file format. A separate C64 binary data file is required. On +Amiga the corresponding C64 data files usually haven't had filename +extensions. However, they might have been renamed on other systems. + + +SIDPLAY info files + + These are plain ASCII text files which have been introduced by the +earlier versions of SIDPLAY/DOS. They are used to be able to alter the +information inside with a normal ASCII text editor. They can be converted +to a single file that contains a binary header. This is a two-file format. +A separate C64 binary data file is required. Notice that each pair of files +usually has the old DOS-naming of .SID for the info file and .DAT for the +C64 data file. + + The SIDPLAY info file is derived from the information inside the PlaySID +one-file format. It is structured like this: + + SIDPLAY INFOFILE + ADDRESS=,, + SONGS=[,] + SPEED= + NAME= + AUTHOR= + COPYRIGHT= + RELEASED= + SIDSONG= + RELOC=, + CLOCK= + SIDMODEL=<6581|8580> + COMPATIBILITY= + + The first line of the text containing ``SIDPLAY INFOFILE'' is only used +to identify the type of file. + + ADDRESS=,, + + Each specified address is a 16-bit effective C64 memory location in case +insensitive hexa-decimal notation without a prefix, e.g. C000 or E012, but +neither $FCE2 nor 0xFCE2. Preceding zeroes are ignored. + + is the C64 memory location where to put the C64 data. 0 +means, the data is in original C64 format, i.e. the first two bytes contain +the little-endian load address (low byte, high byte). Please don't +explicitly specify the load address unless required for sure. If the load +address is explicitly specified, some sidtune converters and utilities +conjecture that the C64 data lacks its load address. Hence they move it in +front of the C64 data. This would create two redundant bytes if the C64 +data already had a load address in the first two bytes. Additionally, those +extra bytes in the beginning can confuse disassemblers. + + is the start address of the machine code subroutine that +initializes a song by accepting the contents of the 8-bit 6510 Accumulator +as the song number parameter. 0 means, the address is equal to the +effective load address. + + is the start address of the machine code subroutine that can +be called frequently to produce a continuous sound. 0 means, the +initialization subroutine is expected to install an interrupt handler, +which then calls the music player. If so, the value in the bank-select +register $01 determines whether the IRQ vector $0314/$0315 (Kernal-ROM on) +or the IRQ vector $FFFE/$FFFF (Kernal-ROM off) is to be used. + + SONGS=,[] + + is the decimal number of songs (or sound effects) that can be +initialized by calling the init address. The minimum is 1. + + is the decimal number of the song to be played by default. This +value is meant as a proposal and is optional. It has a default of 1. It +often specifies the first song you would hear upon starting the program is +has been taken from. + + SPEED= + + is a value in case insensitive hexa-decimal notation without a +prefix. Preceding zeroes are ignored. The value contains information about +the speed of each song. For each song a bit is reserved, bit 0 for song 1, +bit 1 for song 2, and so on. A bit set to 0 means, the music player +subroutine is called at 50 Hz. A bit set to 1 means, the real speed is +indicated by the CIA 1 Timer A $DC04/05, which defaults to 60 Hz. To not +break compatibility to the PlaySID formats, use a maximum of 32 bits, which +is equal to 32 songs. Due to a bug in PlaySID, the PSID format can only +handle up to 8 songs correctly. On the contrary, the SIDPLAY info format is +extended to 256 bits, which is equal to 256 songs. Examples: SPEED=0 +replays every song at 50 Hz speed. SPEED=1F replays songs 1-5 at 60 Hz +speed, all other songs at 50 Hz speed. + + NAME= + AUTHOR= + RELEASED= + or + COPYRIGHT= + + These three fields are all plain ASCII text strings. There are limited to +a maximum of 80 characters each. To not break compatibility to the PlaySID +formats, use a maximum of 31 characters. + + SIDSONG= + + is used to indicate that the corresponding C64 data file is in (Enhanced) +Sidplayer file format. This field is optional and defaults to NO. + + RELOC=, + + is used to indicate a free memory range not used by the sid tune. (e.g. + RELOC=04,65) + + CLOCK= + + is used to indicate the type of C64 the tune was original written for. + + SIDMODEL=<6581|8580> + + is used to indicate the type of sid chip the tune was original written + for. + + COMPATIBILITY= + + is used to indicate the compatibility mode of the sid tune. Normally this +would not be included but is set to R64 when the tune includes "sample" +music and will only play correctly on a real c64 or a newer sidplayer. This +is set to BASIC when the .dat file contains BASIC code. + +An example file ``EXAMPLE.SID'' may look like this: + + SIDPLAY INFOFILE + ADDRESS=2AF0,3002,300C + SONGS=3,2 + SPEED=0 + NAME=Example + AUTHOR=Example + RELEASED=199? (c) Example + SIDSONG=NO + + +PSID/RSID file header + + The detailed structure of the SID header looks like the following. Header +offsets are in hexadecimal notation. Other integer values are decimal +unless explicitly marked otherwise. Any stored integer values are in +big-endian format: + + +00 magicID: ``PSID'' or ``RSID'' + + This is a four byte long ASCII character string containing the value +0x50534944 or 0x52534944. 'RSID' (Real SID) denotes that the file strictly +requires a true Commodore-64 environment to run properly. 'PSID' files will +generally run trouble-free on older PlaySID and libsidplay1 based +emulators, too. + + + Some words about the Real C64 SID file format (RSID): + + The RSID format was designed to contain tunes that are not PlaySID +compatible, but strictly require a real C64 environment to run. Tunes that +are multi-speed and/or contain samples and/or use additional interrupt +sources or do busy looping will cause older SID emulators to lock up or +play very wrongly (if at all). + + By using the name RSID for such rips all existing SID emulators will +reject these tunes safely until they can be upgraded to cope with the +additional requirements. + + Due to the nature of these tunes, every effort must be made to make sure +they are directly runnable on an actual C64 computer. As such the tunes +will only be presented with the default C64 power-on environment and +expected to configure and use all hardware appropriately. + + +RSID is based on PSIDv2NG with the following modifications: + + magicID = RSID + version = only 2 + loadAddress = 0 (reserved) + playAddress = 0 (reserved) + speed = 0 (reserved) + psidSpecific flag is called C64BASIC flag + + The above fields MUST be checked and if any differ from the above then +the tune MUST be rejected. The definitions above will force tunes to +contain proper hardware configuration code and install valid interrupt +handlers. + + +The default C64 environment is as follows: + + VIC - IRQ set to raster 0, but not enabled. + CIA 1 timer A - set to 60Hz with the counter running and IRQs active. + Other timers - disabled and loaded with $FFFF. + Bank register - $37 + + A side effect of the bank register is that init MUST NOT be located under +a ROM/IO memory area (addesses $0000-$07E8, $A000-$BFFF and $D000-$FFFF). +Since every effort needs to be made to run the tune on a real C64 the load +address of the image MUST NOT be set lower than $07E8. + + +04 WORD version + + Available version number can either be 0001 or 0002. Headers of version 2 +provide additional fields. RSID and PSID v2NG files must have 0002 here. + + +06 WORD dataOffset + + This is the offset from the start of the file to the C64 binary data +area. Because of the fixed size of the header, this is either 0x0076 for +version 1 and 0x007C for version 2. + + +08 WORD loadAddress + + The C64 memory location where to put the C64 data. 0 means the data are +in original C64 binary file format, i.e. the first two bytes of the data +contain the little-endian load address (low byte, high byte). This must +always be true for RSID files. Furthermore, the actual load address must +NOT be less than $07E8 in RSID files. + + You must be absolutely sure what to enter here. There is no way to detect +automatically whether the first two bytes in a C64 data file are meant to +be a load address or some arbitrary bytes of code or data. Unless your C64 +file is not a normal binary file and thus has no load address in front, you +need not enter anything else than 0 here. The SID tune will not play if you +specify a load address which is present in the C64 file already. + + Normal C64 binary data files have a load address in their first two +bytes, so they can be loaded to a pre-defined destination address by +executing LOAD"FILE",8,1, for instance. If a load address is explicitly +specified in the sidtune info file, some sidtune converters and utilities +conjecture that the C64 data don't have a load address in their first two +bytes. Hence, the explicit load address from the info file is moved in +front of the C64 data to create a valid C64 binary file which can be easily +loaded on a C64, too. If that C64 file were to be saved, it would contain +two superfluous data bytes at offset 2 if an original load address had been +in the first two bytes of the old file. This process of adding a duplicate +load address can be repeated. The file loader strips off the first two +bytes (the used load address) and puts the rest of the file contents +(including the now obsolete load address at file offset 2) into memory. If +the new load address is the same than the old one the two added bytes cause +the whole data to be displaced by two bytes, which most likely results in +malfunctioning code. Also, superfluous bytes in memory then can confuse +disassemblers which start at the beginning of the file or memory buffer. + + +0A WORD initAddress + + The start address of the machine code subroutine that initializes a song, +accepting the contents of the 8-bit 6510 Accumulator as the song number +parameter. 0 means the address is equal to the effective load address. + + In RSID files initAddress must never point to a ROM area ($A000-$BFFF or +$D000-$FFFF) or be lower than $07E8. Also, if the C64 BASIC flag is set, +initAddress must be 0. + + +0C WORD playAddress + + The start address of the machine code subroutine that can be called +frequently to produce a continuous sound. 0 means the initialization +subroutine is expected to install an interrupt handler, which then calls +the music player at some place. This must always be true for RSID files. + + +0E WORD songs + + The number of songs (or sound effects) that can be initialized by calling +the init address. The minimum is 1. The maximum is 256. + + +10 WORD startSong + + The song number to be played by default. This value is optional. It often +specifies the first song you would hear upon starting the program is has +been taken from. It has a default of 1. + + +12 LONGWORD speed + + This is a 32 bit big endian number. Each bit in 'speed' specifies the +speed for the corresponding tune number, i.e. bit 0 specifies the speed for +tune 1. If there are more than 32 tunes, the speed specified for tune 32 is +also used for all higher numbered tunes. + + A 0 bit specifies vertical blank interrupt (50Hz PAL, 60Hz NTSC), and a 1 +bit specifies CIA 1 timer interrupt (default 60Hz). + + Surplus bits in 'speed' should be set to 0. + + For RSID files 'speed' must always be set to 0. + + Note that if 'play' = 0, the bits in 'speed' should still be set for +backwards compatibility with older SID players. New SID players running in +a C64 environment will ignore the speed bits in this case. + + WARNING: This field does not work in PlaySID for Amiga like it was +intended, therefore the above is a redefinition of the original 'speed' +field in SID v2NG! See also the 'clock' (video standard) field described +below for 'flags'. + + +16 ``'' + +36 ``'' + +56 ``'' (also known as ``'') + + These are 32 byte long zero terminated ASCII character strings. Upon +evaluating the header, a zero byte will always be put into the last byte of +each string. So the maximum number of available free characters is 31. + + +76 + + Version 1 of the SID header is complete at this point. The binary C64 +data starts here. + + Version 2 of the header incorporates the v1 header fields and provides +additional fields. Some of these are actually v2NG specific - those are +noted below. + + +76 WORD flags + + +This is a 16 bit big endian number containing the following bitfields: + + Bit 0 specifies format of the binary data (musPlayer): + 0 = built-in music player, + 1 = Compute!'s Sidplayer MUS data, music player must be merged. + + If this bit is set, the appended binary data are in Compute!'s Sidplayer +MUS format, and does not contain a built-in music player. An external +player machine code must be merged to replay such a sidtune. + + Bit 1 specifies whether the tune is PlaySID specific, e.g. uses PlaySID + samples (psidSpecific): + 0 = C64 compatible, + 1 = PlaySID specific (PSID v2NG) + 1 = C64 BASIC flag (RSID) + +This is a v2NG and RSID specific field. + + PlaySID samples were invented to facilitate playback of C64 volume +register samples with the original Amiga PlaySID software. PlaySID samples +made samples a reality on slow Amiga hardware with a player that was +updated only once a frame. + + Unfortunately, converting C64 volume samples to PlaySID samples means +that they can no longer be played on a C64, and furthermore the conversion +might potentially break the non-sample part of a tune if the timing between +writes to the SID registers is at all altered. This follows from the ADSR +bugs in the SID chip. + + Today, the speed of common hardware and the sophistication of the SID +players is such that there is little need for PlaySID samples. However, +with all the PlaySID sample PSIDs in existence there's a need to +differentiate between SID files containing only original C64 code and PSID +files containing PlaySID samples or having other PlaySID specific issues. +As stated above, bit 1 in 'flags' is reserved for this purpose. + + Since RSID files do not have the need for PlaySID samples, this flag is +used for a different purpose: tunes that include a BASIC executable portion +will be played (with the BASIC portion executed) if the C64 BASIC flag is +set. At the same time, initAddress must be 0. + + Bits 2-3 specify the video standard (clock): + 00 = Unknown, + 01 = PAL, + 10 = NTSC, + 11 = PAL and NTSC. + +This is a v2NG specific field. + + As can be seen from the 'speed' field, it is not possible to specify NTSC +C64 playback. This is unfortunate, since the different clock speeds means +that a tune written for the NTSC C64 will be slightly detuned if played +back on a PAL C64. Furthermore, NTSC C64 tunes driven by a vertical blank +interrupt have to be converted to use the CIA 1 timer to fit into this +scheme. This can cause severe problems, as the NTSC refresh rate is once +every 17045 cycles, while the CIA 1 timer A is latched with 17095 cycles. +Apart from the difference in timing itself, the SID ADSR bugs can actually +break the tune. + +The 'clock' (video standard) field was introduced to circumvent this +problem. + + Bits 4-5 specify the SID version (sidModel): + 00 = Unknown, + 01 = MOS6581, + 10 = MOS8580, + 11 = MOS6581 and MOS8580. + + This is a v2NG specific field. + + The MOS6581 and the MOS8580 have three notable differences. First, +combined waveforms are generally louder on a MOS8580, to the extent that +some combinations that are clearly audible on a MOS8580 are completely +silent on a MOS6581. Second, the internal DC levels in the MOS8580 are so +small that software or hardware tricks must be used to play volume samples. +Third, the MOS8580 analog filter has totally different characteristics from +the MOS6581 analog filter. + + To ensure that music specifically written for one of the two SID versions +can be played back correctly, bits 4-5 in 'flags' are used as stated above. + + Bits 6-15 are reserved and should be set to 0. + + +78 BYTE startPage (relocStartPage) + + This is a v2NG specific field. + + This is an 8 bit number. If 'startPage' is 0, the SID file is clean, i.e. +it does not write outside its data range within the driver ranges. In this +case the largest free memory range can be determined from the start address +and the data length of the SID binary data. If 'startPage' is 0xFF, there +is not even a single free page, and driver relocation is impossible. +Otherwise, 'startPage' specifies the start page of the single largest free +memory range within the driver ranges. For example, if 'startPage' is 0x1E, +this free memory range starts at $1E00. + + +79 BYTE pageLength (relocPages) + + This is a v2NG specific field. + + This is an 8 bit number indicating the number of free pages after +'startPage'. If 'startPage' is not 0 or 0xFF, 'pageLength' is set to the +number of free pages starting at 'startPage'. If 'startPage' is 0 or 0xFF, +'pageLength' must be set to 0. + + The relocation range indicated by 'startPage' and 'pageLength' should +never overlap or encompass the load range of the C64 data. For RSID files, +the relocation range should also not overlap or encompass any of the ROM +areas ($A000-$BFFF and $D000-$FFFF) or the reserved memory area +($0000-$03FF). + + +7A WORD reserved + + This is a 16 bit number and is reserved and should be set to 0. + + +7C + + Version 2 of the SID header ends here. This offset is the start of the +binary C64 data. See also 'loadAddress' for what the first 2 bytes of +'data' might indicate. + + + +MUS files + + The .MUS & .STR file name extensions are used for Compute's Sidplayer +music files. + + The overall file layout is as follows: + The first two bytes contain the load address. + The next two bytes contain the length of the data for Voice 1 + The next two bytes contain the length of the data for Voice 2 + The next two bytes contain the length of the data for Voice 3 + Then the data for Voice 1 follows immediately + Then the data for Voice 2 follows immediately + Then the data for Voice 3 follows immediately + Then the text description of the music file (upto 5 lines) + + The data for each Voice consists of a stream of two byte commands and +should be terminated with a HALT code which is 01 4F. + + The text description can be upto 5 lines long, each line upto 32 +characters wide. It is made up of PETSCII characters and may contain colour +codes. The text description should be terminated with a 00 byte (but might +not be). + diff --git a/Commodore/SPYNE.TXT b/Commodore/SPYNE.TXT new file mode 100644 index 0000000..538fc77 --- /dev/null +++ b/Commodore/SPYNE.TXT @@ -0,0 +1,131 @@ + +*** SPY (SPYne containers) +*** Document revision: 1.3 +*** Last updated: March 11, 2004 +*** Compiler/Editor: Peter Schepers +*** Contributors/sources: John Iannetta + + 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 file, 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 like a human spine. + + This format has some similarities to LNX containers 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 containers do not contain a BASIC program (like LNX) at the +beginning telling you to "Use XXX to dissolve this file", since SPYnes 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 +containers can store up to 144 files. + + Each file inside the container can have up to 65535 blocks. However, the +container 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 container 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 file, +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/high byte format) + 19: LSU byte (see "INTRO.TXT" document for description of + "LSU") + 1A: Last file marker + FF - more files in container + 00 - last file in container + 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. SPYnes cannot contain +write-protected, "splat" or DEL files. 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 file 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 file, 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 container 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. + diff --git a/Commodore/T64.TXT b/Commodore/T64.TXT new file mode 100644 index 0000000..4b4c78b --- /dev/null +++ b/Commodore/T64.TXT @@ -0,0 +1,221 @@ + +*** T64 (Tape containers for C64s) +*** Document revision: 1.5 +*** Last updated: March 11, 2004 +*** Compiler/Editor: Peter Schepers +*** Contributors/sources: Miha Peternel + + 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 container 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 container 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 container name, 24 characters, 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 conatiner 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. + + As mentioned previously, there are faulty T64 files around with the 'end load +address' value set to $C3C6. In order to work around this bug, here's how +to work with T64 files without relying on this value: + + 1. Read in the entire T64 header, ignoring the 'end load address' value + + 2. Sort the list by ascending order of offset into the T64 + + 3. Determine the difference in size (in bytes) between the first file + offset and the next one. Remember to add in the two 'load address' + bytes that are stored in the directory as they are part of the file. + + 4. You should now have your file size, and therefore be able to calculate + the 'end load address' value given the load address. + + +--------------------------------------------------------------------------- + +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 container, 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 all the + emulators start supporting this, it would not be a good idea to use + them this way. + + * 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 (?) + diff --git a/Commodore/TAP.TXT b/Commodore/TAP.TXT new file mode 100644 index 0000000..89d62f3 --- /dev/null +++ b/Commodore/TAP.TXT @@ -0,0 +1,75 @@ + +*** TAP (raw C64 cassette TAPE images) +*** Document revision: 1.1 +*** Last updated: March 11, 2004 +*** Compiler/Editor: Peter Schepers +*** Contributors/sources: Per Hakan Sundell, + Markus Brenner + + Designed by Per Hakan Sundell (author of the CCS64 C64 emulator) in 1997, +this format attempts to duplicate the data stored on a C64 cassette tape, +bit for bit. Since it is simply a representation of the raw serial data +from a tape, it should handle *any* custom tape loaders that exist. + + The TAP images are generally very large, being a minimum of eight times, +and up to sixteen times as large as what a raw PRG file would be. This is +due to the way the data is stored, with each bit of the original file now +being one byte large in the TAP file. The layout is fairly simple, with a +small 14-byte header followed by file data. + + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +0000: 43 36 34 2D 54 41 50 45 2D 52 41 57 00 00 00 00 C64-TAPE-RAW +0010: 51 21 08 00 2F 0F 0D 31 64 1D 26 0D 07 21 0A 12 Q!/1d&! +0020: 4A 2F 2C 34 07 18 0D 31 07 04 23 04 0D 42 0D 1E J/,41#B +0030: 34 04 42 0D 20 15 5E 04 0D 18 61 0D 26 29 34 0D 4B^a&)4 +0040: 23 0D 07 0A 3F 55 04 0A 13 3F 07 0D 12 2B 18 0A #?U?+ + + Bytes: $0000-000B: File signature "C64-TAPE-RAW" + 000C: TAP version (see below for description) + $00 - Original layout + 01 - Updated + 000D-000F: Future expansion + 0010-0013: File data size (not including this header, in + LOW/HIGH format) i.e. This image is $00082151 bytes + long. + 0014-xxxx: File data + + In TAP version $00 files, each data byte in the file data area represents +the length of a pulse, when the C64's hardware will trigger again. This +pulse length is determined by the following formula: + + pulse length (in seconds) = (8 * data byte) / (clock cycles) + + Therefore, a data value of $2F (47 in decimal) would be: + + (47 * 8) / 985248 = .00038975 seconds. + + A data value of $00 represents an "overflow" condition, any pulse length +which is more that 255 * 8 in length. + + The value of "clock cylces" from above (985248) is based on the PAL +value. Since this file format was developed in Europe, which is +predominantly PAL video, this is only logical. The NTSC value would be +1022730, which is very close to the PAL, and therefore won't cause a +compatability problem converting European and NTSC tapes. I would stick to +using the PAL value just in case. + + + In TAP version $01 files, the data value of $00 has been re-coded to +represent values greater than 255 * 8. When a $00 is encountered, three +bytes will follow which are the actual time (in cycles) of a pulse, and the +above formula does not apply. The three bytes are stored in LOW/HIGH +format. + + + The actual interpretation of the serial data takes a little more work to +explain. The typical ROM tape loader (and the turbo loaders) will +initialize a timer with a specified value and start it counting down. If +either the tape data changes or the timer runs out, an IRQ will occur. The +loader will determine which condition caused the IRQ. If the tape data +changed before the timer ran out, we have a short pulse, or a "0" bit. If +the timer ran out first, we have a long pulse, or a "1" bit. Doing this +continuously and we decode the entire file. + diff --git a/Commodore/VICE_FRZ.TXT b/Commodore/VICE_FRZ.TXT new file mode 100644 index 0000000..c091ed0 --- /dev/null +++ b/Commodore/VICE_FRZ.TXT @@ -0,0 +1,969 @@ + +*** VSF (Vice Snapshot File, saved-session file) +*** Document revision: 1.2 +*** Last updated: Oct 1, 2007 +*** Compiler/Editor: Peter Schepers +*** Contributors/sources: VICE documentation + + These files are the saved-session files, similar to C64s FRZ and PC64 +saved-session files, which contains the entire state of the CPU, RAM, ROM +and I/O of the current emulator session. The typical file extension is +".VSF" + + There was a claim that VICE was using the extension ".S64" for its +snapshot files. A package called UnQuill (in unquill.txt and unquill.c) +makes mention of VICE saving snapshot files with such an extension. As it +turns out, the UNIX version of VICE doesn't attach an extension when saving +a snapshot and the author of UnQuill chose S64 as the extension to save +them with. Therefore S64 files, if they exist, are an incorrectly named +VICE snapshot file from the UNIX world. + + The internal structure of a VICE snapshot is a signature, followed by a +series of modules, where the module types are determined by the CPU which +VICE is emulating. That is, if you are running the VICE VIC-20 emulator, +the modules will not all be the same as the C64 emulator. + + The modules contain individual chip or device states, not the complete +state of the emulator. The snapshot format was designed to be as +implementation-independent as possible, to allow reuse of snapshots in +later versions of the VICE emulator, or even in other emulators. + + The VICE signature is the simple text string... + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +0000: 56 49 43 45 20 53 6E 61 70 73 68 6F 74 20 46 69 VICESnapshotFi +0010: 6C 65 1A 00 00 43 31 32 38 00 00 00 00 00 00 00 leC128 +0020: 00 00 00 00 00 .. .. .. .. .. .. .. .. .. .. .. ........... + + Bytes: $00-12 - VICE signature "VICE Snapshot File" in ASCII followed + by a $1A (and padded with $00 if necessary) + 13-14 - Snapshot version $00/$00 (major/minor) + 15-24 - Name of emulated machine in ASCII (padded with $00). + The current machines emulated are (not stored with + quotes): + "PET" + "CBM-II" + "VIC20" + "C64" + "C128" + + + From now on, the snapshot file contains MODULES, with the module name +stored in ASCII. As stated earlier, each emulated machine type contains +certain modules. Note that each HEX dump which follows will be starting as +though it is at offset $0000, which means that each one is treated as +though it was its own file. This makes it easier to break down the module. + + The list below shows what modules belong to what machines: + + C64 - MAINCPU, C64MEM, C64ROM, VIC-II, CIA1, CIA2, SID, REU, ACIA1, TPI + + C128 - MAINCPU, C128MEM, C128ROM, VIC-II, CIA1, CIA2, SID, ACIA1, TPI + (Not yet supported are the 80 column video chip, cartridges and + RAM expansion unit.) + + VIC20 - MAINCPU, VIC20MEM, VIC20ROM, VIC-I, VIA1, VIA2 + + PET - MAINCPU, PETMEM, PETROM, CRTC, PIA1, PIA2, VIA, ACIA1 + + CBM-II - MAINCPU, CBM2MEM, CBM2ROM, CRTC, VIC-II, CIA1, TPI1, TPI2, ACIA1, + SID + + + There were certain modules which were either under construction or +included no description at all at the time of writing this document. These +include: + + MAINCPU (under construction) + DRIVE module layout (no description) + RIOT module (no description) + SID, VIC-I & VIC-II modules (no breakdown) + REU module(s) (no breakdown) + + +--------------------------------------------------------------------------- + + +The MAINCPU Module: + +Chip type: 6502 (6509 for CBM-II) (still under construction) + + Although usually the CPU is a 6510 (6509 on CBM-II, 6502 on VIC-20), only +the 6502 core is saved here. You will also find a clock value here. All +other modules save their own clock values relative to this value. The drive +modules save their clocks relative to their appropriate CPUs. + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +0000: 4D 41 49 4E 43 50 55 00 00 00 00 00 00 00 00 00 MAINCPU +0010: 01 00 35 00 00 00 F8 0E AA 00 00 00 00 F3 5E C2 5^ +0020: 22 F0 01 00 00 F1 00 AA 00 32 15 09 00 2B 00 00 "2+ +0030: 00 33 FE A9 00 .. .. .. .. .. .. .. .. .. .. .. 3........... + + Bytes: $0000-000F - Module type ("MAINCPU"), padded with $00 + 0010-0011 - Module version $01/00 (major/minor) + 0012-0015 - Module size (lo/hi), including this header + 0016-0019 - CPU clock value (lo/hi) + 001A - A register (accumulator) + 001B - X register + 001C - Y register + 001D - Stack pointer + 001E-001F - Program counter + 0020 - Status register + 0021-0024 - Last opcode + 0025-0028 - Clock value when IRQ line active + 0029-002C - Clock value when NMI line active + 002D-0030 - ??? + 0031-0034 - ??? + + +--------------------------------------------------------------------------- + + +The C64MEM Module: + +Chip type: Memory - Holds the RAM contents of the C64. Also the CPU I/O + register contents are saved here. This module is + mandatory. + + The size of the C64 memory modules differs with each different memory +configuration. The RAM configuration is saved in the snapshot, and restored +when the snapshot is loaded. The attached cartridges are not yet saved and +not yet restored upon load. + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +0000: 43 36 34 4D 45 4D 00 00 00 00 00 00 00 00 00 00 C64MEM +0010: 00 00 1A 00 01 00 37 2F 00 00 2F 37 00 AA B1 91 7//7 +0020: B3 22 22 00 00 00 00 FF 00 00 00 00 00 00 00 00 "" +0030: 19 16 00 0A 76 A3 00 00 00 00 00 00 76 A3 B3 BD vv +0040: 00 00 00 00 00 01 08 03 08 03 08 03 08 00 A0 00 + + Bytes: $0000-000F - Module type ("C64MEM"), padded with $00 + 0010-0011 - Module version $00/00 (major/minor) + 0012-0015 - Module size (lo/hi), including this header + 0016 - CPU Port data byte (RAM location $01) + 0017 - CPU Port direction byte (RAM location $00) + 0018 - State of the EXROM cartridge line + 0019 - State of the GAME cartridge line + 001A-10019 - 64K RAM dump + + +--------------------------------------------------------------------------- + + +The C64ROM Module: + +Chip type: ROMs - A dump of the system ROMs (optional) + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +0000: 43 36 34 52 4F 4D 00 00 00 00 00 00 00 00 00 00 C64ROM +0010: 00 00 16 50 00 00 85 56 20 0F BC A5 61 C9 88 90 PVaɈ +0020: 03 20 D4 BA 20 CC BC A5 07 18 69 81 F0 F3 38 E9 Ժ̼i8 +0030: 01 48 A2 05 B5 69 B4 61 95 61 94 69 CA 10 F5 A5 Hiaai +0040: 56 85 70 20 53 B8 20 B4 BF A9 C4 A0 BF 20 59 E0 VpSĠY +0050: A9 00 85 6F 68 20 B9 BA 60 85 71 84 72 20 CA BB oh`qrʻ + + Bytes: $0000-000F - Module type ("C64ROM"), padded with $00 + 0010-0011 - Module version $00/00 (major/minor) + 0012-0015 - Module size (lo/hi), not including this header + 0016-2015 - KERNAL ROM dump ($E000-FFFF) + 2016-4015 - BASIC ROM dump ($A000-BFFF) + 4016-5015 - CHARGEN ROM cump ($D000-DFFF) + + +--------------------------------------------------------------------------- + + +The VIC-II Module: + +Chip type: 656x - The contents of the VIC-II (C64, C128, or C500). Either + the VIC-II or the CRTC exists, not both in one snapshot. + +Breakdown not available as this module is still under construction. + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +0000: 56 49 43 2D 49 49 00 00 00 00 00 00 00 00 00 00 VIC-II +0010: 01 00 DD 04 00 00 01 00 01 0E 0E 0E 0E 0E 0E 0E +0020: 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E +0030: 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E + + Bytes: $0000-000F - Module type ("VIC-II"), padded with $00 + 0010-0011 - Module version $01/00 (major/minor) + 0012-0015 - Module size (lo/hi), including this header + 0016-04DC - VIC-II register contents + + +--------------------------------------------------------------------------- + + +The CIA1 Module: + +Chip type: 6526 (the CIA for the interrupts and the keyboard) + + The CIA 6526 is an I/O port chip with 2 8-bit I/O ports, a shift +register, two timers, a Time of Day clock and interrupts. + + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +0000: 43 49 41 31 00 00 00 00 00 00 00 00 00 00 00 00 CIA1 +0010: 01 02 41 00 00 00 7F 00 FF 00 09 2C FF FF 00 00 A, +0020: 00 01 00 01 01 08 25 40 FF FF 00 40 00 00 00 00 %@@ +0030: 00 00 02 00 00 00 00 2B 1C 00 00 63 08 28 11 00 +c( +0040: 00 .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ............... + + Bytes: $0000-000F - Module type ("CIA1"), padded with $00 + 0010-0011 - Module version $01/02 (major/minor) + 0012-0015 - Module size (lo/hi), including this header + 0016 - Output register A (ORA) + 0017 - Output register B (ORB) + 0018 - Data direction register A (DDRA) + 0019 - Data direction register B (DDRB) + 001A-001B - Timer A Counter (TAC) + 001C-001D - Timer B Counter (TBC) + 001E - Time-of-day current 10'th of a second (TOD_TEN) + 001F - Time-of-day current seconds (TOD_SEC) + 0020 - Time-of-day current minutes (TOD_MIN) + 0021 - Time-of-day current hours (TOD_HR) + 0022 - Shift register contents (SDR) + 0023 - Mask of enabled interrupts (IER) + 0024 - Control register A (CRA) + 0025 - Control register B (CRB) + 0026-0027 - Timer A latch value (TAL) + 0028-0029 - Timer B latch value (TBL) + 002A - Mask of currently active interrupts (IFR) + 002B - Bit 6/7 reflect the PB6/7 toggle bit state. Bit + 2/3 reflect the corresponding port bit state + (PBSTATE) + 002C - Number of half-bits to still shift in/out of SDR + (SRHBITS) + 002D - Time-of-day alarm 10'th of a second (ALARM_TEN) + 002E - Time-of-day alarm seconds (ALARM_SEC) + 002F - Time-of-day alarm minutes (ALARM_MIN) + 0030 - Time-of-day alarm hours (ALARM_HR) + 0031 - Current clock minus the clock when ICR was read + last plus 128 (READICR) + 0032 - Bit 0: 1= latched for reading, Bit 1: 2=stopped + for writing (TODLATCHED) + 0033 - Time-of-day latched 10'th of a second (TODL_TEN) + 0034 - Time-of-day latched seconds (TODL_SEC) + 0035 - Time-of-day latched minutes (TODL_MIN) + 0036 - Time-of-day latched hours (TODL_HR) + 0037-003A - Clock ticks till next 10'th of a second + (TOD_TICKS) + 003B-003C - The state bits of the CIA timer A (TASTATE, new + from revision 1.1) + 003D-003E - The state bits of the CIA timer B (TBSTATE, new + from revision 1.1) + + The last two items have been added in CIA snapshot version 1.1 due to the +improved CIA emulation in the newer VICE versions. Some state bits +correspond to the CIA state as described in the "A Software Model of the +CIA 6526" document by Wolfgang Lorenz, some are delayed versions. For more +read the source file ciatimer.h. + + +--------------------------------------------------------------------------- + + +The CIA2 Module: + +Chip type: 6526 (the CIA for the userport, IEC-bus and RS232) + +(See the CIA1 module for details) + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +0000: 43 49 41 32 00 00 00 00 00 00 00 00 00 00 00 00 CIA2 +0010: 01 02 41 00 00 00 97 00 3F 00 FF FF FF FF 00 00 A? +0020: 00 01 00 00 08 08 FF FF FF FF 00 00 00 00 00 00 +0030: 00 00 02 00 00 00 00 2B 1C 00 00 28 11 28 11 00 +(( +0040: 00 .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ............... + + Bytes: $0000-000F - Module type ("CIA2"), padded with $00 + 0010-0011 - Module version $01/02 (major/minor) + 0012-0015 - Module size (lo/hi), including this header + 0016-xxxx - See the CIA1 breakdown for details + + +--------------------------------------------------------------------------- + + +The SID Module: + +Chip type: 6581 (SID sound chip of the C64/C128) + +Breakdown not available yet, as module is still under construction. + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +0000: 53 49 44 00 00 00 00 00 00 00 00 00 00 00 00 00 SID +0010: 01 00 36 00 00 00 00 00 00 00 00 00 00 00 00 00 6 +0020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0030: 00 00 00 00 00 00 .. .. .. .. .. .. .. .. .. .. .......... + + Bytes: $0000-000F - Module type ("SID"), padded with $00 + 0010-0011 - Module version $01/00 (major/minor) + 0012-0015 - Module size (lo/hi), including this header + 0016-0035 - SID register contents + + +--------------------------------------------------------------------------- + + +The REU Module: + +Chip type: None - The RAM Extension Unit state (optional) + +Breakdown not available yet. + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +0000: 52 45 55 31 37 36 34 00 00 00 00 00 00 00 00 00 REU1764 +0010: 00 00 2A 00 08 00 00 02 00 00 50 4A 00 00 00 00 *PJ +0020: 00 00 00 00 00 00 00 00 00 00 0C 00 76 00 D4 BE vԾ +0030: 81 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + + Bytes: $000000-00000F - Module type ("REU1764"), padded with $00 + 000010-000011 - Module version $00/00 (major/minor) + 000012-000015 - Module size (lo/hi), including this header + 000016-080029 - REU contents + + +-------------------------------------------------------------------------- + + +The C128MEM Module: + +Chip type: RAM - Holds the RAM contents of the C64. Also the CPU I/O + register contents are saved here. This module is + mandatory. + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +0000: 43 31 32 38 4D 45 4D 00 00 00 00 00 00 00 00 00 C128MEM +0010: 00 00 21 00 02 00 00 3F 7F 01 41 B7 04 00 00 01 !?A +0020: 00 2F C3 00 00 00 00 00 00 00 00 00 00 00 9B 00 / +0030: 00 00 00 00 00 00 00 FF FF 1B 00 00 00 00 00 00 +0040: 00 00 00 00 00 03 02 00 00 00 00 00 00 00 01 1C + + Bytes: $000000-00000F - Module type ("C128MEM"), padded with $00 + 000010-000011 - Module version $00/00 (major/minor) + 000012-000015 - Module size (lo/hi), including this header + 000016-000021 - MMU registers (MMU) + 000022-020020 - 128K RAM dump (banks 0 and 1) + + +--------------------------------------------------------------------------- + + +The C128ROM Module: + +Chip type: ROMs - Dump of the system ROMs (optional) + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +0000: 43 31 32 38 52 4F 4D 00 00 00 00 00 00 00 00 00 C128ROM +0010: 00 00 16 C0 00 00 A2 FF 78 9A D8 A9 00 8D 00 FF xة +0020: A2 0A BD 4B E0 9D 00 D5 CA 10 F7 8D 04 0A 20 CD K +0030: E0 20 F0 E1 20 42 E2 20 09 E1 20 3D F6 48 30 07 B=H0 +0040: A9 A5 CD 02 0A F0 03 20 93 E0 20 56 E0 20 00 C0 V + + Bytes: $000000-00000F - Module type ("C128ROM"), padded with $00 + 000010-000011 - Module version $00/00 (major/minor) + 000012-000015 - Module size (lo/hi), including this header + 000016-002015 - KERNAL ROM dump + 002016-00A015 - BASIC ROM dump + 00A016-00B015 - EDITOR ROM dump + 00B016-00C016 - CHARGEN ROM dump + + +--------------------------------------------------------------------------- + + +The VIC20MEM Module: + +Chip type: RAM - Holds the RAM contents of the VIC20. This module is + mandatory. + + The size of the VIC20 memory modules differs with each different memory +configuration. The RAM configuration is saved in the snapshot, and restored +when the snapshot is loaded. The attached cartridges are also restored upon +load if they have been saved in the snapshot. + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +0000: 56 49 43 32 30 4D 45 4D 00 00 00 00 00 00 00 00 VIC20MEM +0010: 01 00 17 A8 00 00 2F 4C 48 D2 AA D1 91 D3 22 22 /LHҪё"" +0020: 00 00 00 00 FF 00 00 00 00 00 00 00 00 19 16 00 +0030: 0A 76 C3 00 00 00 00 00 00 76 C3 B3 DD 00 00 00 vvó +0040: 00 00 01 12 03 12 03 12 03 12 00 80 00 00 00 80 + + Bytes: $0000-000F - Module type ("VIC20MEM"), padded with $00 + 0010-0011 - Module version $01/00 (major/minor) + 0012-0015 - Module size (lo/hi), including this header + 0016 - Configuration register: (CONFIG) + Bit 0 set: 3K RAM block present at $0400-0FFF + Bit 1 set: 8K RAM block present at $2000-3FFF + Bit 2 set: 8K RAM block present at $4000-5FFF + Bit 3 set: 8K RAM block present at $6000-7FFF + Bit 5 set: 8K RAM block present at $A000-BFFF + 0017-0416 - 1K RAM dump ($0000-03FF) + 0417-1416 - 4K RAM dump ($1000-1FFF) + 1417-1B16 - 2K Color RAM ($9400-9BFF) + 1B17-2816 - 3K RAM dump ($0400-0FFF, if CONFIG bit 0 set) + 2817-4816 - 8K RAM dump ($2000-3FFF, if CONFIG bit 1 set) + 4817-6816 - 8K RAM dump ($4000-5FFF, if CONFIG bit 2 set) + 6817-8816 - 8K RAM dump ($6000-7FFF, if CONFIG bit 3 set) + 8817-A816 - 8K RAM dump ($A000-BFFF, if CONFIG bit 5 set) + + +--------------------------------------------------------------------------- + + +The VIC20ROM Module: + +Chip type: ROMs - Holds the ROM of the VIC20, including possibly attached + cartridges (optional) + + The size of the VIC20 memory modules differs with each different memory +configuration. The RAM configuration is saved in the snapshot, and restored +when the snapshot is loaded. The attached cartridges are also restored upon +load if they have been saved in the snapshot. + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +0000: 56 49 43 32 30 52 4F 4D 00 00 00 00 00 00 00 00 VIC20ROM +0010: 01 00 17 50 00 00 00 0F DC A5 61 C9 88 90 03 20 PܥaɈ +0020: D4 DA 20 CC DC A5 07 18 69 81 F0 F3 38 E9 01 48 ܥi8H +0030: A2 05 B5 69 B4 61 95 61 94 69 CA 10 F5 A5 56 85 iaaiV +0040: 70 20 53 D8 20 B4 DF A9 C4 A0 DF 20 56 E0 A9 00 pSߩĠV +0050: 85 6F 68 20 B9 DA 60 85 71 84 72 20 CA DB A9 57 oh`qr۩W + + Bytes: $0000-000F - Module type ("VIC20ROM"), padded with $00 + 0010-0011 - Module version $01/00 (major/minor) + 0012-0015 - Module size (lo/hi), including this header + 0016 - ROM configuration byte (CONFIG) + Bit 0: 1= ROM block $2xxx enabled. + Bit 1: 1= ROM block $3xxx enabled. + Bit 4: 1= ROM block $6xxx enabled. + Bit 5: 1= ROM block $7xxx enabled. + Bit 6: 1= ROM block $Axxx enabled. + Bit 7: 1= ROM block $Bxxx enabled. + 0017-2016 - 8K KERNAL ROM dump ($E000-FFFF) + 2017-4016 - 8K BASIC ROM dump ($C000-DFFF) + 4017-5016 - 4K Character ROM dump + 5017-6016 - 4K ROM image of $2xxx (if CONFIG Bit 0 set) + 6017-7016 - 4K ROM image of $3xxx (if CONFIG Bit 1 set) + 7017-8016 - 4K ROM image of $6xxx (if CONFIG Bit 4 set) + 8017-9016 - 4K ROM image of $7xxx (if CONFIG Bit 5 set) + 9017-A016 - 4K ROM image of $Axxx (if CONFIG Bit 6 set) + A017-B016 - 4K ROM image of $Bxxx (if CONFIG Bit 7 set) + + +--------------------------------------------------------------------------- + + +The VIC-I Module: + +Chip type: 656x - The VIC-I of the VIC20 + +(Breakdown not available as this module is still under contruction.) + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +0000: 56 49 43 2D 49 00 00 00 00 00 00 00 00 00 00 00 VIC-I +0010: 00 00 2B 08 00 00 01 00 00 00 00 06 06 06 06 06 + +0020: 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 +0030: 06 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 +0040: 01 01 01 01 01 01 01 06 06 06 06 06 06 06 06 06 + + Bytes: $0000-000F - Module type ("VIC-I"), padded with $00 + 0010-0011 - Module version $00/00 (major/minor) + 0012-0015 - Module size (lo/hi), including this header + 0016-xxxx - VIC-I register contents + + +--------------------------------------------------------------------------- + + +The VIA1 Module: + +Chip type: 6522 (the VIA for the interrupts and the keyboard) + + The VIA 6522 is the predecessor of the CIA and also an I/O port chip with +2 8-bit I/O ports, a shift register, two timers and interrupts. + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +0000: 56 49 41 31 00 00 00 00 00 00 00 00 00 00 00 00 VIA1 +0010: 01 00 2C 00 00 00 00 00 F7 FF 26 48 05 2C FF AB ,&H, +0020: F9 80 00 40 DE 00 40 00 00 80 FF 00 .. .. .. .. @@.... + + Bytes: $0000-000F - Module type ("VIA1"), padded with $00 + 0010-0011 - Module version $01/00 (major/minor) + 0012-0015 - Module size (lo/hi), including this header + 0016 - Output register A (ORA) + 0017 - Data direction register A (DDRA) + 0018 - Output register B (ORB) + 0019 - Data direction register B (DDRB) + 001A-001B - Timer 1 Latch value (T1L) + 001C-001D - Timer 1 counter value (T1C) + 001E - Timer 2 latch (T2L) + (8 bit as only lower byte is used) + 001F-0020 - Timer 2 counter value (T2C) + 0021 - RUNFL + bit 7: timer 1 will generate IRQ on underflow + bit 6: timer 2 will generate IRQ on underflow + 0022 - Shift register value (SR) + 0023 - Auxiliary control register (ACR) + 0024 - Peripheral control register (PCR) + 0025 - active interrupts (IFR) + 0026 - interrupt mask (IER) + 0027 - PB7 - bit 7 = pb7 state + 0028 - number of half-bits to shift out on SR (SRHBITS) + 0029 - CABSTATE + bit 7: state of CA2 pin + bit 6: state of CB2 pin + 002A - Port A Input Latch (see ACR bit 0) (ILA) + 002B - Port B Input Latch (see ACR bit 1) (ILB) + + +--------------------------------------------------------------------------- + + +The VIA2 Module: + +Chip type: 6522 (the VIA for the userport, IEC-bus and RS232) + +(see the VIA1 module for details) + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +0000: 56 49 41 32 00 00 00 00 00 00 00 00 00 00 00 00 VIA2 +0010: 01 00 2C 00 00 00 00 80 00 00 FF FF CE 66 FF AB ,f +0020: F9 00 00 40 FE 00 02 80 00 C0 7C 00 .. .. .. .. @|.... + + Bytes: $0000-000F - Module type ("VIA2"), padded with $00 + 0010-0011 - Module version $01/00 (major/minor) + 0012-0015 - Module size (lo/hi), including this header + 0016-002B - See the VIA1 breakdown for details + + +-------------------------------------------------------------------------- + + +The PETMEM Module: + +Chip type: RAM - Holds the RAM contents of the PET. This module is + mandatory. + + The size of the PET memory modules differs with each different memory +configuration. The RAM configuration is saved in the snapshot, and restored +when the snapshot is loaded. + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +0000: 50 45 54 4D 45 4D 00 00 00 00 00 00 00 00 00 00 PETMEM +0010: 01 02 1D 88 00 00 02 00 20 00 07 4C 73 C3 22 22 Ls"" +0020: 5B 00 FF 00 01 00 00 00 00 00 00 00 FF FF 16 13 [ +0030: 00 08 12 B3 00 00 00 00 00 00 12 B3 E9 CE 00 00 +0040: 00 00 00 01 04 03 04 03 04 03 04 00 80 00 00 00 + + Bytes: $0000-000F - Module type ("PETMEM"), padded with $00 + 0010-0011 - Module version $01/02 (major/minor) + 0012-0015 - Module size (lo/hi), including this header + 0016 - Configuration value. + Bits 0-3: 0 = 40 col PET without CRTC + 1 = 40 col PET with CRTC + 2 = 80 col PET (with CRTC) + 3 = SuperPET + 4 = 8096 + 5 = 8296 + Bit 6: 1= RAM at $9*** + Bit 7: 1= RAM at $A*** + 0017 - Keyboard type. + 0 = UK business + 1 = Graphics + 2 = German business + 0018 - memory size of low 32k in k + (possible values 4, 8, 16, 32) + 0019 - Value of the 8x96 configuration register + (CONF8X96) + 001A - SuperPET config + Bit 0: 1 = $9*** RAM enabled + Bit 1: 1 = RAM write protected + Bit 2: 1 = CTRL register write protected + Bit 3: 0 = DIAG pin active + Bits 4-7: RAM block in use + 001B-xxxx - 4-32k RAM (not 8296, size depends on MEMSIZE) + xxxx-xxxx - 2/4k VRAM (not 8296, size depends on CONFIG) + xxxx-xxxx - 64k expansion RAM (SuperPET and 8096 only) + xxxx-xxxx - 128k RAM (8296 only) + xxxx - POSITIONAL + bit 0: 0 = symbolic keyboard mapping + bit 0: 1 = positional mapping + +The last item has been added in PETMEM snapshot version 1.1. It is ignored +by earlier restore routines (V1.0) and the V1.1 restore routines do not +change the current setting when reading a V1.0 snapshot. + + +-------------------------------------------------------------------------- + + +The PETROM Module: + +Chip type: ROMs - Holds the ROM of the PET, including possibly attached + cartridges (optional) + + The size of the PET memory modules differs with each different memory +configuration. The RAM configuration is saved in the snapshot, and restored +when the snapshot is loaded. + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +0000: 50 45 54 52 4F 4D 00 00 00 00 00 00 00 00 00 00 PETROM +0010: 01 00 17 50 00 00 04 54 4F 4F 20 4D 41 4E 59 20 PTOOMANY +0020: 46 49 4C 45 D3 46 49 4C 45 20 4F 50 45 CE 46 49 FILEFILEOPEFI +0030: 4C 45 20 4E 4F 54 20 4F 50 45 CE 46 49 4C 45 20 LENOTOPEFILE +0040: 4E 4F 54 20 46 4F 55 4E C4 0D 53 45 41 52 43 48 NOTFOUNSEARCH + + Bytes: $0000-000F - Module type ("PETROM"), padded with $00 + 0010-0011 - Module version $01/00 (major/minor) + 0012-0015 - Module size (lo/hi), including this header + 0016 - CONFIG + Bit 0: 1 = $9*** ROM included + Bit 1: 1 = $A*** ROM included + Bit 2: 1 = $B*** ROM included + Bit 3: 1 = $e900-$efff ROM included + 0017-xxxx - 4k KERNAL ROM image $f000-$ffff + xxxx-xxxx - 2k EDITOR ROM image $e000-$e7ff + xxxx-xxxx - 2k CHARGEN ROM image + xxxx-xxxx - 4k $9*** ROM image (if CONFIG & 1) + xxxx-xxxx - 4k $A*** ROM image (if CONFIG & 2) + xxxx-xxxx - 4k $B*** ROM image (if CONFIG & 4) + xxxx-xxxx - 4k $C*** ROM image + xxxx-xxxx - 4k $D*** ROM image + xxxx-xxxx - 7 blocks $e900-$efff ROM image (if CONFIG & 8) + + +-------------------------------------------------------------------------- + + +The CRTC Module: + +Chip type: 6545 - The CRTC of the PET, C6x0 and C7x0. This can even be + included if it is a dump of a PET without CRTC. + +This module is still under construction. The values for RASTERY and +RASTERLINE might be bogus. + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +0000: 43 52 54 43 00 00 00 00 00 00 00 00 00 00 00 00 CRTC +0010: 01 00 55 00 00 00 FF 07 00 08 00 20 00 10 FF 1F U +0020: 00 10 00 02 00 3F 28 32 08 20 10 19 1D 00 08 00 ?(2 +0030: 00 10 00 00 00 00 00 00 00 00 00 1F 06 00 00 00 +0040: 00 10 B0 09 00 00 00 C0 02 1A 01 00 00 00 00 1C +0050: 00 39 01 1D 01 .. .. .. .. .. .. .. .. .. .. .. 9........... + + Bytes: $0000-000F - Module type ("CRTC"), padded with $00 + 0010-0011 - Module version $01/00 (major/minor) + 0012-0015 - Module size (lo/hi), including this header + 0016-0054 - ???? + + +-------------------------------------------------------------------------- + + +The PIA1 Module: + +Chip type: 6520 (the PIA for the interrupts, tape and the keyboard) + + The PIA 6520 is a chip with two I/O ports (Parallel Interface Adapter) +and four additional handshake lines. The chip is much the same for Port A +and B, only that Port A implements handshaking on read operation and port B +on the write operation. + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +0000: 50 49 41 31 00 00 00 00 00 00 00 00 00 00 00 00 PIA1 +0010: 01 00 1D 00 00 00 F9 0F 3C FF 00 3D C0 .. .. .. <=... + + Bytes: $0000-000F - Module type ("PIA1"), padded with $00 + 0010-0011 - Module version $01/00 (major/minor) + 0012-0015 - Module size (lo/hi), including this header + 0016 - Output register A (ORA) + 0017 - Data Direction Register A (DDRA) + 0018 - Control Register A (CTRLA) + 0019 - Output register B (ORB) + 001A - Data Direction Register B (DDRB) + 001B - Control Register B (CTRLB) + 001C - Bit 7:state of CA2, Bit 6:state of CB2 (CABSTATE) + + +-------------------------------------------------------------------------- + + +The PIA2 Module: + +Chip type: 6520 (the PIA for the IEEE488-bus) + +(see the PIA1 module for details) + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +0000: 50 49 41 32 00 00 00 00 00 00 00 00 00 00 00 00 PIA2 +0010: 01 00 1D 00 00 00 FF 00 3C FF FF 3C C0 .. .. .. <<... + + Bytes: $0000-000F - Module type ("PIA2"), padded with $00 + 0010-0011 - Module version $01/00 (major/minor) + 0012-0015 - Module size (lo/hi), including this header + 0016-001C - See the PIA1 breakdown for details + + +-------------------------------------------------------------------------- + + +The VIA Module: + +Chip type: 6522 (the VIA for IEEE488, userport, sound) + +(see the VIA1 module for details) + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +0000: 56 49 41 00 00 00 00 00 00 00 00 00 00 00 00 00 VIA +0010: 01 00 2C 00 00 00 00 00 DF 1E FF FF CE 7B 0E 58 ,{X +0020: 77 00 00 00 0E 40 00 80 00 C0 00 DF .. .. .. .. w@.... + + Bytes: $0000-000F - Module type ("VIA"), padded with $00 + 0010-0011 - Module version $01/00 (major/minor) + 0012-0015 - Module size (lo/hi), including this header + 0016-002B - See the VIA1 breakdown for details + + +-------------------------------------------------------------------------- + + +The CBM2MEM Module: + +Chip type: RAM - Holds the RAM contents of the CBM-II models. Also holds + the exec-bank and indirection bank registers. This module + is mandatory. + + The size of the CBM-II memory modules differs with each different memory +configuration. The RAM configuration is saved in the snapshot, and restored +when the snapshot is loaded. + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +0000: 43 42 4D 32 4D 45 4D 00 00 00 00 00 00 00 00 00 CBM2MEM +0010: 01 00 1B 10 02 00 01 00 02 0F 01 0F 01 4C A7 9B L +0020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 +0030: 00 00 D4 FA 02 00 FF FF 00 FF FF C8 FA 5E FA 01 ^ +0040: 00 00 00 00 00 00 00 00 03 00 05 00 02 00 00 00 +0050: 02 00 00 00 02 00 BD FA 00 00 BD FA 02 00 FF 00 +0060: 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00 00 + + Bytes: $0000-000F - Module type ("CBM2MEM"), padded with $00 + 0010-0011 - Module version $01/00 (major/minor) + 0012-0015 - Module size (lo/hi), including this header + 0016 - Memory size in 128k blocks (MEMSIZE) + (1=128k, 2=256k, 4=512k, 8=1024k) + 0017 - MEMCONFIG + Bit 0 = $f0800-$f0fff RAM + Bit 1 = $f1000-$f1fff RAM + Bit 2 = $f2000-$f3fff RAM + Bit 3 = $f4000-$f5fff RAM + Bit 4 = $f6000-$f7fff RAM + Bit 5 = $fc000-$fcfff RAM + 0018 - HWCONFIG + Bit 0: 0 = CRTC + 1 = VIC-II video chip + (Basically the destinction between + C500 and C600/700) + 0019 - CPUs execution bank register (EXECBANK) + 001A - CPUs indirection bank register (INDBANK) + 001B-xxxx - 2k system RAM $f0000-$f07ff + xxxx-xxxx - 2k video RAM $fd000-$fd7ff + xxxx-xxxx - RAM dump, size according to MEMSIZE + xxxx-xxxx - if memsize < 1M and CONFIG & 1 then + 2k RAM $f0800-$f0fff + xxxx-xxxx - if memsize < 1M and CONFIG & 2 then + 4k RAM $f1000-$f1fff + xxxx-xxxx - if memsize < 1M and CONFIG & 4 then + 8k RAM $f2000-$f3fff + xxxx-xxxx - if memsize < 1M and CONFIG & 8 then + 8k RAM $f4000-$f5fff + xxxx-xxxx - if memsize < 1M and CONFIG & 16 then + 8k RAM $f6000-$f7fff + xxxx-xxxx - if memsize < 1M and CONFIG & 32 then + 4k RAM $fc000-$fcfff + +The RAM arrays are only saved if the RAM itself is less than 1M. If the +memory size is 1M then those areas are taken from the bank 15 area of the +normal RAM. + + +-------------------------------------------------------------------------- + + +The CBM2ROM Module: + +Chip type: ROMs - Holds the ROM images (optional) + + The size of the CBM-II memory modules differs with each different memory +configuration. The RAM configuration is saved in the snapshot, and restored +when the snapshot is loaded. + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +0000: 43 42 4D 32 52 4F 4D 00 00 00 00 00 00 00 00 00 CBM2ROM +0010: 01 00 17 70 00 00 00 4C 09 EE EA 4C 44 E0 4C FE pLLDL +0020: E0 4C 79 E1 4C 99 E2 4C 3F E0 4C 65 E8 4C DA E0 LyLL?LeL +0030: 4C 25 E0 4C 3A E0 4C 70 E9 4C F8 E6 B0 0E 86 CA L%L:LpL +0040: 86 CF 84 CB 84 CE 20 CD E0 20 DA E0 A6 CA A4 CB τ˄ʤ +0050: 60 A2 00 A0 DC 60 A2 50 A0 19 60 A9 00 A2 23 95 ``P`# + + Bytes: $0000-000F - Module type ("CBM2ROM"), padded with $00 + 0010-0011 - Module version $01/00 (major/minor) + 0012-0015 - Module size (lo/hi), including this header + 0016 - CONFIG + Bit 1: 1 = $1*** ROM image included + Bit 2: 1 = $2000-$3fff ROM image included + Bit 3: 1 = $4000-$5fff ROM image included + Bit 4: 1 = $6000-$7fff ROM image included + 0017-xxxx - 8k KERNAL ROM image ($e000-$efff) + xxxx-xxxx - xK BASIC ROM image + xxxx-xxxx - 4k CHARGEN ROM image + xxxx-xxxx - 4k cartridge ROM image for $1*** + (if CONFIG & 2) + xxxx-xxxx - 8k cartridge ROM image for $2000-$3fff + (if CONFIG & 4) + xxxx-xxxx - 8k cartridge ROM image for $4000-$5fff + (if CONFIG & 8) + xxxx-xxxx - 8k cartridge ROM image for $6000-$7fff + (if CONFIG & 16) + + +-------------------------------------------------------------------------- + + +The TPI1 Module: + +Chip type: 6525 (TPI 1 for IEEE488) + + The TPI 6525 is a chip with three I/O ports (Tri-Port-Interface). One of +the ports can double as an interrupt prioritizer. Therefore we also have to +save the states of the interrupt stack etc. + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +0000: 54 50 49 31 00 00 00 00 00 00 00 00 00 00 00 00 TPI1 +0010: 01 00 20 00 00 00 38 3F 00 3F 7D FF E3 00 00 40 8??}@ + + Bytes: $0000-000F - Module type ("TPI1"), padded with $00 + 0010-0011 - Module version $01/00 (major/minor) + 0012-0015 - Module size (lo/hi), including this header + 0016 - Port A output register (PRA) + 0017 - Port B output register (PRB) + 0018 - Port C output register (PRC) - Doubles as IRQ + latch register + 0019 - Port A data direction register (DDRA) + 001A - Port B data direction register (DDRB) + 001B - Port C data direction register (DDRC) - Doubles + as IRQ mask register + 001C - Control Register (CR) + 001D - Active interrupt register + 001E - Interrupt stack, the interrupt bits that are not + yet saved (STACK) + 001F - State of the CA/CB pins... (CABSTATE) + Bit 7: State of CA + Bit 6: State of CB + + +-------------------------------------------------------------------------- + + +The TPI2 Module: + +Chip type: 6525 (TPI 2 for interrupts and keyboard) + +(see the TPI1 module for details) + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +0000: 54 50 49 32 00 00 00 00 00 00 00 00 00 00 00 00 TPI2 +0010: 01 00 20 00 00 00 7F FF 00 FF FF 00 00 00 00 00  + + Bytes: $0000-000F - Module type ("TPI2"), padded with $00 + 0010-0011 - Module version $01/00 (major/minor) + 0012-0015 - Module size (lo/hi), including this header + 0016-001F - See the TPI1 breakdown for details + + +-------------------------------------------------------------------------- + + +The ACIA1 Module: + +Chip type: 6551 - An ACIA (RS232 interface) at $DE00 (C64, optional) (or) + The ACIA for the SuperPET or CBM-II (optional) + + The ACIA 6551 is an RS232 interface chip. VICE emulates RS232 connections +via /dev/ttyS* (Unix) or COM: (DOS/WIN - not yet?). When saving a snapshot, +those connections are of course lost. The state of the ACIA however is +restored if possible. I.e. if a connection is already open when restoring +the snapshot, this connection is used instead. If no connection is open, a +carrier/DTR drop is emulated. + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +0000: 41 63 69 61 31 00 00 00 00 00 00 00 00 00 00 00 Acia1 +0010: 01 00 20 00 00 00 00 00 10 00 00 00 00 00 00 00 + + Bytes: $0000-000F - Module type ("ACIA1"), padded with $00 + 0010-0011 - Module version $01/00 (major/minor) + 0012-0015 - Module size (lo/hi), including this header + 0016 - Transmit data register (TDR) + 0017 - Receiver data register (RDR) + 0018 - Status register (SR) + 0019 - Command register (CMD) + 001A - Control register (CTRL) + 001B - 0 = no data to tx + 1 = Data is being transmitted + 2 = Data is being transmitted while data in TDR + waiting to be put to internal transmit + register + 001C-001F - Clock ticks till the next TDR empty interrupt + + +-------------------------------------------------------------------------- + + +The TPI Module: + +Chip type: 6525 (TPI at $DF00 for a parallel IEEE488 interface, optional + module on the C64) + +(see the TPI1 module for details) + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +0000: 54 50 49 00 00 00 00 00 00 00 00 00 00 00 00 00 TPI +0010: 01 00 20 00 00 00 00 00 00 00 00 00 00 00 00 00 + + Bytes: $0000-000F - Module type ("TPI"), padded with $00 + 0010-0011 - Module version $01/00 (major/minor) + 0012-0015 - Module size (lo/hi), including this header + 0016-001F - See the TPI1 breakdown for details + + +-------------------------------------------------------------------------- + diff --git a/Commodore/WAV.TXT b/Commodore/WAV.TXT new file mode 100644 index 0000000..643b344 --- /dev/null +++ b/Commodore/WAV.TXT @@ -0,0 +1,145 @@ + +*** WAV (RIFF audio files) Resource Interchange File Format +*** Document revision: 1.1 +*** Last updated: March 11, 2004 +*** Compiler/Editor: Peter Schepers +*** Contributors/sources: Various net documents + + The WAV file is a variant of the RIFF format, specifically used for +audio. RIFF is a generic format used mainly for video (AVI) and audio. It +is built up with "chunks" which contain a chunk ID and a chunk size. + + Below is a dump of a sample WAV file showing the header. + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +0000: 52 49 46 46 D4 45 CC 01 57 41 56 45 66 6D 74 20 RIFFEWAVEfmt +0010: 10 00 00 00 01 00 02 00 44 AC 00 00 10 B1 02 00 D +0020: 04 00 10 00 64 61 74 61 B0 45 CC 01 95 00 6D FF dataEm +0030: 97 00 77 FF 6E 00 25 FF 58 00 14 FF 75 00 ED FE wn%Xu +0040: 62 00 33 FE 2C 00 07 FE C4 FF 7A FE 53 FF C3 FE b3,zS +0050: 91 FF 83 FE 21 00 91 FE EB 00 0D FF FF 00 57 FF !W +0060: 98 00 C4 FF 9F 00 79 00 60 00 DD 00 07 00 1D 01 y` + + + $0000-0003: Chunk ID "RIFF" in ASCII ("RIFX" files identify the + samples audio data in hi/lo format instead of the normal + lo/hi format) + + 0004-0007: Chunk size (lo/hi) $01CC45D4=30,164,452 is the total size + minus 8 (these first 8 bytes are not included in the + overall size) + + 0008-000B: Chunk format "WAVE". This format requires two subchunks to + exist, "fmt " and "data". + + 000C-000F: Subchunk1 ID "fmt ". This describes the format of the next + DATA subchunk. + + 0010-0013: Subchunk size (lo/hi) $00000010 (usually this value for + PCM audio) + + 0014-0015: Audio format (1=PCM, 2 and higher are custom) ($0001) + - $0001 = standard PCM + - $0101 = IBM mu-law (custom) + - $0102 = IBM a-law (custom) + - $0103 = IBM AVC ADPCM (custom) + + 0016-0017: Number of channels (1=mono, 2=stereo, etc) ($0002) + + 0018-001B: Sample rate per second (lo/hi) $0000AC44 = 44100 + + 001C-001F: Byte rate per second (=sample rate * number of channels * + (bits per channel/8)) $0002B110 = 176400 + + 0020-0021: Block Align (=number of channels * bits per sample/8) + ($0004). + + 0022-0023: Bits per sample (8=8 bits, 16=16 bits) ($0010). Samples + not using the entire bit range allocated should set the + unused bits off. + + 0024-0027: Subchunk2 ID "data". This chunk contains the audio + samples. There can be more than one in a WAV file. + + 0028-002B: Subchunk2 size (lo/hi) ($01CC45B0=30,164,400) + + 002C-xxxx: Audio data (lo/hi), stored as 2's complimented signed + integers in the following order: + + Sample 1: Channel1 (left) ($0095=+149) + Sample 1: Channel2 (right) ($FF6D=-) + Sample 2: Channel1 (left) ($0097=+151) + Sample 2: Channel2 (right) ($FF77=-) + Sample 3: Channel1 (left) ($006E=+110) + Sample 3: Channel2 (right) ($FF25=-) + +Notes: 8-bit samples are stored as unsigned chars, with values ranging + ranging from 0-255. 16-bit samples are stored as signed integers, + with values ranging from -32768 to 32767 + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +2D402C: 4C 49 53 54 40 00 00 00 49 4E 46 4F 49 53 46 54 LIST@INFOISFT +2D403C: 15 00 00 00 53 6F 6E 79 20 53 6F 75 6E 64 20 46 SonySoundF +2D404C: 6F 72 67 65 20 37 2E 30 00 00 49 45 4E 47 02 00 orge7.0IENG +2D405C: 00 00 20 00 49 43 52 44 0B 00 00 00 32 30 30 33 ICRD2003 +2D406C: 2D 31 30 2D 31 37 00 02 .. .. .. .. .. .. .. .. -10-17........ + + Above is a dump of the end of a WAV file, with the LIST information chunk +shown. The four bytes (40 00 00 00) immediately following the "LIST" +identifier show the size of the LIST chunk, in LO/HI format. In this case, +the chunk size is $00000040, or 64 bytes. + + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +02F488AC: 63 75 65 20 C4 00 00 00 08 00 00 00 01 00 00 00 cue +02F488BC: 00 C0 21 00 64 61 74 61 00 00 00 00 00 00 00 00 !data +02F488CC: 00 C0 21 00 02 00 00 00 00 40 11 00 64 61 74 61 !@data +02F488DC: 00 00 00 00 00 00 00 00 00 40 11 00 03 00 00 00 @ +02F488EC: 00 00 3A 00 64 61 74 61 00 00 00 00 00 00 00 00 :data +02F488FC: 00 00 3A 00 04 00 00 00 00 00 59 00 64 61 74 61 :Ydata +02F4890C: 00 00 00 00 00 00 00 00 00 00 59 00 05 00 00 00 Y +02F4891C: 00 C0 6C 00 64 61 74 61 00 00 00 00 00 00 00 00 ldata +02F4892C: 00 C0 6C 00 06 00 00 00 00 40 84 00 64 61 74 61 l@data +02F4893C: 00 00 00 00 00 00 00 00 00 40 84 00 07 00 00 00 @ +02F4894C: 00 80 9A 00 64 61 74 61 00 00 00 00 00 00 00 00 data +02F4895C: 00 80 9A 00 08 00 00 00 00 00 AC 00 64 61 74 61 data +02F4896C: 00 00 00 00 00 00 00 00 00 00 AC 00 4C 49 53 54 LIST +02F4897C: 84 00 00 00 61 64 74 6C 6C 61 62 6C 07 00 00 00 adtllabl +02F4898C: 01 00 00 00 30 31 00 00 6C 61 62 6C 07 00 00 00 01labl +02F4899C: 02 00 00 00 30 32 00 00 6C 61 62 6C 07 00 00 00 02labl +02F489AC: 03 00 00 00 30 33 00 00 6C 61 62 6C 07 00 00 00 03labl +02F489BC: 04 00 00 00 30 34 00 00 6C 61 62 6C 07 00 00 00 04labl +02F489CC: 05 00 00 00 30 35 00 00 6C 61 62 6C 07 00 00 00 05labl +02F489DC: 06 00 00 00 30 36 00 00 6C 61 62 6C 07 00 00 00 06labl +02F489EC: 07 00 00 00 30 37 00 00 6C 61 62 6C 07 00 00 00 07labl +02F489FC: 08 00 00 00 30 38 00 00 .. .. .. .. .. .. .. .. 08........ + + Above is the "cue " chunk layout, also at the end of the WAV. These +describe cue points (or markers) placed in the WAV file. + + + To analyse a WAV file quickly is very easy: + + 1. Examine the initial chunk ID (RIFF) and its size. The size should be + the filesize-8. + + 2. Check for the WAVE chunk ID next. If it's not there then you don't + have a proper WAV file. + + 3. Now you can start checking the individual sub-chunks. Read in 8 + bytes. The first four are the sub-chunk ID and the last four are the + sub-chunk size. If you want to check the contents of the sub-chunk + thats up to you. + + 4. If you seek forward in the file the size of the sub-chunk you will + find yourself at the next sub-chunk. + + + WAV files can also have other sub-chunk ID's such as FACT, ASFP and LIST. +I will not get into the specifics of these. There are other more extensive +documents on the web that describe the WAV and RIFF format much better than +I can. + diff --git a/Commodore/WRA-WR3.TXT b/Commodore/WRA-WR3.TXT new file mode 100644 index 0000000..4a02885 --- /dev/null +++ b/Commodore/WRA-WR3.TXT @@ -0,0 +1,226 @@ + +*** WRA, WR3 (WRAptor compressed files, and version 3.0 files) +*** Document revision: 1.4 +*** Last updated: March 11, 2004 +*** Compiler/Editor: Peter Schepers +*** Contributors/sources: Todd Elliott, + Fender Tucker & Doreen Horne (Loadstar) + + Written by Bill Lucier (copyright 1995), distributed by Loadstar (on disk +and from the website), and fixed/updated by Doreen Horne, this is an +uncommon compression format as it is a relatively new program. It handles +PRG, SEQ, USR and GEOS files (Sequential and VLIR), but not REL files. As +of this writing, the latest bug fixed version was 3.0B. It is the support +for compressing GEOS files which makes this program special. + + Many thanks to Fender Tucker (from Loadstar) and Doreen Horne for their +support on the Wraptor format, as well as authorizing the release of the +source code, and subsequent documentation of the format. I hope this +prolongs the life and usefulness of Wraptor. + + Wraptor utilizes a variant of the LZSS (Lempel-Ziv) compression +algorithm, starting at 9 bits per code. The following is a dump of a sample +WRA file. The four bytes at the beginning of the file, "FF 42 4C FF" are +the signature, and preceed each compressed file in the archive. The "42 4C" +are the authors initials, "BL". + + 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=(unsigned)32768) + { + /* Write out the buffer to the output file */ + /* Here is where we would decode the GEOS file structure */ + fwrite(buffer, 1, buff_pointer, writefile); + + /* Reset buffer pointer for another block of data */ + buff_pointer=0; + } + } + + /* Encoded data, preceeded by a one bit */ + else + { + /* Get dictionary offset */ + dict_offset=get_bits(read_bitsize); + + /* A "0" offset, either an EOF or increase read_bitsize by one */ + if(!dict_offset) + { + /* Check next bit */ + tmp=get_bits(1); + + /* If next bit clear, we are at the end of the compressed file */ + if(!tmp) + { + /* Write output buffer to the output file */ + /* Here is where we would decode the GEOS file structure */ + fwrite(buffer, 1, buff_pointer,writefile); + buff_pointer=0; + break; + } + /* If next bit set, increase read_bitsize by one */ + else + { + read_bitsize++; + } + } + + /* We have a valid offset, get the length */ + else + { + /* Length of the stored string, 5 bits */ + rep_length=get_bits(5); + + /* + Copy the data from in the buffer at the dict_offset position to + the end of the buffer + */ + + for(i=0;i=(unsigned)32768) + { + fwrite(buffer, 1, buff_pointer,writefile); + buff_pointer=0; + } + } + } + } + } + + /* Get the two-byte CRC which follows the compressed data stream */ + get_crc(); + + /* Make sure the CRC you read matches the one you calculated */ + check_crc(); + + fclose(readfile); + fclose(writefile); +} + + diff --git a/Commodore/X64.TXT b/Commodore/X64.TXT new file mode 100644 index 0000000..016e717 --- /dev/null +++ b/Commodore/X64.TXT @@ -0,0 +1,94 @@ + +*** X64 (X64 and VICE emulator image files) +*** Document revision: 1.3 +*** Last updated: March 11, 2004 +*** Compiler/Editor: Peter Schepers +*** Contributors/sources: Jouko Valta + + This file type, created by Teemu Rantanen, is used on the X64 emulator (a +UNIX-based emulator) which has been superceeded by VICE. Both Vice and X64 +support the X64 file standard, with Vice also supporting the regular D64 +and T64 files. + + X64 is not a specific type of file, but rather encompasses *all* known +C64 disk types (hard disk, floppies, etc). An X64 is created by prepending +a 64-byte header to an existing image (1541, 1571, etc) and setting +specific bytes which describe what type of image follows. This header has +undergone some revision, and this description file is based on the 1.02 +version, which was the last known at the time of writing. + + The most common X64 file you will see is the D64 variety, typically +174912 bytes long (174848 for the D64 and 64 bytes for the header, assuming +no error bytes are appended). The header layout (as used in 64COPY) is as +follows: + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +0000: 43 15 41 64 01 02 01 23 00 00 00 00 00 00 00 00 C.Ad...# +0010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +0040: XX XX XX <- standard C64 image starts here.... + + Bytes:$00-03: This is the "Magic header" ($43 $15 $41 $64) + 04: Header version major ($01) + 05: Header version minor ($01, now its up to $02) + 06: Device type represented ($00) + $00=1540 See note below... + $01=1541 (Default) + $02=1542 + $03=1551 + $04=1570 + $05=1571 + $06=1572 + $08=1581 + $10=2031,4031 + $11=2040,3040 + $12=2041 + $18=4040 + $20=8050 + $21=8060 + $22=8061 + $30=SFD-1001 + $31=8250 + $32=8280 + 07: Maximum tracks in image (only in version 1.02 or greater) + 1540/41/70: 35 + 1571: 35 + 1581: 80 (Logical single-sided disk) + 08: Number of disk sides in image. This value must be $00 for + all 1541 and 1581 formats. + $00=No second side + $01=Second side + 09: Error data flag. I assume that if this location has any + non-zero value in it, this will indicate the existance of + the error bytes. For a description of the error bytes, see + the D64 topic dealing with extended formats. + 0A-1F: Unused, set to $00 + 20-3E: Disk image description (in ASCII or ISO Latin/1) + 3F: Always set to $00 + 40-: Standard C64 file begins here + + The first four bytes used for the device type at position $06 ($00 to +$03) are functionally the same, and are compatible with older version of +X64 files. Some old X64 files might have $00 for the device type (instead +of $01), but it makes no real difference. + + As most instances of X64 files will be strictly 1541 images, bytes 08-3F +are set to zero, and some versions of the X64 emulator don't use bytes +08-3F. + + There is no advantage for PC users to use this format since virtually no +PC emulator that I know of uses them, and for the most part, it provides +the same functionality as a D64 file. + + In order to read a generic X64 file, first you must determine that it is +an X64, and then determine the type of file it contains. In effect, you +have to double-decode the file, which makes support a little more +difficult. Also, you would have to be able to work with *all* of the types +of drives that X64 supports, a daunting task. + + Its only advantage is that is encompasses all of the standard disk +formats on the C64. If other disk types were common (like 1581 or CMD +disks), then this format might be more popular. + diff --git a/Commodore/ZIP.TXT b/Commodore/ZIP.TXT new file mode 100644 index 0000000..05674a4 --- /dev/null +++ b/Commodore/ZIP.TXT @@ -0,0 +1,97 @@ + +*** ZIP (PKZip compressed files) +*** Document revision: 1.3 +*** Last updated: March 11, 2004 +*** Compiler/Editor: Peter Schepers +*** Contributors/sources: net documents + + The files seen on the C64 are generally PKZIP 1.1-compatible archives, +using the older IMPLODE algorithm, which are decompressible on the C64/C128 +using various utilities. All versions of PKUNZIP (and compatible programs) +will also handle the older archives. The explanation I provide below covers +up to the newest version PKZIP at the time of writing this document, 2.04g. + + They always start with the 'PK' string at the beginning of the file, and +the first filename follows very closely. The example archive below holds +4-pack ZipCode files, as the filename shows: + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +00000: 50 4B 03 04 14 00 00 00 08 00 00 00 00 00 19 A1 PK.............. +00010: EB 0D C2 45 00 00 50 69 00 00 07 00 00 00 31 21 ..............1! +00020: 4D 53 48 4F 57 E4 BC 7B 5C 53 47 DA 38 3E 67 CE MSHOW........... + + Bytes: $00-03: PKZIP local file header signature ($50 $4B $03 $04, first + two bytes are ASCII "PK"). This signature is used at the + beginning of *each* compressed file. + 04-05: Program version that created archive: + decimal value/10 = major version # (in this case 2) + decimal value%10 = minor version # (in this case .0) + 06-07: General purpose bit flags: + bit 0: set - file is encrypted + clear - file is not encrytped + bit 1: if compression method 6 used (imploding) + set - 8K sliding dictionary + clear - 4K sliding dictionary + bit 2: if compression method 6 used (imploding) + set - 3 Shannon-Fano trees were used to encode + the sliding dictionary output + clear - 2 Shannon-Fano trees were used + + For method 8 compression (deflate): + bit 2 bit 1 + 0 0 Normal (-en) compression + 0 1 Maximum (-ex) compression + 1 0 Fast (-ef) compression + 1 1 Super Fast (-es) compression + + Note: Bits 1 and 2 are undefined if the + compression method is any other than 6 or 8. + bit 3: if compression method 8 (deflate) + set - the fields crc-32, compressed size and + uncompressed size are set to zero in the + local header. The correct values are put + in the data descriptor immediately + following the compressed data. + + The upper three bits are reserved and used internally by + the software when processing the zipfile. The remaining + bits are unused. + 08-09: Compression method: + 0 - Stored (no compression) + 1 - Shrunk + 2 - Reduced with compression factor 1 + 3 - Reduced with compression factor 2 + 4 - Reduced with compression factor 3 + 5 - Reduced with compression factor 4 + 6 - Imploded + 7 - Reserved for Tokenizing compression algorithm + 8 - Deflated + 0A-0B: Last modified file time in MSDOS format + Bits 00-04: Seconds/2 (0-58, only even numbers) + 05-10: Minutes (0-59) + 11-15: Hours (0-23, no AM or PM) + 0C-0D: Last modified file date in MSDOS format + Bits 00-04: Day (1-31) + 05-09: Month (1-12) + 10-15: Year minus 1980 + 0E-11: CRC-32 of file (low-high format) + 12-15: Compressed size of file (low-high format) + 16-19: Uncompressed size of file (low-high format) + 1A-1B: Filename length (FL) + 1C-1D: Extra field length, description (EFL) + 1E-(1E+FL-1): Filename + (1E+FL)-(1E+FL+EFL-1): Extra field + + You will notice that in the above byte layout, there is no mention of C64 +filetype. That particular field seems to be stored in the central directory +at the end of the ZIP archive. + + There are several other signatures used within the ZIP format. The byte +sequence 50 4B 01 02 is used to signify the beginning of the central +directory while the byte sequence 50 4B 05 06 is used to show the end of +the central directory. + + The above explanation is only included for completeness. Without source +code, it is almost impossible to work with ZIP archives. + diff --git a/Commodore/ZIP_DISK.TXT b/Commodore/ZIP_DISK.TXT new file mode 100644 index 0000000..35975d3 --- /dev/null +++ b/Commodore/ZIP_DISK.TXT @@ -0,0 +1,185 @@ + +*** DiskPacked ZipCode (4 or 5 file version, 1!xxxxxx, 2!xxxxxx, etc) +*** Document revision: 1.2 +*** Last updated: March 11, 2004 +*** Compiler/Editor: Peter Schepers +*** Contributors/sources: Paul David Doherty + + This format works directly on D64 images only. It is a compressed form of +a 1541 disk (or a D64 file) and is typically comprised of 4 files for a 35 +track disk. The 5-file version is for 40-track images, and is a Joe +Forster/STA extension of the standard. This form of the ZipCode format +can't be used to store disks with errors on them, as there are no +provisions for error bytes. It is strictly a compressed sector copy of a +disk. + + The following chart shows the filenames, range of tracks and the total +sectors that each one contains: + + FileName Track Range Block Count + -------- ----------- ----------- + 1!xxxxxx 1 - 8 168 sectors + 2!xxxxxx 9 - 16 168 sectors + 3!xxxxxx 17 - 25 172 sectors + 4!xxxxxx 26 - 35 175 sectors + 5!xxxxxx 36 - 40 85 sectors (valid only for 40 track disk images) + + This format uses sector interleaving to read the disk. It reads each +sector using an interleave of -10 for even #'s sectors (0,2,4...) and +11 +for odd numbered sectors (1,3,5...). The actual value for both interleaves +varies as we progress further into the disk. At track 18, it goes to -9 for +evens and +10 for odds, and at track 25 it changes to -8 for evens and +9 +for odds. This is important to better understand the layout, as it means +the sectors are *not* stored in order (0,1,2...), but the changing +interleave makes reading/writing the sectors much faster. This also means +that in order to reconstruct each track, a buffer of memory the size of the +largest track (track 1, 21 sectors*256 bytes = 5.25 kbytes) must be set +aside, and the sector information copied into the appropriate area until +the whole track is assembled. + +Here is a partial HEX dump of the first file and description of the layout. + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + ----------------------------------------------- +0000: FE 03 36 34 41 00 00 41 0B 00 41 01 00 41 0C 00 +0010: 41 02 00 41 0D 00 41 03 00 41 0E 00 41 04 00 41 +0020: 0F 00 41 05 00 41 10 00 41 06 00 81 11 33 02 00 +0030: 2F 80 25 9D FA 66 AF 9B 6A 14 A0 E4 10 CA 18 90 +0040: 7B 67 51 47 92 2B 4C 52 83 78 01 A9 58 D0 31 70 +0050: 34 30 B7 85 2C D4 9F 1C 1F A9 EA EA EA 15 3E 02 +0060: D0 00 41 07 00 41 12 00 41 08 00 41 13 00 41 09 + + Byte: $00-01: Load address, low/high byte. If the load address is $03FE + then we have the DISK ID following immediately after. If + it's $0400, then no DISK ID follows. + 02-03: Disk ID, only if the load address is $0400. + + From here on, the format can vary, depending on the contents of each +sector. The next two bytes contain the track/sector, but the track value +now includes the compression method, contained on the top two bits... + +Bit: 76543210 + xxyyyyyy + ^^| | + | ------ + | ^ + | | + | | + | These are the track bits. + | + These are the compression flags + + Since the track range is from 1-35, only the bottom 5 bit are used. This +leaves the top two empty, and usable. Here is their usage: + + 00 - No compression, the sector is stored in full. The next 256 bytes + contain the full sector information. + 01 - Sector is filled with *one* character. The next character is the + fill byte. Repeat it 256 times, and fill the sector. + 10 - Sector is compressed using RLE compression (see below for details) + 11 - Unused + + Lets look at each method of storing a sector with different compression +methods, using the above example... + + 00: This is the simplest method, as it entails no compression. All we + have is a track and sector value, and 256 bytes of data follow it. + + 01: At byte 04 we have 41 00 00. Breaking down $41 to binary we have + "01000001". The top two bits indicate we have type 01 compression + (fill sector), and the bottom 6 indicate we have track 1. The next + byte is the sector ($00), and the next byte is also a $00, indicating + this sector is completely filled with $00. + + 0000: .. .. .. .. 41 00 00 41 0B 00 41 01 00 41 0C 00 + 0010: 41 02 00 41 0D 00 41 03 00 41 0E 00 41 04 00 41 + + 10: The RLE encoding takes some explanation. RLE stands for "Run Length + Encoding", and is simply a means of encoding a series of the same + numbers into a much smaller string (i.e. encoding the 1's in the + string "0456111111111645" into something much shorter). + + Looking at the example below, when we encounter a "10" type, we have + track ($81, meaning track 1), sector ($11), the length of the encoded + string $33 (51 decimal) and a REP code, a unique byte used as a flag + to show when we encounter an encoded repeated string. The REP code is + a single byte whose value doesn't occur in the decoded sector. It is + typically the first unused value starting from 0, but in practice it + can be anything, it simply must be an unused value. + + 0020: .. .. .. .. .. .. .. .. .. .. .. 81 11 33 02 00 + 0030: 2F 80 25 9D FA 66 AF 9B 6A 14 A0 E4 10 CA 18 90 + 0040: 7B 67 51 47 92 2B 4C 52 83 78 01 A9 58 D0 31 70 + 0050: 34 30 B7 85 2C D4 9F 1C 1F A9 EA EA EA 15 3E 02 + 0060: D0 00 .. .. .. .. .. .. .. .. .. .. .. .. .. .. + + We know with this example that the encoded data is 51 bytes long + ($33), and with a REP code of $02, whenever we encounter a $02, we + have an encoded sequence. If we do not encounter a $02, we have + normal bytes. In the above sequence, we do not encounter a $02 until + $005F, so all the rest are normal bytes, which would go into the + sector starting at position $00. + + Once we hit a $02, the next two bytes are encoded this way... repeat + count ($D0, decimal 208) and byte to repeat ($00). So we fill the + next 208 ($D0) bytes with $00's. + + If you add up what we had before the $02, it was 48 bytes long, add + this to the 208 bytes and we have a full sector of 256 bytes. A + 256-byte sector stored in 55 (51 + 4 byte header) bytes represents a + good savings. + + Notice the byte sequence in the above example 'EA EA EA'. Why was + this not encoded? Simple. The encoding sequence (REP, LENGTH, CHAR) + takes three bytes. It would not make any sense to encode something + which is no shorter than the original string. ZipCode will only + encode a repeated string of 4 bytes or longer. + + Now, lets break down the above sample into its encoded parts, to see + how its made... + + 0000: FE 03 - Load Address + 0002: 36 34 - Disk ID + 0004: 41 00 00 - T/S 1,00, fill $00 + 0007: 41 0B 00 - T/S 1,11, fill $00 + 000A: 41 01 00 - T/S 1,01, fill $00 + 000D: 41 0C 00 - T/S 1,12, fill $00 + 0010: 41 02 00 - T/S 1,02, fill $00 + 0013: 41 0D 00 - T/S 1,13, fill $00 + 0016: 41 03 00 - T/S 1,03, fill $00 + 0019: 41 0E 00 - T/S 1,14, fill $00 + 001C: 41 04 00 - T/S 1,04, fill $00 + 001F: 41 0F 00 - T/S 1,15, fill $00 + 0022: 41 05 00 - T/S 1,05, fill $00 + 0025: 41 10 00 - T/S 1,16, fill $00 + 0028: 41 06 00 - T/S 1,06, fill $00 + 002B: 81 11 33 02 - T/S 1,17, RLE, length 51 bytes, REP byte $02 + 00 2F 80 25 - Normal data + 9D FA 66 AF + 9B 6A 14 A0 + E4 10 CA 18 + 90 7B 67 51 + 47 92 2B 4C + 52 83 78 01 + A9 58 D0 31 + 70 34 30 B7 + 85 2C D4 9F + 1C 1F A9 EA + EA EA 15 3E + 005F: 02 D0 00 - REP byte found, repeat 208, fill with $00 + 0062: 41 07 00 - T/S 1,07, fill $00 + 0065: 41 12 00 - T/S 1,18, fill $00 + + This listing is basically what you would see if you ran CheckZipCode from +inside 64COPY. It will dump out the ZipCode files into their constituent +parts, so you can see how the file is made, and if any errors exist. + + The 4 and 5 file ZipCode format can't be used to store disks with errors +on them, as there are no provisions for error bytes. It is strictly a +compressed sector copy of a disk. + + There is no benefit for using ZipCode as it is only used for making disks +easier to upload/download (for a BBS) or store. It is not a format that any +of the emulators use directly. You can find utilites for the PC to undo and +create the images, if you need to. + diff --git a/Commodore/ZIP_FILE.TXT b/Commodore/ZIP_FILE.TXT new file mode 100644 index 0000000..c57a0a3 --- /dev/null +++ b/Commodore/ZIP_FILE.TXT @@ -0,0 +1,165 @@ + +*** FilePacked ZipCode (A!xxxxxx, B!xxxxxx, etc) +*** Document revision: 1.4 +*** Last updated: March 11, 2004 +*** Compiler/Editor: Peter Schepers +*** Contributors/sources: Joe Forster/STA + + This is another rarely seen format, and is very similar to the Diskpacked +(4-pack) Zipcode in structure. It is comprised of a series of files denoted +by A!xxxxxx and B!xxxxxx, with letters instead of numbers as the first +characters of the filename. It also contains one other file called X!xxxxxx +which contains a directory of the files stored in the overall archive. Here +is the layout of the files: + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +0000: FF 03 A6 11 0A 01 08 0E 08 CE 07 9E 20 28 32 30 (20 +0010: 36 34 29 00 00 00 78 A9 34 85 01 A2 05 BD 42 08 64)x4B +0020: 9D 2D 00 CA 10 F7 9A A0 00 C6 32 CE 2C 08 B1 31 -2,1 +0030: 99 00 00 C8 D0 F8 A5 32 C9 08 D0 ED B9 48 08 99 2H +0040: 00 01 C8 D0 F7 4C 00 01 01 08 46 4D F3 BB B1 2F LFM/ + + Bytes: 00-01: Load Address, low/high format, usually $FF $03, or $03FF) + 02: Number of sectors in the file (maximum 166, or $A6) + 03-??: Zipcoded sector data starts here + + If 166 sectors was not enough to store the file then more x!xxxxxx files +are needed, and the layout is the same. This makes the resulting file size +of each section approximately the same as the 4-pack zipcode would be, as +166 sectors is 1/4 of a normal D64 (664 sector) disk. + + The sector information is zipcoded in the same manner as Diskpacked +4-pack Zipcodes, but the sector size (excluding the t/s link) is 254 bytes, +not 256 as in 4-pack zipcode. The compression is still stored in the top +two bits of the track link, and the remainder of the sector (254 bytes) is +encoded. Each block of the file is stored in full, even the last one, +though it is rarely completely used. + + Bits + ---- + 00 - No compression, the sector is stored in full. The next 254 bytes + contains the remainder of the sector information. + 01 - Sector is filled with *one* character. The next character is the + fill byte. Repeat it 254 times, and fill the sector. + 10 - Sector is compressed using RLE compression (see 4-pack ZipCode for + details) + 11 - Unused + + If the track is decoded as $00, then we are on the last block of the +file, and the sector represents the number of bytes used. + + + The special file, X!xxxxxx, as mentioned above, contains a listing of all +the files in the archive. It has most of the information that the D64/1541 +entry would. Here is the layout: + + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +0000: 01 08 0B 08 00 00 9E 32 30 36 31 00 00 00 A0 00 2061 +0010: 8C 20 D0 8C 21 D0 B9 C7 08 F0 06 20 D2 FF C8 D0 Ќ!й +0020: F5 85 FF 85 FB A0 0A 84 FC 85 FD 85 FE A0 11 B1 +0030: FB 48 AA C8 B1 FB 48 A8 20 4B 09 20 41 09 8A 20 HȱHKA +0040: 41 09 98 20 41 09 68 AA 68 18 65 FD 85 FD 8A 65 AAhhee +0050: FE 85 FE 20 39 09 20 3C 09 A0 00 B1 FB C9 A0 F0 9<ɠ +0060: 08 20 41 09 C8 C0 10 D0 F2 20 3C 09 C0 13 F0 06 A< +0070: 20 39 09 C8 D0 F6 A0 10 B1 FB 29 7F 20 41 09 20 9)A +0080: 3F 09 A5 FB 18 69 15 85 FB 90 02 E6 FC E6 FF A5 ?i +0090: FF CD FF 09 D0 97 AA A0 00 20 4B 09 8E 08 09 8C ЗK +00A0: 09 09 A6 FD A4 FE 20 4B 09 8D 1A 09 8E 1B 09 8C K +00B0: 1C 09 AD FE 09 09 30 8D 2D 09 A0 00 B9 F7 08 F0 0- +00C0: 06 20 41 09 C8 D0 F5 60 93 9B 11 11 11 11 11 11 A` +00D0: 11 11 11 11 11 11 11 11 11 11 48 4F 4C 44 20 53 HOLDS +00E0: 54 4F 50 20 54 4F 20 50 41 55 53 45 20 4C 49 53 TOPTOPAUSELIS +00F0: 54 49 4E 47 3A 0D 0D 00 0D 0D 54 4F 54 41 4C 20 TING:TOTAL +0100: 46 49 4C 45 53 20 20 3D 20 30 30 0D 54 4F 54 41 FILES=00TOTA +0110: 4C 20 42 4C 4F 43 4B 53 20 3D 20 30 30 30 0D 50 LBLOCKS=000P +0120: 41 43 4B 45 44 20 46 49 4C 45 53 20 3D 20 30 0D ACKEDFILES=0 +0130: 05 5B 5A 43 20 49 49 5D 0D 00 A9 20 2C A9 22 2C [ZCII],", +0140: A9 0D 20 D2 FF A5 91 C9 7F F0 FA 60 8E 92 09 8C ` +0150: 93 09 A0 02 A9 30 99 96 09 88 10 FA A2 02 AD 92 0 +0160: 09 38 FD 8F 09 8D 94 09 AD 93 09 E9 00 8D 95 09 8 +0170: 90 11 AD 94 09 8D 92 09 AD 95 09 8D 93 09 FE 96 +0180: 09 D0 DB CA 10 D8 AD 98 09 AE 97 09 AC 96 09 60 ح` +0190: 01 0A 64 00 00 00 00 31 32 33 00 00 00 00 00 00 d123 +01A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +01B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +01C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +01D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +01E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +01F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 +0200: 0E 4D 55 53 49 43 20 53 45 4C 45 43 54 4F 52 A0 MUSICSELECTOR +0210: A0 D0 B6 00 11 00 31 30 30 31 20 4C 45 54 54 45 ж1001LETTE +0220: 52 20 2D 56 2D A0 D0 72 00 13 00 4E 45 57 20 4D R-V-rNEWM +0230: 41 49 4C 2F 44 44 A0 A0 A0 A0 A0 D0 1E 00 19 00 AIL/DD +0240: 4A 41 43 4B 20 54 48 45 20 4E 49 50 50 45 52 A0 JACKTHENIPPER +0250: D0 C0 00 1A 06 54 55 52 4E 45 52 20 49 49 A0 A0 TURNERII +0260: A0 A0 A0 A0 A0 D0 2B 00 07 00 53 43 52 45 45 4E +SCREEN +0270: 20 20 30 A0 A0 A0 A0 A0 A0 A0 D3 07 00 05 00 53 0S +0280: 43 52 45 45 4E 20 20 31 A0 A0 A0 A0 A0 A0 A0 D3 CREEN1 +0290: 0C 00 05 01 53 43 52 45 45 4E 20 20 32 A0 A0 A0 SCREEN2 +02A0: A0 A0 A0 A0 D3 0B 00 04 00 53 43 52 45 45 4E 20 SCREEN +02B0: 20 33 A0 A0 A0 A0 A0 A0 A0 D3 02 00 04 01 53 43 3SC +02C0: 52 45 45 4E 20 20 34 A0 A0 A0 A0 A0 A0 A0 D3 03 REEN4 +02D0: 00 04 03 53 43 52 45 45 4E 20 20 35 A0 A0 A0 A0 SCREEN5 +02E0: A0 A0 A0 D3 07 00 04 07 53 43 52 45 45 4E 20 20 SCREEN +02F0: 36 A0 A0 A0 A0 A0 A0 A0 D3 08 00 03 00 53 43 52 6SCR +0300: 45 45 4E 20 20 37 A0 A0 A0 A0 A0 A0 A0 D3 07 00 EEN7 +0310: 03 01 53 43 52 45 45 4E 20 20 38 A0 A0 A0 A0 A0 SCREEN8 +0320: A0 A0 D3 0B 00 03 09 .. .. .. .. .. .. .. .. .. ......... + + Bytes: 0000-01FE: BASIC program which lists the contents of the archive + (a SYS 2061 call to an ML program) + 01FF: Number of archive (x!xxxxxx) files. Since the upper + value is 4, we have A!xxxxxx, B!xxxxxx, C!xxxxxx, + D!xxxxxx and X!xxxxxx. + 0200: Number of C64 files contained in the directory (14) + 0201: Start of the directory + + Each file has a directory entry in the X!xxxxxx file, starting at $0201, +each 21 bytes long, and laid out as follows: + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +0200: .. 4D 55 53 49 43 20 53 45 4C 45 43 54 4F 52 A0 .MUSICSELECTOR +0210: A0 D0 B6 00 11 00 31 30 30 31 20 4C 45 54 54 45 ж1001LETTE +0220: 52 20 2D 56 2D A0 D0 72 00 13 00 4E 45 57 20 4D R-V-rNEWM +0230: 41 49 4C 2F 44 44 A0 A0 A0 A0 A0 D0 1E 00 19 00 AIL/DD +0240: 4A 41 43 4B 20 54 48 45 20 4E 49 50 50 45 52 A0 JACKTHENIPPER +0250: D0 C0 00 1A 06 54 55 52 4E 45 52 20 49 49 A0 A0 TURNERII +0260: A0 A0 A0 A0 A0 D0 2B 00 07 00 53 43 52 45 45 4E +SCREEN +0270: 20 20 30 A0 A0 A0 A0 A0 A0 A0 D3 07 00 05 00 53 0S +0280: 43 52 45 45 4E 20 20 31 A0 A0 A0 A0 A0 A0 A0 D3 CREEN1 +0290: 0C 00 05 01 53 43 52 45 45 4E 20 20 32 A0 A0 A0 SCREEN2 +02A0: A0 A0 A0 A0 D3 0B 00 04 00 53 43 52 45 45 4E 20 SCREEN +02B0: 20 33 A0 A0 A0 A0 A0 A0 A0 D3 02 00 04 01 53 43 3SC +02C0: 52 45 45 4E 20 20 34 A0 A0 A0 A0 A0 A0 A0 D3 03 REEN4 +02D0: 00 04 03 53 43 52 45 45 4E 20 20 35 A0 A0 A0 A0 SCREEN5 +02E0: A0 A0 A0 D3 07 00 04 07 53 43 52 45 45 4E 20 20 SCREEN +02F0: 36 A0 A0 A0 A0 A0 A0 A0 D3 08 00 03 00 53 43 52 6SCR +0300: 45 45 4E 20 20 37 A0 A0 A0 A0 A0 A0 A0 D3 07 00 EEN7 +0310: 03 01 53 43 52 45 45 4E 20 20 38 A0 A0 A0 A0 A0 SCREEN8 +0320: A0 A0 D3 0B 00 03 09 .. .. .. .. .. .. .. .. .. ......... + + Bytes:$00-0F: 16 character filename (PETASCII, padded with $A0) + 10: Filetype: (the character "P" "S" or "U" OR'd with 0x80). + This means that the write-protect and splat bits are *not* + transferred, neither are custom file types, and REL is not + allowed either. + 11-12: Length of the file in sectors (0 for no size) + 13-14: Original starting track/sector of the file + + In order to extract *one* specific file, you would have to read the +entire archive until you came across the directory entry that you wanted, +then process that specific file. This format does not contain any offset +references in the central directory for each file, just the original file +size, which means that we don't know anything about where a file might be +in the archive, since the original sector size doesn't apply as the stored +file in compressed. + + Since this format seems to be uncommon, I can't see any benefit of using +it over LNX as a native C64 file. The only plus is it uses simple +compression, whereas LNX does not. However, LNX only uses one file for the +entire file set stored. + diff --git a/Commodore/ZIP_SIX.TXT b/Commodore/ZIP_SIX.TXT new file mode 100644 index 0000000..7b289bb --- /dev/null +++ b/Commodore/ZIP_SIX.TXT @@ -0,0 +1,372 @@ + +*** SixPack Zipcode (6-file version, 1!!xxxxx, 2!!xxxxx, etc) +*** Document revision: 1.4 +*** Last updated: March 11, 2004 +*** Compiler/Editor: Peter Schepers +*** Contributors/sources: Paul David Doherty, + Wolfgang Moser + + This is another rare form of ZipCode, spanning six files, and hence the +use of the name SixPack. Notice how the filename uses two "!!" characters +in it, versus one for the other 4-file or filepacked zipcode formats. + + Name Track Range + -------- ----------- + 1!!xxxxx 1 - 6 + 2!!xxxxx 7 - 12 + 3!!xxxxx 13 - 18 + 4!!xxxxx 19 - 25 + 5!!xxxxx 26 - 32 + 6!!xxxxx 33 - 35 (or 40 for 40-track images) + + The format for these is *nothing* like the 4-pack, as it contains no +compression or track/sector references. Rather, all the sector data is +stored in GCR code (Group Code Recording). GCR is the method used to store +information, at the lowest level, on a 1541 diskette. It converts 4-bit +nybbles (2 nybbles per byte, upper 4 bits and lower 4 bits) into an encoded +5-bit GCR code. The conversion chart for 4-bit to 5-bit conversion is as +follows: + + Hex Binary GCR (dec) Hex Binary GCR (dec) + --- ------ ---------- --- ------ ---------- + 0 - 0000 - 01010 (10) 8 - 1000 - 01001 (9) + 1 - 0001 - 01011 (11) 9 - 1001 - 11001 (25) + 2 - 0010 - 10010 (18) A - 1010 - 11010 (26) + 3 - 0011 - 10011 (19) B - 1011 - 11011 (27) + 4 - 0100 - 01110 (14) C - 1100 - 01101 (13) + 5 - 0101 - 01111 (15) D - 1101 - 11101 (29) + 6 - 0110 - 10110 (22) E - 1110 - 11110 (30) + 7 - 0111 - 10111 (23) F - 1111 - 10101 (21) + +If you look over the GCR table, there are two details that should be noted. + + 1. You *cannot* combine any group of GCR nybbles into a sequence of bits + that contain more than 8 consecutive 1-bits. At least ten (or more) + consecutive 1-bits is used for a SYNC mark, used to tell the disk + controller that sector data is coming up. (In actual fact, the 1541 + records an overkill of 40 sequential 1-bits to the disk as a SYNC mark + to ensure the controller can find the mark!). + + Note that some documents refer to a minimum of 12 bits needed for a + SYNC mark. This is likely why Commodore chose to use 40 bits for the + standard mark, as the overkill makes it almost impossible to miss. + + 2. There will never be any more than two consecutive 0-bits. This is done + to insure the accuracy of clocking data back to the 1541 controller. + Too many zero bits, and the clock will go out of sync and start + clocking in phantom '1' bits. + + Using the above table, let's convert some numbers. For reasons I will +explain later, we must work in groups of four bytes in order to convert +normal HEX to GCR. + + Using these HEX numbers... + + 0D F5 E4 37 + + now, split these values into nybbles and convert to binary... + + 0 D F 5 E 4 3 7 + ---- ---- ---- ---- ---- ---- ---- ---- + 0000 1101 1111 0101 1110 0100 0011 0111 + + convert nybbles to GCR using the conversion table... + + 0000 1101 1111 0101 1110 0100 0011 0111 + ----- ----- ----- ----- ----- ----- ----- ----- + 01010 11101 10101 01111 11110 01110 10011 10111 + + now, recombine the bit into groups of 8... + + 01010 11101 10101 01111 11110 01110 10011 10111 + | || || || || | + | byte 1|| byte 2 || byte 3 || byte 4 || byte 5| + | || || || || | + ------- ---------- --------- ---------- ------- + 01010111 01101010 11111111 00111010 01110111 + + and convert back to HEX... + + 01010111 01101010 11111111 00111010 01110111 + -------- -------- -------- -------- -------- + 57 6A FF 3A 77 + + So, now we have converted a group of 4 bytes into 5 GCR bytes. The reason +we must encode in groups of 4 is that it is the *minimum* number of bytes +which, when converted to GCR bits, is divisible by 8 bits without any +remainder... 1 byte would be 10 bits, 2 bytes would be 20, 3 bytes would be +30, but 4 bytes is 40 bits, divisible by 8 since it leaves us with 5 groups +of 8 bits. + + Now that we have a foundation of GCR encoding, we can begin to analyse +the layout of the 6-pack zipcode. Below is a sample of the beginning of the +first file (1!!xxxxx): + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII + ----------------------------------------------- ---------------- +0000: FF 03 24 52 55 25 29 4B 9A E7 25 55 55 52 55 35 $RU%)K%UURU5 +0010: 2D 4B 9A E7 25 55 55 52 54 A5 49 4B 9A E7 25 55 -K%UURTIK%U +0020: 55 52 54 B5 4D 4B 9A E7 25 55 55 52 55 65 39 4B URTMK%UURUe9K +0030: 9A E7 25 55 55 52 55 75 3D 4B 9A E7 25 55 55 52 %UURUu=K%UUR +0040: 54 E5 59 4B 9A E7 25 55 55 52 54 F5 5D 4B 9A E7 TYK%UURT]K +0050: 25 55 55 52 55 A5 25 4B 9A E7 25 55 55 52 55 B5 %UURU%K%UURU +0060: 65 4B 9A E7 25 55 55 52 54 95 69 4B 9A E7 25 55 eK%UURTiK%U +0070: 55 52 55 95 6D 4B 9A E7 25 55 55 52 55 E5 35 4B URUmK%UURU5K +0080: 9A E7 25 55 55 52 55 55 75 4B 9A E7 25 55 55 52 %UURUUuK%UUR +0090: 54 D5 79 4B 9A E7 25 55 55 52 55 D5 55 4B 9A E7 TyK%UURUUK +00A0: 25 55 55 52 57 25 A9 4B 9A E7 25 55 55 52 57 35 %UURW%K%UURW5 +00B0: AD 4B 9A E7 25 55 55 52 56 A5 C9 4B 9A E7 25 55 K%UURVK%U +00C0: 55 52 56 B5 CD 4B 9A E7 25 55 55 52 57 65 B9 4B URVK%UURWeK +00D0: 9A E7 25 55 55 29 0F 05 C0 99 00 02 C8 D0 D4 A9 %UU)ԩ +00E0: 02 8D 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00F0: 00 00 00 00 00 00 00 00 00 41 4D 45 3A 20 31 32 AME:12 +0100: 33 34 15 D4 B5 2D 4B 52 D4 B5 2D 4B 52 D4 B5 2D 34Ե-KRԵ-KRԵ- +0110: 4B 52 D4 B5 2D 4B 52 D4 B5 2D 4B 52 D4 B5 2D 4B KRԵ-KRԵ-KRԵ-K +0120: 52 D4 B5 2D 4B 52 D4 B5 2D 4B 52 D4 B5 2D 4B 52 RԵ-KRԵ-KRԵ-KR +0130: D4 B5 2D 4B 52 D4 B5 2D 4B 52 D4 B5 2D 4B 52 D4 Ե-KRԵ-KRԵ-KR +0140: B5 2D 4B 52 D4 B5 29 4D 55 55 D4 A5 2D 4B 52 D4 -KRԵ)MUUԥ-KR +0150: B5 2D 4B 52 D4 B5 2D 4B 52 D4 B5 2D 4B 52 D4 B5 -KRԵ-KRԵ-KRԵ + + Each file starts with a 3-byte signature, $FF, $03, and then either a $24 +for a 35 track image, or a $29 for a 40 track image. + +0000: FF 03 24 .. .. .. .. .. .. .. .. .. .. .. .. .. + + Track information follows, and is comprised of a 256 byte track +descriptor block (mostly GCR encoded), followed by sector information at +326 bytes/sector. The track descriptor contains the header information of +each sector in that track, as well as the number of sectors encoded on that +track. + + The descriptor block is broken up into groups of 10 bytes. Each of these +groups contains the header information of a sector stored in the track. +Sectors are stored in the header in linear order, but not necessarily +starting at sector 0. If the numbers doesn't start at sector 0, then it +will go something like this: 4, 5, 6, 7, 8...16, 17, 18, 19, 20, 0, 1, 2, +3. Since this track started on sector 4, notice the wrap-around from sector +20 back to 0 and up to 3. + + +Here is the layout from the above sample block... + + Pos Byte CGR Contents Normal Contents (decoded) + --- ---- ----------------------------- -------------------------------- + Sig Chk Sec Trk Id2 Id1 OffBytes + 0 00: 52 55 25 29 4B 9A E7 25 55 55 08 02 00 01 31 32 0F 0F + 1 0A: 52 55 35 2D 4B 9A E7 25 55 55 08 03 01 01 31 32 0F 0F + 2 14: 52 54 A5 49 4B 9A E7 25 55 55 08 00 02 01 31 32 0F 0F + 3 1E: 52 54 B5 4D 4B 9A E7 25 55 55 08 01 03 01 31 32 0F 0F + 4 28: 52 55 65 39 4B 9A E7 25 55 55 08 06 04 01 31 32 0F 0F + 5 32: 52 55 75 3D 4B 9A E7 25 55 55 08 07 05 01 31 32 0F 0F + 6 3C: 52 54 E5 59 4B 9A E7 25 55 55 08 04 06 01 31 32 0F 0F + 7 46: 52 54 F5 5D 4B 9A E7 25 55 55 08 05 07 01 31 32 0F 0F + 8 50: 52 55 A5 25 4B 9A E7 25 55 55 08 0A 08 01 31 32 0F 0F + 9 5A: 52 55 B5 65 4B 9A E7 25 55 55 08 0B 09 01 31 32 0F 0F + 10 64: 52 54 95 69 4B 9A E7 25 55 55 08 08 0A 01 31 32 0F 0F + 11 6E: 52 55 95 6D 4B 9A E7 25 55 55 08 09 0B 01 31 32 0F 0F + 12 78: 52 55 E5 35 4B 9A E7 25 55 55 08 0E 0C 01 31 32 0F 0F + 13 82: 52 55 55 75 4B 9A E7 25 55 55 08 0F 0D 01 31 32 0F 0F + 14 8C: 52 54 D5 79 4B 9A E7 25 55 55 08 0C 0E 01 31 32 0F 0F + 15 96: 52 55 D5 55 4B 9A E7 25 55 55 08 0D 0F 01 31 32 0F 0F + 16 A0: 52 57 25 A9 4B 9A E7 25 55 55 08 12 10 01 31 32 0F 0F + 17 AA: 52 57 35 AD 4B 9A E7 25 55 55 08 13 11 01 31 32 0F 0F + 18 B4: 52 56 A5 C9 4B 9A E7 25 55 55 08 10 12 01 31 32 0F 0F + 19 BE: 52 56 B5 CD 4B 9A E7 25 55 55 08 11 13 01 31 32 0F 0F + 20 C8: 52 57 65 B9 4B 9A E7 25 55 55 08 16 14 01 31 32 0F 0F + + D2: 29 0F 05 C0 99 00 02 C8 D0 D4 garbage + DC: A9 02 8D 00 00 00 00 00 00 00 garbage + E6: 00 00 00 00 00 00 00 00 00 00 garbage + F0: 00 00 00 00 00 00 garbage + F6: 41 4D 45 3A 20 31 32 33 34 garbage "AME: 1234" + FF: 15 Number of valid sectors contained + with this track ($15=21 dec) + + Each sector header block is laid out in the following order (after +decoding the 10 GCR bytes to 8 normal bytes): + + Byte: $00 - Header block descriptor value $08 (SIG value) + 01 - Header checksum (EOR of bytes 02-05) (CHK value) + 02 - Sector number (SEC) + 03 - Track number (TRK) + 04 - Second byte of disk ID (ID2) + 05 - First byte of disk ID (ID1) + 06-07 - "OFF" bytes ($0F's). These "fill" up the header to make it + a multiple of 4 bytes, necessary in order to convert it to + GCR (as six bytes would be too short to convert) + + The entries for Sectors 17-20 will only be valid if the track being +operated on has that many sectors in it. If the value at $FF is $00, then +we have an empty track (bad track from the original disk, and the whole +track should be set to error code 21). When this happens, all the sector +header info in the track descriptor block will be invalid. If we only use +up to sector 16 (for tracks 31 and up), then all the info following the +entry for sector 16 will be invalid. Invalid data can be anything, just +ignore it. + + All of the sixpack files I have either created or received contain the +string "AME: 1234" at the end of the track descriptor block. It is likely a +"garbage" string, and can be useful in locating the descriptor blocks when +manually looking over the sixpack files with a HEX editor, but it shouldn't +be used in any other capacity. You also can't easily tell what track you +are on, but given the track ranges covered by each file, and the sector +count at the end of the descriptor block, it is possible to figure it out. + + Each sector is 326 bytes long (GCR encoded), and each track is 256 bytes ++ (# of sectors/track * 326) bytes. Track 1 would be 256 + (21 * 326) = +7102 bytes. The sector information stored in a specific interleave pattern, +depending on the track we are on (unlike the entries in the descriptor +block, which are stored in linear order). Note that if this was a 40 track +image, the interleave pattern for the last set of tracks would apply up to +track 40 instead of 35. + + Note that the numbers referred to in the "Sector Data Interleave" portion +of the table do *not* refer to actual sector numbers, but correspond to the +group position in the header descriptor block. Thus header group 0 is at +interleave position 0, header group 1 is stored at interleave position 8, +etc. The header and sector data must be recombined this way before decoding +the header to see what the real sector value is. + + Track Sector Data interleave reading pattern + ----- ---------------------------------------------------- + 1-17 - 0,8,16,3,11,19,6,14,1,9,17,4,12,20,7,15,2,10,18,5,13 + 18-24 - 0,8,16,5,13,2,10,18,7,15,4,12,1,9,17,6,14,3,11 + 25-30 - 0,8,16,6,14,4,12,2,10,1,9,17,7,15,5,13,3,11 + 31-40 - 0,8,16,7,15,6,14,5,13,4,12,3,11,2,10,1,9 + + The data within each sector is in two sections, and is stored *out of +order*. This is partially due to the way the 1541 reads the data. The first +256 GCR bytes are read into a buffer, then the remaining 70 GCR bytes are +read into an "overflow" buffer. In the Sixpack image, the last 70 bytes (of +the 326) are first, then the first 256 bytes follow, for reasons left up +the author of the sixpack format. You need to re-arrange the data to be in +the correct order before decoding it. We actually only decode 325 bytes +(from 0-324, this 325 bytes, divisible by 5), so the last byte is left out. +Once decoded, we have the following information: + + Bytes: $000 - Data block descriptor value $07 + 001-100 - Normal sector info + 101 - Sector checksum (EOR of the data block, from 001-100) + 102-103 - "OFF" bytes ($00's), used to "fill" up the sector, to + make it a multiple of 4 bytes. + + ZipCode disks are usually used to transfer disks which contain errors +(copy-protected disks). It also is used for those disks which use unusual +fastloaders such as Vorpal or Warp25, which use different low-level +encoding methods. + + The offset for each track into its respective file can vary. Assuming +that the image contains no errors, we can look at each file and calculate +the offset position of where each track should be. + + File 1!! Offset File 2!! Offset + -------- ------------- -------- ------------- + Track 1 $0003 (3) Track 7 $0003 (3) + Track 2 $1BC1 (7105) Track 8 $1BC1 (7105) + Track 3 $377F (14207) Track 9 $377F (14207) + Track 4 $533D (21309) Track 10 $533D (21309) + Track 5 $6EFB (28411) Track 11 $6EFB (28411) + Track 6 $8AB9 (35513) Track 12 $8AB9 (35513) + + File 3!! Offset File 4!! Offset + -------- ------------- -------- ------------- + Track 13 $0003 (3) Track 19 $0003 (3) + Track 14 $1BC1 (7105) Track 20 $1935 (6453) + Track 15 $377F (14207) Track 21 $3267 (12903) + Track 16 $533D (21309) Track 22 $4B99 (19353) + Track 17 $6EFB (28411) Track 23 $64CB (25803) + Track 18 $8AB9 (35513) Track 24 $7DFD (32253) + Track 25 $972F (38703) + + File 5!! Offset File 6!! Offset + -------- ------------- -------- ------------- + Track 26 $0003 (3) Track 33 $0003 (3) + Track 27 $17EF (6127) Track 34 $16A9 (5801) + Track 28 $2FDB (12251) Track 35 $2D4F (11599) + Track 29 $47C7 (18375) Track 36 $43F5 (17397) + Track 30 $5FB3 (24499) Track 37 $5A9B (23195) + Track 31 $779F (30623) Track 38 $7141 (28993) + Track 32 $8E45 (36421) Track 39 $87E7 (34791) + Track 40 $9E8D (40589) + + + Looking at the error codes for a normal 1541 disk, let's look at how some +of the errors can be stored in the ZipCode images. The following chart is +in reverse order of appearance, with the first errors being the earliest +detected. + + Note that the description of the error may not be *completely* correct +compared to how the drive DOS actually works, but serves as a reasonable +explanation in understanding where the error comes from. + + Err# Error description and method + ---- ----------------------------------------------------------------- + 21 No SYNC character + + Before we can read any sector from a track, the drive will look + for a special "sync" marker, a minimum series of 10 1-bits. If a + sync marker is not found, the track is presumed bad or + unformatted. The SixPack will not contain any sector data + following the 256-byte header as there is no track data to store. + The sector count byte in the track descriptor block will be set + to zero. + + + 20 Header block descriptor not found + + This applies to individual sectors where the header ID ($08, from + above) isn't seen where it should be. The actual header is still + read and stored, and the data should still be there. + + + 27 Header block checksum error + + The checksum stored in the sector header block doesn't correspond + to the checksum calculated for the header. The data block should + still be there. + + + 29 Disk ID mismatch + + The ID's contained in the sector header block don't match the + disk master ID (from the header block of track 18/0, not the one + at offset $A2/A3 of the sector data). The data block is still + present. + + + 22 Data block descriptor not found + + If the special value $07, preceeding the sector data isn't seen + where it should be, this error is generated. The SixPack will + still contain the sector data. + + + 23 Data block checksum error + + This one comes from the checksum value stored after the sector + data. If the checksum present doesn't match the checksum you + calculate, this error is generated. The data block is still + present in the SixPack. + + + When decoding these files, and attempting to determine what errors exist, +here are a few tips to work by... + + 1. Any errors detected in the track descriptor block (20, 27, 29) occur + in linear order (sector 0,1,2,3, etc) + + 2. Any error detected in the data block (22, 23) is *out* of order, and + follows the previously laid-out sector interleave pattern for the + given track. + + + The real strength of this format is its usefulness in transmitting +error-protected and non-standard low-level fast-loaded disks. If the disk +you wish to transmit has no errors, using this format would be a waste as +almost *any* other format will use much less space. + + One caveat to this format is the unforgiving nature of the 6-pack +creation utility on the C64. The one I used would generate a bad sector if +it encountered a sector that was only slightly bad, but would normally read +back fine on the 1541 (due to the drive's error-correcting nature). + diff --git a/Commodore/d64.html b/Commodore/d64.html new file mode 100644 index 0000000..893e9eb --- /dev/null +++ b/Commodore/d64.html @@ -0,0 +1,659 @@ + + +D64 (Electronic form of a physical 1541 disk) + + +
+
+*** D64 (Electronic form of a physical 1541 disk)
+*** Document revision: 1.9
+*** Last updated: March 11, 2004
+*** Contributors/sources: Immers/Neufeld "Inside Commodore  DOS"
+                          Wolfgang Moser
+
+(Note: This document will try to explain the layout of the 1541  disks,  as
+well as some of the files they contain. However, I do not explain  GEOS  or
+REL files here. See the file GEOS.TXT or REL.TXT for  more  information  on
+those file types or disk structure). Special thanks to Wolfgang  Moser  for
+his work on identifying the differences between the various 'Speeder' DOS's
+that exist. This information is included in a table later in this document.
+
+  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 inner  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   Storage in Bytes
+        -----   -------------   ---------   ----------------
+         1-17        21            357           7820
+        18-24        19            133           7170
+        25-30        18            108           6300
+        31-40(*)     17             85           6020
+                                   ---
+                                   683 (for a 35 track image)
+
+  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
+
+  (*)Tracks 36-40 apply to 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, using a sector interleave of 3. This makes  the
+chain links go 18/1, 18/4, 18/7 etc.
+
+Note that you can extend the directory off  of  track  18,  but  only  when
+reading the disk or image. Attempting to write to a directory sector not on
+track 18 will cause directory corruption.
+
+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, max. value 254)
+          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
+
+Files, on a standard 1541, are stored using an interleave of 10. Assuming a
+starting track/sector of 17/0, the chain  would  run  17/0,  17/10,  17/20,
+17/8, 17/18, etc.
+
+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 ($00), 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, DOLPHIN and  ProLogic  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.  Any  leftover
+bits that refer to sectors that don't exist, like bits 21-23 in  the  above
+example, are set to allocated.
+
+  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)
+
+
+---------------------------------------------------------------------------
+
+
+*** 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. This can also have error bytes attached like variant #1.
+
+  3. The Commodore 128 allowed for "auto-boot" disks. With  this,  t/s  1/0
+     holds a specific byte sequence which the computer recognizes  as  boot
+     code. See the document C128BOOT.TXT for more info.
+
+
+  Below is a small chart detailing the standard file sizes of  D64  images,
+35 or 40 tracks, with or without error bytes.
+
+     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
+
+
+  The following table (provided by Wolfgang Moser) outlines the differences
+between the standard 1541 DOS and the various "speeder" DOS's  that  exist.
+The 'header 7/8' category is the 'fill bytes' as  the  end  of  the  sector
+header of  a  real  1541  disk  See  the  document  G64.TXT  for  a  better
+explanation of these bytes.
+
+        Disk format             |Tracks|Header 7/8|Dos type|DiskDos
+                                |      |allsechdrs|        |vs.type
+       ============================================================
+        Original CBM DOS v2.6   |  35  | $0f  $0f |  "2A"  |$41/'A'
+       ------------------------------------------------------------
+        SpeedDOS+               |  40  | $0f  $0f |  "2A"  |$41/'A'
+       ------------------------------------------------------------
+        ProfessionalDOS Initial |  35  | $0f  $0f |  "2A"  |$41/'A'
+          (Version 1/Prototype) |  40  | $0f  $0f |  "2A"  |$41/'A'
+       ------------------------------------------------------------
+        ProfDOS Release         |  40  | $0f  $0f |  "4A"  |$41/'A'
+       ------------------------------------------------------------
+        Dolphin-DOS 2.0/3.0     |  35  | $0f  $0f |  "2A"  |$41/'A'
+        Dolphin-DOS 2.0/3.0     |  40  | $0d  $0f |  "2A"  |$41/'A'
+       ------------------------------------------------------------
+        PrologicDOS 1541        |  35  | $0f  $0f |  "2A"  |$41/'A'
+        PrologicDOS 1541        |  40  | $0f  $0f |  "2P"  |$50/'P'
+        ProSpeed 1571 2.0       |  35  | $0f  $0f |  "2A"  |$41/'A'
+        ProSpeed 1571 2.0       |  40  | $0f  $0f |  "2P"  |$50/'P'
+       ------------------------------------------------------------
+
+
+  The location of the extra BAM information in sector 18/0,  for  40  track
+images, will be different depending on what standard the  disks  have  been
+formatted with. SPEED DOS stores them from $C0 to $D3, DOLPHIN  DOS  stores
+them from $AC to $BF and PrologicDOS stored them right after  the  existing
+BAM entries from $90-A3. PrologicDOS also  moves  the  disk  label  and  ID
+forward from the standard location of $90 to $A4. 64COPY and Star Commander
+let you select from several different types of extended  disk  formats  you
+want to create/work with.
+
+  All three of the speeder DOS's mentioned above don't alter  the  standard
+sector interleave of 10 for files and 3 for directories. The reason is that
+they use a memory cache installed in the drive which reads the entire track
+in one pass. This alleviates the need for custom interleave values. They do
+seem to alter the algorithm that finds the next available  free  sector  so
+that the interleave value can deviate from 10 under certain  circumstances,
+but I don't know why they would bother.
+
+
+  Below is a HEX dump of a Speed DOS BAM sector. Note the location of the
+extra BAM info from $C0-D3.
+
+      00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F       ASCII
+      -----------------------------------------------  ----------------
+0070: 12 FF FF 03 12 FF FF 03 12 FF FF 03 11 FF FF 01  ????????????????
+0080: 11 FF FF 01 11 FF FF 01 11 FF FF 01 11 FF FF 01  ????????????????
+0090: A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0  ????????????????
+00A0: A0 A0 30 30 A0 32 41 A0 A0 A0 A0 00 00 00 00 00  ??00?2A?????????
+00B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ????????????????
+00C0: 11 FF FF 01 11 FF FF 01 11 FF FF 01 11 FF FF 01  ????????????????
+00D0: 11 FF FF 01 00 00 00 00 00 00 00 00 00 00 00 00  ????????????????
+
+
+  Below is a HEX dump of a Dolphin DOS BAM sector. Note the location of the
+extra BAM info from $AC-BF.
+
+      00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F       ASCII
+      -----------------------------------------------  ----------------
+0070: 12 FF FF 03 12 FF FF 03 12 FF FF 03 11 FF FF 01  ????????????????
+0080: 11 FF FF 01 11 FF FF 01 11 FF FF 01 11 FF FF 01  ????????????????
+0090: A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0  ????????????????
+00A0: A0 A0 30 30 A0 32 41 A0 A0 A0 A0 00 11 FF FF 01  ??00?2A?????????
+00B0: 11 FF FF 01 11 FF FF 01 11 FF FF 01 11 FF FF 01  ????????????????
+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  ????????????????
+
+
+  Below is a HEX dump of a PrologicDOS BAM sector. Note that the disk  name
+and ID are now located at $A4 instead of starting at $90.
+
+      00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F       ASCII
+      -----------------------------------------------  ----------------
+0070: 12 FF FF 03 12 FF FF 03 12 FF FF 03 11 FF FF 01  ????????????????
+0080: 11 FF FF 01 11 FF FF 01 11 FF FF 01 11 FF FF 01  ????????????????
+0090: 11 FF FF 01 11 FF FF 01 11 FF FF 01 11 FF FF 01  ????????????????
+00A0: 11 FF FF 01 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0  ????????????????
+00B0: A0 A0 A0 A0 A0 A0 30 30 A0 32 50 A0 A0 A0 A0 00  ??????00?2P?????
+00C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ????????????????
+00ED: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ????????????????
+
+
+---------------------------------------------------------------------------
+
+
+  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, whether it's searching for any SYNC mark, any header ID, any  valid
+header, or reading a sector.
+
+  These first errors are "seek" errors, where the disk controller is simply
+reading headers and looking at descriptor bytes, checksums, format ID's and
+reporting what errors it sees. These errors do *not* necessarily  apply  to
+the exact sector being looked for. This fact  makes  duplication  of  these
+errors very unreliable.
+
+    Code  Error  Type   1541 error description
+    ----  -----  ----   ------------------------------
+     03    21    Seek   No SYNC sequence found.
+
+                        Each  sector  data  block  and  header  block   are
+                        preceeded by SYNC marks. If *no* sync  sequence  is
+                        found within 20 milliseconds (only ~1/10 of a  disk
+                        rotation!) then this error is generated. This error
+                        used to mean the entire track is bad, but  it  does
+                        not have to be the case. Only a small area  of  the
+                        track needs to be without  a  SYNC  mark  and  this
+                        error will be generated.
+
+                        Converting this error to a D64 is very  problematic
+                        because it depends on where the physical head is on
+                        the disk when a read attempt is made. If it  is  on
+                        valid header/sectors then it  won't  occur.  If  it
+                        happens over an area without SYNC  marks,  it  will
+                        happen.
+
+
+     02    20    Seek   Header descriptor byte not found (HEX $08, GCR $52)
+
+                        Each sector is preceeded by an  8-byte  GCR  header
+                        block, which starts with the value  $52  (GCR).  If
+                        this value is not found  after  90  attempts,  this
+                        error is generated.
+
+                        Basically, what a track  has  is  SYNC  marks,  and
+                        possibly valid data blocks,  but  no  valid  header
+                        descriptors.
+
+
+     09    27    Seek   Checksum error in header block
+
+                        The  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.
+
+
+     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
+                        low-level header of 18/0. If there is  a  mismatch,
+                        this error is generated.
+
+
+     02    20    Seek   Header block not found
+
+                        This error can be reported again when searching for
+                        the correct header block. An image of the header is
+                        built and searched for, but not found after 90 read
+                        attempts.  Note  the  difference  from  the   first
+                        occurance. The first one only searches for a  valid
+                        ID, not the whole header.
+
+  Note that error 20 occurs twice during this phase. The first time is when
+a header ID is being searched for, the second is  when  the  proper  header
+pattern for the sector being searched for is not found.
+
+
+  From this point on, all the errors apply to the specific sector  you  are
+looking for. If a read passed all the previous checks, then we are  at  the
+sector being searched for.
+
+  Note that the entire sector is read before  these  errors  are  detected.
+Therefore the data, checksum and off bytes are available.
+
+    Code  Error  Type   1541 error description
+    ----  -----  ----   ------------------------------
+     04    22    Read   Data descriptor byte not found (HEX $07, GCR $55)
+
+                        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.
+
+
+     0F    74    Read   Drive Not Ready (no disk in drive or no device 1)
+
+
+  These errors only  apply  when  writing  to  a  disk.  I  don't  see  the
+usefulness of having these as they cannot be present when only *reading*  a
+disk.
+
+    Code  Error  Type   1541 error description
+    ----  -----  ----   ------------------------------
+     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.
+
+
+     0A    28    Write  Write error
+
+                        In actual fact, this error never occurs, but it  is
+                        included for completeness.
+
+
+  This is not an error at all, but when gets reported when the  read  of  a
+sector is ok.
+
+    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.
+
+
+  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 reasonably robust,  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 files), since you lose the extra 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.
+
+  Preceeding each sector on a real  1541  disk  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.  Some
+programs fail to work properly since the D64 doesn't  contain  these  ID's.
+These bytes would be 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  D64
+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 REL and all GEOS files
+
+  * Allows complete directory customization
+
+  * Because it is a random-access  device,  it  supports  fast-loaders  and
+    random sector access
+
+  * PC 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. This is by no means a big problem.
+
+  * It is not an expandable filetype, like LNX or T64
+
+  * Unless most of the space on a D64 disk is used,  you  do  end  up  with
+    wasted 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 files, GEOS VLIR files)
+
+
+ + diff --git a/Commodore/list.txt b/Commodore/list.txt new file mode 100644 index 0000000..bfda176 --- /dev/null +++ b/Commodore/list.txt @@ -0,0 +1,100 @@ +http://ist.uwaterloo.ca/~schepers/formats/D64.TXT +http://ist.uwaterloo.ca/~schepers/formats/D71.TXT +http://ist.uwaterloo.ca/~schepers/formats/D81.TXT +http://ist.uwaterloo.ca/~schepers/formats/X64.TXT +http://ist.uwaterloo.ca/~schepers/formats/G64.TXT +http://ist.uwaterloo.ca/~schepers/formats/D2M-DNP.TXT +http://ist.uwaterloo.ca/~schepers/formats/D80-D82.TXT +http://ist.uwaterloo.ca/~schepers/formats/DISK.TXT +http://ist.uwaterloo.ca/~schepers/formats/REL.TXT +http://ist.uwaterloo.ca/~schepers/formats/GEOS.TXT +http://ist.uwaterloo.ca/~schepers/formats/F64.TXT +http://ist.uwaterloo.ca/~schepers/formats/T64.TXT +http://ist.uwaterloo.ca/~schepers/formats/TAP.TXT +http://ist.uwaterloo.ca/~schepers/formats/ARC.TXT +http://ist.uwaterloo.ca/~schepers/formats/ARK-SRK.TXT +http://ist.uwaterloo.ca/~schepers/formats/CKIT.TXT +http://ist.uwaterloo.ca/~schepers/formats/CPK.TXT +http://ist.uwaterloo.ca/~schepers/formats/LHA.TXT +http://ist.uwaterloo.ca/~schepers/formats/LNX.TXT +http://ist.uwaterloo.ca/~schepers/formats/SDA.TXT +http://ist.uwaterloo.ca/~schepers/formats/SFX.TXT +http://ist.uwaterloo.ca/~schepers/formats/SPYNE.TXT +http://ist.uwaterloo.ca/~schepers/formats/WRA-WR3.TXT +http://ist.uwaterloo.ca/~schepers/formats/ZIP.TXT +http://ist.uwaterloo.ca/~schepers/formats/ZIP_DISK.TXT +http://ist.uwaterloo.ca/~schepers/formats/ZIP_FILE.TXT +http://ist.uwaterloo.ca/~schepers/formats/ZIP_SIX.TXT +http://ist.uwaterloo.ca/~schepers/formats/BINARY.TXT +http://ist.uwaterloo.ca/~schepers/formats/BITMAP.TXT +http://ist.uwaterloo.ca/~schepers/formats/CRT.TXT +http://ist.uwaterloo.ca/~schepers/formats/CVT.TXT +http://ist.uwaterloo.ca/~schepers/formats/LBR.TXT +http://ist.uwaterloo.ca/~schepers/formats/WAV.TXT +http://ist.uwaterloo.ca/~schepers/formats/PC64.TXT +http://ist.uwaterloo.ca/~schepers/formats/SIDPLAY.TXT +http://ist.uwaterloo.ca/~schepers/formats/64LAN.TXT +http://ist.uwaterloo.ca/~schepers/formats/64NET.TXT +http://ist.uwaterloo.ca/~schepers/formats/PCLINK.TXT +http://ist.uwaterloo.ca/~schepers/formats/PCVIC.TXT +http://ist.uwaterloo.ca/~schepers/formats/PHAUZEH.TXT +http://ist.uwaterloo.ca/~schepers/formats/VICE_FRZ.TXT +http://ist.uwaterloo.ca/~schepers/formats/POWER64.TXT +http://ist.uwaterloo.ca/~schepers/formats/C64S_FRZ.TXT +http://ist.uwaterloo.ca/~schepers/formats/PC64_FRZ.TXT +http://ist.uwaterloo.ca/~schepers/formats/PC64_ROM.TXT +http://ist.uwaterloo.ca/~schepers/F64.html +http://unusedino.de/ec64/technical/formats/d64.html +http://vice-emu.sourceforge.net/vice_15.html +http://ist.uwaterloo.ca/~schepers/formats/64LAN.TXT +http://ist.uwaterloo.ca/~schepers/formats/64NET.TXT +http://ist.uwaterloo.ca/~schepers/formats/ARC.TXT +http://ist.uwaterloo.ca/~schepers/formats/ARK-SRK.TXT +http://ist.uwaterloo.ca/~schepers/formats/BINARY.TXT +http://ist.uwaterloo.ca/~schepers/formats/BITMAP.TXT +http://ist.uwaterloo.ca/~schepers/formats/C64S_FRZ.TXT +http://ist.uwaterloo.ca/~schepers/formats/C128BOOT.TXT +http://ist.uwaterloo.ca/~schepers/formats/CKIT.TXT +http://ist.uwaterloo.ca/~schepers/formats/CPK.TXT +http://ist.uwaterloo.ca/~schepers/formats/CRT.TXT +http://ist.uwaterloo.ca/~schepers/formats/CVT.TXT +http://ist.uwaterloo.ca/~schepers/formats/D2M-DNP.TXT +http://ist.uwaterloo.ca/~schepers/formats/D64.TXT +http://ist.uwaterloo.ca/~schepers/formats/D71.TXT +http://ist.uwaterloo.ca/~schepers/formats/D80-D82.TXT +http://ist.uwaterloo.ca/~schepers/formats/D81.TXT +http://ist.uwaterloo.ca/~schepers/formats/DISK.TXT +http://ist.uwaterloo.ca/~schepers/formats/F64.TXT +http://ist.uwaterloo.ca/~schepers/formats/G64.TXT +http://ist.uwaterloo.ca/~schepers/formats/GEOS.TXT +http://ist.uwaterloo.ca/~schepers/formats/INTRO.TXT +http://ist.uwaterloo.ca/~schepers/formats/LBR.TXT +http://ist.uwaterloo.ca/~schepers/formats/LHA.TXT +http://ist.uwaterloo.ca/~schepers/formats/LNX.TXT +http://ist.uwaterloo.ca/~schepers/formats/PC64.TXT +http://ist.uwaterloo.ca/~schepers/formats/PC64_FRZ.TXT +http://ist.uwaterloo.ca/~schepers/formats/PC64_ROM.TXT +http://ist.uwaterloo.ca/~schepers/formats/PCLINK.TXT +http://ist.uwaterloo.ca/~schepers/formats/PCVIC.TXT +http://ist.uwaterloo.ca/~schepers/formats/PHAUZEH.TXT +http://ist.uwaterloo.ca/~schepers/formats/POWER64.TXT +http://ist.uwaterloo.ca/~schepers/formats/REL.TXT +http://ist.uwaterloo.ca/~schepers/formats/SDA.TXT +http://ist.uwaterloo.ca/~schepers/formats/SFX.TXT +http://ist.uwaterloo.ca/~schepers/formats/SIDPLAY.TXT +http://ist.uwaterloo.ca/~schepers/formats/SPYNE.TXT +http://ist.uwaterloo.ca/~schepers/formats/T64.TXT +http://ist.uwaterloo.ca/~schepers/formats/TAP.TXT +http://ist.uwaterloo.ca/~schepers/formats/VICE_FRZ.TXT +http://ist.uwaterloo.ca/~schepers/formats/WAV.TXT +http://ist.uwaterloo.ca/~schepers/formats/WRA-WR3.TXT +http://ist.uwaterloo.ca/~schepers/formats/X64.TXT +http://ist.uwaterloo.ca/~schepers/formats/ZIP.TXT +http://ist.uwaterloo.ca/~schepers/formats/ZIP_DISK.TXT +http://ist.uwaterloo.ca/~schepers/formats/ZIP_FILE.TXT +http://ist.uwaterloo.ca/~schepers/formats/ZIP_SIX.TXT +http://justsolve.archiveteam.org/wiki/CBMFS +http://justsolve.archiveteam.org/wiki/Commodore_1581_disk +http://justsolve.archiveteam.org/wiki/Commodore_1571_disk +http://justsolve.archiveteam.org/wiki/Commodore_1541_disk + diff --git a/Commodore/vice_15.html b/Commodore/vice_15.html new file mode 100644 index 0000000..2ce46fe --- /dev/null +++ b/Commodore/vice_15.html @@ -0,0 +1,11213 @@ + + + + +VICE Manual - 15 The emulator file formats + + +Go to the first, previous, next, last section, table of contents. +


+ + +

15 The emulator file formats

+ +

+This chapter gives a technical description of the various files +supported by the emulators. + +

+ + + +

15.1 The T64 tape image format

+ +

+(This section was taken from the C64S distribution.) + +

+

+The T64 File Structure was developed by Miha Peternel for use in +the C64S emulator. It is easy to use and allows future extensions. + +

+ + + +

15.1.1 T64 File structure

+ + + + + + + + + + + + + + + + + + + + + + +
OffsetSizeDescription
064tape record
6432*nfile records for n directory entries
64+32*nvariesbinary contents of the files
+ + + +

15.1.2 Tape Record

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OffsetSizeDescription
032DOS tape description + EOF (for type)
322tape version ($0200)
342number of directory entries
362number of used entries (can be 0 in my loader)
382free
4024user description as displayed in tape menu
+ + + +

15.1.3 File record

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OffsetSizeDescription
01entry type (see below)
11C64 file type
22start address
42end address
62free
84offset of file contents start within T64 file
124free
1616C64 file name
+ +

+Valid entry types are: + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CodeExplanation
0free entry
1normal tape file
2tape file with header: header is saved just before file data
3memory snapshot v0.9, uncompressed
4tape block
5digitized stream
6 ... 255reserved
+ +

+Notes: + +

+ +
    +
  • VICE only supports file type 1. + +
  • Types 3, 4 and 5 are subject to change (and + +are rarely used). +
+ + + +

15.2 The G64 GCR-encoded disk image format

+ +

+(This section was contributed by Peter Schepers and slightly edited by +Ettore Perazzoli.) + +

+

+This format was defined in 1998 as a cooperative effort between several +emulator people, mainly Per Hkan Sundell, author of the CCS64 C64 +emulator, Andreas Boose of the VICE CBM emulator team and Joe +Forster/STA, the author of Star Commander. It was the first real public +attempt to create a format for the emulator community which removed +almost all of the drawbacks of the other existing image formats, namely +D64. + +

+

+The intention behind G64 is not to replace the widely used +D64 format, as D64 works fine with the vast majority of +disks in existence. It is intended for those small percentage of +programs which demand to work with the 1541 drive in a non-standard way, +such as reading or writing data in a custom format. The best example is +with speeder software such as Action Cartridge in Warp Save mode or +Vorpal which write track/sector data in another format other than +standard GCR. The other obvious example is copy-protected software +which looks for some specific data on a track, like the disk ID, which +is not stored in a standard D64 image. + +

+

+G64 has a deceptively simply layout for what it is capable of +doing. We have a signature, version byte, some predefined size values, +and a series of offsets to the track data and speed zones. It is what's +contained in the track data areas and speed zones which is really at the +heart of this format. + +

+

+Each track entry in simply the raw stream of GCR data, just what a read +head would see when a diskette is rotating past it. How the data gets +interpreted is up to the program trying to access the disk. Because the +data is stored in such a low-level manner, just about anything can be +done. Most of the time I would suspect the data in the track would be +standard sectors, with SYNC, GAP, header, data and checksums. The +arrangement of the data when it is in a standard GCR sector layout is +beyond the scope of this document. + +

+

+Since it is a flexible format in both track count and track byte size, +there is no "standard" file size. However, given a few constants like +42 tracks and halftracks, a track size of 7928 bytes and no speed offset +entries, the typical file size will a minimum of 333744 bytes. + +

+

+Below is a dump of the header, broken down into its various parts. +After that will be an explanation of the track offset and speed zone +offset areas, as they demand much more explanation. + +

+ +
+Addr  00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
+----  -----------------------------------------------
+0000: 47 43 52 2D 31 35 34 31 00 54 F8 1E .. .. .. ..
+
+ + + + + + + + + + + + + + + + + + + + + + +
OffsetDescription
$0000-0007File signature (GCR-1541)
$0008G64 version (presently only $00 defined)
$0009Number of tracks in image (usually $54, decimal 84)
$000A-000BSize of each stored track in bytes (usually 7928, or $1EF8) in LO/HI format.
+ +

+An obvious question here is "why are there 84 tracks defined when a +normal D64 disk only has 35 tracks?" Well, by definition, this +image includes all half-tracks, so there are actually 42 tracks and 42 +half tracks. The 1541 stepper motor can access up to 42 tracks and the +in-between half-tracks. Even though using more than 35 tracks is not +typical, it was important to define this format from the start with what +the 1541 is capable of doing, and not just what it typically does. + +

+

+At first, the defined track size value of 7928 bytes may seem to be +arbitrary, but it is not. It is determined by the fastest write speed +possible (speed zone 0), coupled with the average rotation speed of the +disk (300 rpm). After some math, the answer that actually comes up is +7692 bytes. Why the discrepency between the actual size of 7692 and the +defined size of 7928? Simply put, not all drives rotate at 300 rpm. +Some can be faster or slower, so a upper safety margin of +3% was built +added, in case some disks rotate slower and can write more data. After +applying this safety factor, and some rounding-up, 7928 bytes per track +was arrived at. + +

+

+Also note that this upper limit of 7928 bytes per track really only +applies to 1541 and compatible disks. If this format were applied to +another disk type like the SFD1001, this value would be higher. + +

+

+Below is a dump of the first section of a G64 file, showing the offsets +to the data portion for each track and half-track entry. Following that +is a dump of the speed zone offsets. + +

+ +
+Addr  00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
+----  -----------------------------------------------
+0000: .. .. .. .. .. .. .. .. .. .. .. .. AC 02 00 00
+0010: 00 00 00 00 A6 21 00 00 00 00 00 00 A0 40 00 00
+0020: 00 00 00 00 9A 5F 00 00 00 00 00 00 94 7E 00 00
+0030: 00 00 00 00 8E 9D 00 00 00 00 00 00 88 BC 00 00
+0040: 00 00 00 00 82 DB 00 00 00 00 00 00 7C FA 00 00
+0050: 00 00 00 00 76 19 01 00 00 00 00 00 70 38 01 00
+0060: 00 00 00 00 6A 57 01 00 00 00 00 00 64 76 01 00
+0070: 00 00 00 00 5E 95 01 00 00 00 00 00 58 B4 01 00
+0080: 00 00 00 00 52 D3 01 00 00 00 00 00 4C F2 01 00
+0090: 00 00 00 00 46 11 02 00 00 00 00 00 40 30 02 00
+00A0: 00 00 00 00 3A 4F 02 00 00 00 00 00 34 6E 02 00
+00B0: 00 00 00 00 2E 8D 02 00 00 00 00 00 28 AC 02 00
+00C0: 00 00 00 00 22 CB 02 00 00 00 00 00 1C EA 02 00
+00D0: 00 00 00 00 16 09 03 00 00 00 00 00 10 28 03 00
+00E0: 00 00 00 00 0A 47 03 00 00 00 00 00 04 66 03 00
+00F0: 00 00 00 00 FE 84 03 00 00 00 00 00 F8 A3 03 00
+0100: 00 00 00 00 F2 C2 03 00 00 00 00 00 EC E1 03 00
+0110: 00 00 00 00 E6 00 04 00 00 00 00 00 E0 1F 04 00
+0120: 00 00 00 00 DA 3E 04 00 00 00 00 00 D4 5D 04 00
+0130: 00 00 00 00 CE 7C 04 00 00 00 00 00 C8 9B 04 00
+0140: 00 00 00 00 C2 BA 04 00 00 00 00 00 BC D9 04 00
+0150: 00 00 00 00 B6 F8 04 00 00 00 00 00 .. .. .. ..
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OffsetDescription
$000C-000FOffset to stored track 1.0 ($000002AC, in LO/HI format, see below for more)
$0010-0013Offset to stored track 1.5 ($00000000)
$0014-0017Offset to stored track 2.0 ($000021A6)
...
$0154-0157Offset to stored track 42.0 ($0004F8B6)
$0158-015BOffset to stored track 42.5 ($00000000)
+ + +
+      00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
+      -----------------------------------------------
+0150: .. .. .. .. .. .. .. .. .. .. .. .. 03 00 00 00
+0160: 00 00 00 00 03 00 00 00 00 00 00 00 03 00 00 00
+0170: 00 00 00 00 03 00 00 00 00 00 00 00 03 00 00 00
+0180: 00 00 00 00 03 00 00 00 00 00 00 00 03 00 00 00
+0190: 00 00 00 00 03 00 00 00 00 00 00 00 03 00 00 00
+01A0: 00 00 00 00 03 00 00 00 00 00 00 00 03 00 00 00
+01B0: 00 00 00 00 03 00 00 00 00 00 00 00 03 00 00 00
+01C0: 00 00 00 00 03 00 00 00 00 00 00 00 03 00 00 00
+01D0: 00 00 00 00 03 00 00 00 00 00 00 00 03 00 00 00
+01E0: 00 00 00 00 02 00 00 00 00 00 00 00 02 00 00 00
+01F0: 00 00 00 00 02 00 00 00 00 00 00 00 02 00 00 00
+0200: 00 00 00 00 02 00 00 00 00 00 00 00 02 00 00 00
+0210: 00 00 00 00 02 00 00 00 00 00 00 00 01 00 00 00
+0220: 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00
+0230: 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00
+0240: 00 00 00 00 01 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 .. .. .. ..
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
OffsetDescription
$015C-015FSpeed zone entry for track 1 ($03, in LO/HI format, see below for more)
$0160-0163Speed zone entry for track 1.5 ($03)
...
$02A4-02A7Speed zone entry for track 42 ($00)
$02A8-02ABSpeed zone entry for track 42.5 ($00)
+ +

+Starting here at $02AC is the first track entry (from above, it is the +first entry for track 1.0) + +

+

+The track offsets (from above) require some explanation. When one is +set to all 0's, no track data exists for this entry. If there is a +value, it is an absolute reference into the file (starting from the +beginning of the file). From the track 1.0 entry we see it is set for +$000002AC. Going to that file offset, here is what we see... + +

+ +
+      00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
+      -----------------------------------------------
+02A0: .. .. .. .. .. .. .. .. .. .. .. .. 0C 1E FF FF
+02B0: FF FF FF 52 54 B5 29 4B 7A 5E 95 55 55 55 55 55
+02C0: 55 55 55 55 55 55 FF FF FF FF FF 55 D4 A5 29 4A
+02D0: 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52
+
+ + + + + + + + + + + + + + +
OffsetDescription
$02AC-02ADActual size of stored track (7692 or $1E0C, in LO/HI format)
$02AE-02AE+$1E0CTrack data
+ +

+Following the track data is filler bytes. In this case, there are 368 +bytes of unused space. This space can contain anything, but for the +sake of those wishing to compress these images for storage, they should +all be set to the same value. In the sample I used, these are all set +to $FF. + +

+

+Below is a dump of the end of the track 1.0 data area. Note the actual +track data ends at address $20B9, with the rest of the block being +unused, and set to $FF. + +

+ +
+      00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
+      -----------------------------------------------
+1FE0: 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52
+1FF0: 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94
+2000: A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5
+2010: 29 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29
+2020: 4A 52 94 A5 29 4A 52 94 A5 29 4A 52 94 A5 29 4A
+2030: 55 55 55 55 55 55 FF FF FF FF FF FF FF FF FF FF
+2040: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+2050: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+2060: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+2070: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+2080: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+2090: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+20A0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+20B0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+20C0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+20D0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+20E0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+20F0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+2100: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+2110: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+2120: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+2130: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+2140: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+2150: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+2160: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+2170: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+2180: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+2190: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+21A0: FF FF FF FF FF FF .. .. .. .. .. .. .. .. .. ..
+
+ +

+The speed offset entries can be a little more complex. The 1541 has four +speed zones defined, which means the drive can write data at four +distinct speeds. On a normal 1541 disk, these zones are as follows: + +

+ + + + + + + + + + + + + + + + + + + + + +
Track RangeSpeed Zone
1-173 (highest writing speed)
18-242
25-301
31 and up0 (lowest writing speed)
+ +

+Note that you can, through custom programming of the 1541, change the +speed zone of any track to something different (change the 3 to a 0) and +write data differently. From the dump of the speed offset entries +above, we see that all the entries are in the range of 0-3. If any entry +is less than 4, this is not considered a speed offset but defines the +whole track to be recorded at that one speed. + +

+

+In the example I had, there were no offsets defined, so no speed zone +dump can be shown. However, I can define what should be there. You +will have a block of data, 1982 bytes long. Each byte is encoded to +represent the speed of 4 bytes in the track offset area, and is broken +down as follows: + +

+ +
+Speed entry $FF:  in binary %11111111
+                             |'|'|'|'
+                             | | | |
+                             | | | +- 4'th byte speed (binary 11, 3 dec)
+                             | | +--- 3'rd byte speed (binary 11, 3 dec)
+                             | +----- 2'nd byte speed (binary 11, 3 dec)
+                             +------- 1'st byte speed (binary 11, 3 dec)
+
+ +

+It was very smart thinking to allow for two speed zone settings, one in +the offset block and another defining the speed on a per-byte basis. If +you are working with a normal disk, where each track is one constant +speed, then you don't need the extra blocks of information hanging +around the image, wasting space. + +

+

+What may not be obvious is the flexibility of this format to add tracks +and speed offset zones at will. If a program decides to write a track +out with varying speeds, and no speed offset exist, a new block will be +created by appending it to the end of the image, and the offset pointer +for that track set to point to the new block. If a track has no offset +yet, meaning it doesn't exist (like a half-track), and one needs to be +added, the same procedure applies. The location of the actual track or +speed zone data is not important, meaning they do not have to be in any +particular order since they are all referenced by the offsets at the +beginning of the image. + +

+ + +

15.3 The P64 NRZI flux pulse disk image format

+ +

+This section is taken from "P64 file format specification" by Benjamin 'BeRo' +Rosseaux. + +

+

+All values are in little endian order ! + +

+ + +

15.3.1 P64 Header Layout

+ + +
+        0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
+      +---------------------------------------------------------------+
+0000: |'P'|'6'|'4'|'-'|'1'|'5'|'4'|'1'|    Version    |     Flags     |   
+      +---------------+---------------+-------------------------------+
+0010: |     Size      | CRC32Checksum |
+      +-------------------------------+
+
+ +

+ Version: File format version, current is 0x00000000 + + Size Size of the following whole chunk content stream + + Flags: Bit 0 = Write protect + Bit 1-31 = Reserved, all set to 0 when creating a file, + preserve existing value when updating + + CRC32CheckSum: CRC32 checksum of the following whole chunk content stream + +

+ + +

15.3.2 P64 Chunk Header Layout

+ + +
+        0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
+      +-----------------------------------------------+
+0000: |Chunk Signature|      Size     | CRC32Checksum |   
+      +-----------------------------------------------+
+
+ +

+ Chunk signature: Signature of chunk + + Size: Size of the chunk data + + CRC32CheckSum: CRC32 checksum of the chunk data + +

+ + +

15.3.3 P64 Chunk 'HTPx' Layout

+ +

+ | x = half track index byte | + +---------------------------+ + + Track 18 = Half track 36 = Half track index byte decimal value 36 + + Half track NRZI transition flux pulse data chunk block + + +

+        0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
+      +---------------------------------------------------------------+
+0000: |  Count pulses |     Size      | ..... Range-encoded data .... |    
+      +---------------------------------------------------------------+
+
+ +

+ Count pulses: Count of the NRZI transition flux pulses in half track + + Size: Size of the range-encoded data + + + +

15.3.4 'HTPx' Range encoded data format

+ +

+ Hint: For a working C implememtation see p64.c and p64.h + +

+

+The range coder is a FPAQ0-style range coder combined with 12-bit 0-order +models, one model per byte with one bit per byte processing. + +

+ +
+ +--------------------------------------------------------------------------+
+ |   Sub stream     | Count of models |  Size per model  | Total value bits |
+ +------------------+-----------------+------------------+------------------+
+ |     Position     |        4        |      65536       |        32        |
+ +------------------+-----------------+------------------+------------------+
+ |     Strength     |        4        |      65536       |        32        | 
+ +------------------+-----------------+------------------+------------------+
+ |   Position flag  |        1        |        2         |        1         |
+ +------------------+-----------------+------------------+------------------+
+ |   Strenth flag   |        1        |        2         |        1         | 
+ +------------------+-----------------+------------------+------------------+
+ +===Total models===|        10       |==================|==================|
+ +--------------------------------------------------------------------------+
+
+ +

+All initial model state values are initialized with zero. + +All initial model probability values are initialized with 2048. + +

+

+These model probability values will be updating in a adaptive way on the +fly and not precalculated before the encoding and even not loaded before +the decoding, see pseudo code below. + +

+

+16000000 Hz / 5 rotations per second at 300 RPM = maximal 3200000 flux pulses + +So NRZI transition flux pulse positions are in the 0 .. 3199999 value range, +which is also a exact single rotation, where each time unit is a cycle at +16 MHz with 300 RPM as a mapping for the ideal case. + +The NRZI transition flux pulse stength are in the 0x00000000 .. 0xffffffff +value range, where 0xffffffff indices a strong flux pulse, that always +triggers, and 0x00000001 indices a weak flux pulse, that almost never +triggers, and 0x00000000 indices a flux pulse, that absolutly never +triggers. + +For 32-bit values, the model sub streams are subdivided byte wide in a +little-endian manner, and each byte is processed bitwise with model +probability shifting of 4 bits, just as: + +

+

+Pascal-Style pseudo code: + +

+procedure WriteDWord(Model, Value : longword);                             
+var ByteValue, ByteIndex, Context, Bit : longword;                         
+begin                                                                      
+  for ByteIndex := 0 to 3 do begin                                         
+    ByteValue := (Value shr (ByteIndex shl 3)) and $ff;                    
+    Context := 1;                                                          
+    for Bit := 7 downto 0 do begin                                         
+      Context := (Context shl 1) or RangeCoderEncodeBit(                   
+                    RangeCoderProbabilities[                               
+                     RangeCoderProbabilityOffsets[Model + ByteIndex] +     
+                     (((RangeCoderProbabilityStates[Model + ByteIndex]      
+                     shl 8) or Context) and $ffff)], 4, (ByteValue shr     
+                     Bit) and 1);                                          
+    end;                                                                   
+    RangeCoderProbabilityStates[Model+ByteIndex] := ByteValue;             
+  end;                                                                     
+end;                                                                       
+
+ +

+And for 1-bit flag values it is much simpler, but also with model probability +shifting of 4 bits, just as: + +

+

+Pascal-Style pseudo code: + +

+procedure WriteBit(Model, Value : longword);                               
+begin                                                                      
+   RangeCoderProbabilityStates[Model] :=                                   
+     RangeCoderEncodeBit(RangeCoderProbabilities[                          
+       RangeCoderProbabilityOffsets[Model] +                               
+         RangeCoderProbabilityStates[Model]], 4, Value and 1);             
+end;                                                                       
+
+ +

+The position and strength values are delta-encoded. If a value is equal to +the last previous value, then the value will not encoded, instead, a flag for +this will encoded. First the position value will encoded, then the stength +value. If the last position delta is 0, then it is a track stream end marker. + +

+

+Pascal-Style pseudo code: + +

+LastPosition := 0;                                                         
+PreviousDeltaPosition := 0                                                 
+                                                                           
+LastStrength := 0;                                                         
+                                                                           
+for PulseIndex := 0 to PulseCount - 1 do begin                             
+                                                                           
+  DeltaPosition := Pulses[PulseIndex].Position - LastPosition;             
+  if PreviousDeltaPosition <> DeltaPosition then begin                     
+    PreviousDeltaPosition := DeltaPosition;                                
+    WriteBit(ModelPositionFlag, 1)                                         
+    WriteDWord(ModelPosition, DeltaPosition);                              
+  end else begin                                                           
+    WriteBit(ModelPositionFlag, 0);                                        
+  end;                                                                     
+  LastPosition := Pulses[PulseIndex].Position;                              
+                                                                           
+  if LastStrength <> Pulses[PulseIndex].Strength then begin                
+    WriteBit(ModelStrengthFlag, 1)                                         
+    WriteDWord(ModelStrength, Pulses[PulseIndex].Strength - LastStrength);   
+  end else begin                                                           
+    WriteBit(ModelStrengthFlag, 0);                                         
+  end;                                                                       
+  LastStrength := Pulses^[PulseIndex].Strength;                            
+                                                                           
+end;                                                                       
+                                                                           
+// End code                                                                
+WriteBit(ModelPositionFlag, 1);                                            
+WriteDWord(ModelPosition, 0);                                              
+
+ +

+ +The decoding is simply just in the another direction way. + +Pseudo code for a FPAQ0-style carryless range coder: + +

+

+Pascal-Style pseudo code: + +

+procedure RangeCoderInit; // At encoding and decoding start                
+begin                                                                      
+  RangeCode := 0;                                                          
+  RangeLow := 0;                                                           
+  RangeHigh := $ffffffff;                                                  
+end;                                                                       
+                                                                           
+procedure RangeCoderStart; // At decoding start                            
+var Counter : longword;                                                       
+begin                                                                      
+  for Counter := 1 to 4 do begin                                           
+   RangeCode := (RangeCode shl 8) or ReadByteFromInput;                    
+  end;                                                                     
+end;                                                                       
+                                                                           
+procedure RangeCoderFlush; // At encoding end                              
+var Counter : longword;                                                      
+begin                                                                      
+  for Counter := 1 to 4 do begin                                           
+    WriteByteToOutput(RangeHigh shr 24);                                   
+    RangeHigh := RangeHigh shl 8;                                          
+  end;                                                                     
+end;                                                                        
+                                                                           
+procedure RangeCoderEncodeNormalize;                                          
+begin                                                                      
+  while ((RangeLow xor RangeHigh) and $ff000000) = 0 do begin              
+   WriteByteToOutput(RangeHigh shr 24);                                    
+   RangeLow := RangeLow shl 8;                                             
+   RangeHigh := (RangeHigh shl 8) or $ff;                                    
+  end;                                                                      
+end;                                                                        
+                                                                           
+function RangeCoderEncodeBit(var Probability : longword; Shift,            
+                             BitValue : longword) : longword;               
+begin                                                                      
+  RangeMiddle := RangeLow + (((RangeHigh - RangeLow) shr 12) *             
+                              Probability);                                  
+  if BitValue <> 0 then begin                                               
+    inc(Probability, ($fff - Probability) shr Shift);                      
+    RangeHigh := RangeMiddle;                                                
+  end else begin                                                           
+    dec(Probability, Probability shr Shift);                               
+    RangeLow := RangeMiddle + 1;                                           
+  end;                                                                     
+  RangeCoderEncodeNormalize;                                               
+  result := BitValue;                                                      
+end;                                                                       
+                                                                            
+procedure RangeCoderDecodeNormalize;                                        
+begin                                                                      
+  while ((RangeLow xor RangeHigh) and $ff000000) = 0 do begin              
+    RangeLow := RangeLow shl 8;                                            
+    RangeHigh := (RangeHigh shl 8) or $ff;                                 
+    RangeCode := (RangeCode shl 8) or ReadByteFromInput;                   
+  end;                                                                     
+end;                                                                       
+                                                                            
+function RangeCoderDecodeBit(var Probability : longword;                   
+                             Shift : longword) : longword;                 
+begin                                                                      
+  RangeMiddle := RangeLow + (((RangeHigh - RangeLow) shr 12) *             
+                             Probability);                                 
+  if RangeCode <= RangeMiddle then begin                                   
+    inc(Probability, ($fff - Probability) shr Shift);                      
+    RangeHigh := RangeMiddle;                                              
+    result := 1;                                                           
+  end else begin                                                           
+    dec(Probability, Probability shr Shift);                               
+    RangeLow := RangeMiddle + 1;                                           
+    result := 0;                                                           
+  end;                                                                     
+  RangeCoderDecodeNormalize;                                               
+end;                                                                       
+
+ +

+The probability may be never zero! But that can't happen here with this +adaptive model in this P64 file format, since the adaptive model uses a +shift factor of 4 bits and initial probabilities value of 2048, so the +probability has a value range from 15 up to 4080 here. If you do want to use +the above range coder routines for other stuff with other probability models, +then you must to ensure that the probability output value is never zero, for +example with "probability |= (probability < 1); " in C. + + + +

15.3.5 P64 Chunk 'DONE' Layout

+ +

+This is the last empty chunk for to signalize that the correct file end is +reached. + +

+ + + +

15.4 The D64 disk image format

+ +

+(This section was contributed by Peter Schepers and slightly edited by +Marco van den Heuvel.) + +

+

+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 inner 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. + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TrackSectors/track# Sectors
1-1721357
18-2419133
25-3018108
31-351785
36-40(*)1785
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Track#Sect#SectorsInD64 Offset
1210$00000
22121$01500
32142$02A00
42163$03F00
52184$05400
621105$06900
721126$07E00
821147$09300
921168$0A800
1021189$0BD00
1121210$0D200
1221231$0E700
1321252$0FC00
1421273$11100
1521294$12600
1621315$13B00
1721336$15000
1819357$16500
1919376$17800
2019395$18B00
2119414$19E00
2219433$1B100
2319452$1C400
2419471$1D700
2518490$1EA00
2618508$1FC00
2718526$20E00
2818544$22000
2918562$23200
3018580$24400
3117598$25600
3217615$26700
3317632$27800
3417649$28900
3517666$29A00
36(*)17683$2AB00
37(*)17700$2BC00
38(*)17717$2CD00
39(*)17734$2DE00
40(*)17751$2EF00
+ +

+(*) Tracks 36-40 apply to 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, using a sector interleave of 3. This makes the +chain links go 18/1, 18/4, 18/7 etc. + +

+

+Note that you can extend the directory off of track 18, but only +when reading the disk or image. Attempting to write to a directory +sector not on track 18 will cause directory corruption. 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: + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BytesDescription
$00-$1FFirst directory entry
$20-$3FSecond dir entry
$40-$5FThird dir entry
$60-$7FFourth dir entry
$80-$9FFifth dir entry
$A0-$BFSixth dir entry
$C0-$DFSeventh dir entry
$E0-$FFEighth dir entry
+ +

+This is a breakdown of a standard directory entry: + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BytesDescription
$00-$01Track/Sector location of next directory sector ($00 $00 if not the first entry in the sector)
$02File type
$03-$04Track/sector location of first sector of file
$05-$1416 character filename (in PETASCII, padded with $A0)
$15-$16Track/Sector location of first side-sector block (REL file only)
$17REL file record length (REL file only, max. value 254)
$18-$1DUnused (except with GEOS disks)
$1E-$1FFile size in sectors, low/high byte order ($1E+$1F*256). The approx. filesize in bytes is <= #sectors * 254
+ +

+The file type field is used as follows: + +

+ + + + + + + + + + + + + + + + + + + + + + + + + +
BitsDescription
0-3The actual file type
4Unused
5Used only during SAVE-@ replacement
6Locked flag (Set produces ">" locked files)
7Closed flag (Not set produces "*", or "splat" files)
+ +

+The actual file type can be one of the following: + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BinaryDecimalFile type
00000DEL
00011SEQ
00102PRG
00113USR
01004REL
+ +

+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. + +

+

+Files, on a standard 1541, are stored using an interleave of 10. +Assuming a starting track/sector of 17/0, the chain would run +17/0, 17/10, 17/20, 17/8, 17/18, etc. + +

+ + +

15.4.1 Non-Standard & Long Directories

+ +

+Most Commdore floppy disk drives use a single dedicated +directory track where all filenames are stored. This limits the +number of files stored on a disk based on the number of sectors +on the directory track. There are some disk images that contain +more files than would normally be allowed. This requires extending +the directory off the default directory track by changing the last +directory sector pointer to a new track, allocating the new +sectors in the BAM, and manually placing (or moving existing) file +entries there. The directory of an extended disk can be read and +the files that reside there can be loaded without problems on a +real drive. However, this is still a very dangerous practice as +writing to the extended portion of the directory will cause +directory corruption in the non-extended part. Many of the floppy +drives core ROM routines ignore the track value that the directory +is on and assume the default directory track for operations. + +

+

+To explain: assume that the directory has been extended from track +18 to track 19/6 and that the directory is full except for a few +slots on 19/6. When saving a new file, the drive DOS will find an +empty file slot at 19/6 offset $40 and correctly write the filename +and a few other things into this slot. When the file is done being +saved the final file information will be written to 18/6 offset $40 +instead of 19/6 causing some directory corruption to the entry at +18/6. Also, the BAM entries for the sectors occupied by the new +file will not be saved and the new file will be left as a SPLAT (*) +file. + +

+

+Attempts to validate the disk will result in those files residing +off the directory track to not be allocated in the BAM, and could +also send the drive into an endless loop. The default directory +track is assumed for all sector reads when validating so if the +directory goes to 19/6, then the validate code will read 18/6 +instead. If 18/6 is part of the normal directory chain then the +validate routine will loop endlessly. + +

+ + +

15.4.2 BAM layout

+ +

+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
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BytesDescription
$00-$01Track/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)
$02Disk DOS version type (see note below) $41 ("A")
$03Unused
$04-$8FBAM entries for each track, in groups of four bytes per track, starting on track 1 (see below for more details)
$90-$9FDisk Name (padded with $A0)
$A0-$A1Filled with $A0
$A2-$A3Disk ID
$A4Usually $A0
$A5-$A6DOS type, usually "2A"
$A7-$AAFilled with $A0
$ABUnused ($00)
$AC-$BFFor DOLPHIN DOS track 36-40 BAM entries, otherwise unused ($00)
$C0-$D3For SPEED DOS track 36-40 BAM entries, otherwise unused ($00)
$D4-$FF Unused ($00)
+ +

+Note: The BAM entries for SPEED, DOLPHIN and ProLogic 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. + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BytesDataDescription
$04-$07$12 $FF $F9 $17Track 1 BAM
$08-$0B$15 $FF $FF $FFTrack 2 BAM
$0C-$0F$15 $FF $FF $1FTrack 3 BAM
.........
$8C-$8F$11 $FF $FF $01Track 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. Any leftover bits that refer to +sectors that don't exist, like bits 21-23 in the above +example, are set to allocated. + +

+

+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. + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
123456
------------------------
17/017/1017/2017/117/110/52
(11/00)(11/0A)(11/14)(11/01)(11/0B)(0/34)
+ + + +

15.4.3 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. This can also have error +bytes attached like variant #1. + +

+

+3. The Commodore 128 allowed for "auto-boot" disks. With this, +t/s 1/0 holds a specific byte sequence which the computer +recognizes as boot code. + +

+

+Below is a small chart detailing the standard file sizes of +D64 images, 35 or 40 tracks, with or without error bytes. + +

+ + + + + + + + + + + + + + + + + + + + + +
Disk typeSize
35 track, no errors174848
35 track, 683 error bytes175531
40 track, no errors196608
40 track, 768 error bytes197376
+ +

+The following table (provided by Wolfgang Moser) outlines +the differences between the standard 1541 DOS and the +various "speeder" DOS's that exist. The 'header 7/8' +category is the 'fill bytes' as the end of the sector +header of a real 1541 disk. + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Disk formattracksheader 7/8Dos typeDiskdos vs. type
Original CBM DOS v2.635$0f $0f"2A"$41/'A'
*SpeedDOS+40$0f $0f"2A"$41/'A'
Professional DOS Initial35$0f $0f"2A"$41/'A'
Professional DOS Version 1/Prototype40$0f $0f"2A"$41/'A'
ProfDOS Release40$0f $0f"4A"$41/'A'
Dolphin-DOS 2.0/3.035$0f $0f"2A"$41/'A'
Dolphin-DOS 2.0/3.040$0d $0f"2A"$41/'A'
PrologicDOS 154135$0f $0f"2A"$41/'A'
PrologicDOS 154140$0f $0f"2P"$50/'P'
ProSpeed 1571 2.035$0f $0f"2A"$41/'A'
ProSpeed 1571 2.040$0f $0f"2P"$50/'P'
+ +

+*Note: There are also clones of SpeedDOS that exist, such as +RoloDOS and DigiDOS. Both are just a change of the DOS startup +string. + +

+

+The location of the extra BAM information in sector 18/0, for +40 track images, will be different depending on what standard +the disks have been formatted with. SPEED DOS stores them from +$C0 to $D3, DOLPHIN DOS stores them from $AC to $BF and +PrologicDOS stored them right after the existing BAM entries +from $90-A3. PrologicDOS also moves the disk label and ID +forward from the standard location of $90 to $A4. 64COPY and +Star Commander let you select from several different types of +extended disk formats you want to create/work with. + +

+

+All three of the speeder DOS's mentioned above don't alter the +standard sector interleave of 10 for files and 3 for +directories. The reason is that they use a memory cache +installed in the drive which reads the entire track in one +pass. This alleviates the need for custom interleave values. +They do seem to alter the algorithm that finds the next +available free sector so that the interleave value can deviate +from 10 under certain circumstances, but I don't know why they +would bother. + +

+

+Below is a HEX dump of a Speed DOS BAM sector. Note the +location of the extra BAM info from $C0-D3. + +

+ +
+       00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
+       -----------------------------------------------
+ 0070: 12 FF FF 03 12 FF FF 03 12 FF FF 03 11 FF FF 01
+ 0080: 11 FF FF 01 11 FF FF 01 11 FF FF 01 11 FF FF 01
+ 0090: A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0
+ 00A0: A0 A0 30 30 A0 32 41 A0 A0 A0 A0 00 00 00 00 00
+ 00B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00C0: 11 FF FF 01 11 FF FF 01 11 FF FF 01 11 FF FF 01
+ 00D0: 11 FF FF 01 00 00 00 00 00 00 00 00 00 00 00 00
+
+ +

+Below is a HEX dump of a Dolphin DOS BAM sector. Note +the location of the extra BAM info from $AC-BF. + +

+ +
+       00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
+       -----------------------------------------------
+ 0070: 12 FF FF 03 12 FF FF 03 12 FF FF 03 11 FF FF 01
+ 0080: 11 FF FF 01 11 FF FF 01 11 FF FF 01 11 FF FF 01
+ 0090: A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0
+ 00A0: A0 A0 30 30 A0 32 41 A0 A0 A0 A0 00 11 FF FF 01
+ 00B0: 11 FF FF 01 11 FF FF 01 11 FF FF 01 11 FF FF 01
+ 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
+
+ +

+Below is a HEX dump of a PrologicDOS BAM sector. Note +that the disk name and ID are now located at $A4 instead +of starting at $90. + +

+ +
+       00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
+       -----------------------------------------------
+ 0070: 12 FF FF 03 12 FF FF 03 12 FF FF 03 11 FF FF 01
+ 0080: 11 FF FF 01 11 FF FF 01 11 FF FF 01 11 FF FF 01
+ 0090: 11 FF FF 01 11 FF FF 01 11 FF FF 01 11 FF FF 01
+ 00A0: 11 FF FF 01 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0 A0
+ 00B0: A0 A0 A0 A0 A0 A0 30 30 A0 32 50 A0 A0 A0 A0 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
+
+ + + +

15.4.4 Error codes

+ +

+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, whether it's searching for any SYNC mark, any header +ID, any valid header, or reading a sector. + +

+

+These first errors are "seek" errors, where the disk +controller is simply reading headers and looking at +descriptor bytes, checksums, format ID's and reporting what +errors it sees. These errors do *not* necessarily apply to +the exact sector being looked for. This fact makes +duplication of these errors very unreliable. + +

+

+Code : $03 +Error : 21 +Type : Seek +Message : No SYNC sequence found. + +

+

+Each sector data block and header block are preceeded by +SYNC marks. If *no* sync sequence is found within 20 +milliseconds (only ~1/10 of a disk rotation!) then this +error is generated. This error used to mean the entire +track is bad, but it does not have to be the case. Only +a small area of the track needs to be without a SYNC +mark and this error will be generated. + +

+

+Converting this error to a D64 is very problematic +because it depends on where the physical head is on the +disk when a read attempt is made. If it is on valid +header/sectors then it won't occur. If it happens over +an area without SYNC marks, it will happen. + +

+

+Code : $02 +Error : 20 +Type : Seek +Message : Header descriptor byte not found (HEX $08, GCR $52) + +

+

+Each sector is preceeded by an 8-byte GCR header block, which +starts with the value $52 (GCR). If this value is not found +after 90 attempts, this error is generated. + +

+

+Basically, what a track has is SYNC marks, and possibly valid +data blocks, but no valid header descriptors. + +

+

+Code : $09 +Error : 27 +Type : Seek +Message : Checksum error in header block + +

+

+The 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. + +

+

+Code : $0B +Error : 29 +Type : Seek +Message : Disk sector ID mismatch + +

+

+The ID's from the header block of the currently read sector are +compared against the ones from the low-level header of 18/0. If +there is a mismatch, this error is generated. + +

+

+Code : $02 +Error : 20 +Type : Seek +Message : Header block not found + +

+

+This error can be reported again when searching for the correct +header block. An image of the header is built and searched for, +but not found after 90 read attempts. Note the difference from +the first occurance. The first one only searches for a valid +ID, not the whole header. + +

+

+Note that error 20 occurs twice during this phase. The first +time is when a header ID is being searched for, the second is +when the proper header pattern for the sector being searched +for is not found. + +

+

+From this point on, all the errors apply to the specific +sector you are looking for. If a read passed all the previous +checks, then we are at the sector being searched for. + +

+

+Note that the entire sector is read before these errors are +detected. Therefore the data, checksum and off bytes are +available. + +

+

+Code : $04 +Error : 22 +Type : Read +Message : Data descriptor byte not found (HEX $07, GCR $55) + +

+

+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. + +

+

+Code : $05 +Error : 23 +Type : Read +Message : 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. + +

+

+Code : $0F +Error : 74 +Type : Read +Message : Drive Not Ready (no disk in drive or no device 1) + +

+

+These errors only apply when writing to a disk. I don't see the +usefulness of having these as they cannot be present when only +*reading* a disk. + +

+

+Code : $06 +Error : 24 +Type : Write +Message : Write verify (on format) + +

+

+Code : $07 +Error : 25 +Type : Write +Message : 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. + +

+

+Code : $08 +Error : 26 +Type : Write +Message : Write protect on + +

+

+Self explanatory. Remove the write-protect tab, and try again. + +

+

+Code : $0A +Error : 28 +Type : Write +Message : Write error + +

+

+In actual fact, this error never occurs, but it is included +for completeness. + +

+

+This is not an error at all, but it gets reported when the +read of a sector is ok. + +

+

+Code : $01 +Error : 00 +Type : N/A +Message : No error. + +

+

+Self explanatory. No errors were detected in the reading +and decoding of the sector. + +

+

+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. + +

+ + +

15.5 The X64 disk image format

+ +

+(This section was contributed by Peter Schepers and slightly edited by +Marco van den Heuvel.) + +

+

+This file type, created by Teemu Rantanen, is used on the X64 +emulator (a UNIX-based emulator) which has been superceeded by +VICE. Both VICE and X64 support the X64 file standard, with +VICE also supporting the regular D64 and T64 files. + +

+

+X64 is not a specific type of file, but rather encompasses +*all* known C64 disk types (hard disk, floppies, etc). An X64 +is created by prepending a 64-byte header to an existing image +(1541, 1571, etc) and setting specific bytes which describe +what type of image follows. This header has undergone some +revision, and this description is based on the 1.02 version, +which was the last known at the time of writing. + +

+

+The most common X64 file you will see is the D64 variety, +typically 174912 bytes long (174848 for the D64 and 64 bytes +for the header, assuming no error bytes are appended). The +header layout (as used in 64COPY) is as follows: + +

+ +
+      00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
+      -----------------------------------------------
+0000: 43 15 41 64 01 02 01 23 00 00 00 00 00 00 00 00
+0010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+0020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+0040: XX XX XX <- standard C64 image starts here....
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BytesDescription
$00-$03This is the "Magic header" ($43 $15 $41 $64)
$04Header version major ($01)
$05Header version minor ($01, now its up to $02)
$06Device type represented
$07Maximum tracks in image (only in version 1.02 or greater) 1540/41/70: 35 1571: 35 1581: 80 (Logical single-sided disk)
$08Number of disk sides in image. This value must be $00 for all 1541 and 1581 formats. $00=No second side $01=Second side
$09Error data flag.
$0A-$1FUnused, set to $00
$20-$3EDisk image description (in ASCII or ISO Latin/1)
$3FAlways set to $00
$40-Standard C64 file begins here.
+ +

+The device types are: + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ValueDrive type
$001540 See note below...
$011541 (Default)
$021542
$031551
$041570
$051571
$061572
$081581
$102031 or 4031
$112040 or 3040
$122041
$184040
$208050
$218060
$228061
$30SFD-1001
$318250
$328280
+ +

+The first four bytes used for the device type at position $06 +($00 to $03) are functionally the same, and are compatible with +older version of X64 files. Some old X64 files might have $00 +for the device type (instead of $01), but it makes no real +difference. + +

+

+As most instances of X64 files will be strictly 1541 images, +bytes $08-$3F are set to zero, and some versions of the X64 +emulator don't use bytes $08-$3F. + +

+ + +

15.6 The D71 disk image format

+ +

+(This section was contributed by Peter Schepers and slightly edited by +Marco van den Heuvel.) + +

+

+Similar to the D64 (1541), the 1571 drive can operate in either +single-sided (1541 compatible) mode or double-sided (1571) mode. In +this section I will be dealing with the double-sided mode only. For +the breakdown of the single-sided mode, see the D64 section. + +

+

+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: + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TrackSec/trk# Sectors
1-17 (side 0)21357
18-24 (side 0)19133
25-30 (side 0)18108
31-35 (side 0)1785
36-52 (side 1)21357
53-59 (side 1)19133
60-65 (side 1)18108
66-70 (side 1)1785
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Track#Sect#SectorsInD71 Offset
1210$00000
22121$01500
32142$02A00
42163$03F00
52184$05400
621105$06900
721126$07E00
821147$09300
921168$0A800
1021189$0BD00
1121210$0D200
1221231$0E700
1321252$0FC00
1421273$11100
1521294$12600
1621315$13B00
1721336$15000
1819357$16500
1919376$17800
2019395$18B00
2119414$19E00
2219433$1B100
2319452$1C400
2419471$1D700
2518490$1EA00
2618508$1FC00
2718526$20E00
2818544$22000
2918562$23200
3018580$24400
3117598$25600
3217615$26700
3317632$27800
3417649$28900
3517666$29A00
3621683$2AB00
3721704$2C000
3821725$2D500
3921746$2EA00
4021767$2FF00
4121788$31400
4221809$32900
4321830$33E00
4421851$35300
4521872$36800
4621893$37D00
4721914$39200
4821935$3A700
4921956$3BC00
5021977$3D100
5121998$3E600
52211019$3FB00
53191040$41000
54191059$42300
55191078$43600
56191097$44900
57191116$45C00
58191135$46F00
59191154$48200
60181173$49500
61181191$4A700
62181209$4B900
63181227$4CB00
64181245$4DD00
65181263$4EF00
66171281$50100
67171298$51200
68171315$52300
69171332$53400
70171349$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
+    -----------------------------------------------
+00: 12 04 82 11 00 4A 45 54 20 53 45 54 20 57 49 4C
+10: 4C 59 A0 A0 A0 00 00 00 00 00 00 00 00 00 2B 00
+20: 00 00 82 0F 01 4A 53 57 20 31 A0 A0 A0 A0 A0 A0
+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
+50: 47 45 52 A0 A0 00 00 00 00 00 00 00 00 00 AE 00
+60: 00 00 82 15 0D 50 4F 54 54 59 20 50 49 47 45 4F
+70: 4E A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 A2 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
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BytesDescription
$00-$1FFirst directory entry
$20-$3FSecond dir entry
$40-$5FThird dir entry
$60-$7FFourth dir entry
$80-$9FFifth dir entry
$A0-$BFSixth dir entry
$C0-$DFSeventh dir entry
$E0-$FFEighth dir entry
+ +

+This is a breakdown of a standard directory entry: + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BytesDescription
$00-$01Track/Sector location of next directory sector ($00/$FF if its the last sector)
$02File type
$03-$04Track/sector location of first sector of file
$05-$1416 character filename (in PETASCII, padded with $A0)
$15-$16Track/Sector location of first side-sector block (REL file only)
$17REL file record length (REL file only, max. value 254)
$18-$1DUnused (except with GEOS disks)
$1E-$1FFile size in sectors, low/high byte order ($1E+$1F*256). The approx. filesize in bytes is <= #sectors * 254
+ +

+The file type field is used as follows: + +

+ + + + + + + + + + + + + + + + + + + + + + + + + +
BitsDescription
0-3The actual file type
4Unused
5Used only during SAVE-@ replacement
6Locked flag (Set produces ">" locked files)
7Closed flag (Not set produces "*", or "splat" files)
+ +

+The actual file type can be one of the following: + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BinaryDecimalFile type
00000DEL
00011SEQ
00102PRG
00113USR
01004REL
+ +

+Values 5-15 are illegal, but if used will produce very strange +results. The 1571 is inconsistent in how it treats these bits. +Some routines use all 4 bits, others ignore bit 3, resulting in +values from 0-7. + +

+

+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. + +

+ + +

15.6.1 Non-Standard & Long Directories

+ +

+Most Commodore floppy disk drives use a single dedicated +directory track where all filenames are stored. This limits the +number of files stored on a disk based on the number of sectors +on the directory track. There are some disk images that contain +more files than would normally be allowed. This requires +extending the directory off the default directory track by +changing the last directory sector pointer to a new track, +allocating the new sectors in the BAM, and manually placing (or +moving existing) file entries there. The directory of an +extended disk can be read and the files that reside there can be +loaded without problems on a real drive. However, this is still +a very dangerous practice as writing to the extended portion of +the directory will cause directory corruption in the non- +extended part. Many of the floppy drives core ROM routines +ignore the track value that the directory is on and assume the +default directory track for operations. + +

+

+To explain: assume that the directory has been extended from +track 18 to track 19/6 and that the directory is full except +for a few slots on 19/6. When saving a new file, the drive DOS +will find an empty file slot at 19/6 offset $40 and correctly +write the filename and a few other things into this slot. When +the file is done being saved the final file information will +be written to 18/6 offset $40 instead of 19/6 causing some +directory corruption to the entry at 18/6. Also, the BAM +entries for the sectors occupied by the new file will not be +saved and the new file will be left as a SPLAT (*) file. + +

+

+Attempts to validate the disk will result in those files +residing off the directory track to not be allocated in the +BAM, and could also send the drive into an endless loop. The +default directory track is assumed for all sector reads when +validating so if the directory goes to 19/6, then the validate +code will read 18/6 instead. If 18/6 is part of the normal +directory chain then the validate routine will loop endlessly. + +

+ + +

15.6.2 Bam layout 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
+    -----------------------------------------------
+00: 12 01 41 80 12 FF F9 17 15 FF FF 1F 15 FF FF 1F
+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
+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
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BytesDescription
$00-$01Track/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)
$02Disk DOS version type (see note below) $41 ('A') = 1541
$03Double-sided flag $00 - Single sided disk $80 - Double sided disk
$04-8FBAM entries for each track, in groups of four bytes per track, starting on track 1.
$90-$9FDisk Name (padded with $A0)
$A0-$A1Filled with $A0
$A2-$A3Disk ID
$A4Usually $A0
$A5-$A6DOS type, usually "2A"
$A7-$AAFilled with $A0
$AB-$DCNot used ($00's)
$DD-$FFFree 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
+    -----------------------------------------------
+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. + +

+ + +

15.7 The D81 disk image format

+ +

+(This section was contributed by Peter Schepers and slightly edited by +Marco van den Heuvel.) + +

+

+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 section. +One important difference from the D64 and D71 is all the sector +interleaves are 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#SectorsInD81 Offset
1400$00000
24040$02800
34080$05000
440120$07800
540160$0A000
640200$0C800
740240$0F000
840280$11800
940320$14000
1040360$16800
1140400$19000
1240440$1B800
1340480$1E000
1440520$20800
1540560$23000
1640600$25800
1740640$28000
1840680$2A800
1940720$2D000
2040760$2F800
2140800$32000
2240840$34800
2340880$37000
2440920$39800
2540960$3C000
26401000$3E800
27401040$41000
28401080$43800
29401120$46000
30401160$48800
31401200$4B000
32401240$4D800
33401280$50000
34401320$52800
35401360$55000
36401400$57800
37401440$5A000
38401480$5C800
39401520$5F000
40401560$61800
41401600$64000
42401640$66800
43401680$69000
44401720$6B800
45401760$6E000
46401800$70800
47401840$73000
48401880$75800
49401920$78000
50401960$7A800
51402000$7D000
52402040$7F800
53402080$82000
54402120$84800
55402160$87000
56402200$89800
57402240$8C000
58402280$8E800
59402320$91000
60402360$93800
61402400$96000
62402440$98800
63402480$9B000
64402520$9D800
65402560$A0000
66402600$A2800
67402640$A5000
68402680$A7800
69402720$AA000
70402760$AC800
71402800$AF000
72402840$B1800
73402880$B4000
74402920$B6800
75402960$B9000
76403000$BB800
77403040$BE000
78403080$C0800
79403120$C3000
80403160$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
+    -----------------------------------------------
+00: 28 03 44 00 31 35 38 31 20 55 54 49 4C 49 54 59
+10: 20 56 30 31 A0 A0 47 42 A0 33 44 A0 A0 00 00 00
+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
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BytesDescription
$00-$01Track/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)
$02Disk DOS version type (see note below) $44 ('D')=1581
$03$00
$04-$1316 character Disk Name (padded with $A0)
$14-$15$A0
$16-$17Disk ID
$18$A0
$19DOS Version ("3")
$1ADisk version ("D")
$1B-$1C$A0
$1D-$FFUnused (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) + +

+ + + + + + + + + + + + + + + + + +
BytesDescription
$AB-$ACBorder sector (GEOS only, else set to $00)
$AD-$BCGEOS ID string ("geos FORMAT V1.x" GEOS only, else $00)
$BD-$FFUnused (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 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
+    -----------------------------------------------
+00: 28 04 81 2B 00 53 43 52 45 45 4E 20 20 33 A0 A0
+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
+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
+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
+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
+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
+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
+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
+F0: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 05 00
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BytesDescription
$00-$1FFirst directory entry
$20-$3FSecond dir entry
$40-$5FThird dir entry
$60-$7FFourth dir entry
$80-$9FFifth dir entry
$A0-$BFSixth dir entry
$C0-$DFSeventh dir entry
$E0-$FFEighth dir entry
+ +

+This is a breakdown of a standard directory entry: + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BytesDescription
$00-$01Track/Sector location of next directory sector
$02File type
$03-$04Track/sector location of first sector of file or partition
$05-$1416 character filename (in PETASCII, padded with $A0)
$15-$16Track/Sector location of first SUPER SIDE SECTOR block (REL file only)
$17REL file record length (REL file only)
$18-$1BUnused (except with GEOS disks)
$1C-$1D(Used during an SAVE or OPEN, holds the new t/s link)
$1E-$1FFile or partition size in sectors, low/high byte order ($1E+$1F*256). The approx. file size in bytes is <= #sectors * 254
+ +

+The file type field is used as follows: + +

+ + + + + + + + + + + + + + + + + + + + + + + + + +
BitsDescription
0-3The actual file type
4Unused
5Used only during SAVE-@ replacement
6Locked flag (Set produces ">" locked files)
7Closed flag (Not set produces "*", or "splat" files)
+ +

+The actual file type can be one of the following: + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BinaryDecimalFile type
00000DEL
00011SEQ
00102PRG
00113USR
01004REL
01015CBM (partition or sub-directory)
+ +

+Values 6-15 are illegal, but if used will produce very strange results. + +

+ + +

15.7.1 Non-Standard & Long Directories

+ +

+Most Commdore floppy disk drives use a single dedicated directory +track where all filenames are stored. This limits the number of +files stored on a disk based on the number of sectors on the +directory track. There are some disk images that contain more +files than would normally be allowed. This requires extending the +directory off the default directory track by changing the last +directory sector pointer to a new track, allocating the new +sectors in the BAM, and manually placing (or moving existing) +file entries there. The directory of an extended disk can be read +and the files that reside there can be loaded without problems on +a real drive. However, this is still a very dangerous practice as +writing to the extended portion of the directory will cause +directory corruption in the non-extended part. Many of the floppy +drives core ROM routines ignore the track value that the +directory is on and assume the default directory track for +operations. + +

+ + +

15.7.2 BAM layout

+ +

+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
+    -----------------------------------------------
+00: 28 02 44 BB 47 42 C0 00 00 00 00 00 00 00 00 00
+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
+$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
+    -----------------------------------------------
+00: 00 FF 44 BB 47 42 C0 00 00 00 00 00 00 00 00 00
+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. + +

+ + +

15.7.3 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
+ 10: 49 4E 46 4F A0 27 02 FE 00 00 00 00 00 00 D2 0B
+
+ +

+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
+ 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.
+
+ + + +

15.7.4 1581 Partitions and Sub-directories

+ +

+At the beginning of this section 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
+ 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 as 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
+ 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
+ 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. + +

+ + +

15.7.5 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
+
+ + + +

15.8 The D80 disk image format

+ +

+(This section was contributed by Peter Schepers and slightly edited by +Marco van den Heuvel.) + +

+

+This is a sector-for-sector copy of an 8050 floppy disk. The +file size for an 8050 image is 533248 bytes. It is comprised +of 256-byte sectors arranged across 77 tracks, with a +varying number of sectors per track for a total of 2083 +sectors. Track counting starts at 1 (not 0) and sector +counting starts at 0 (not 1), therefore a track with 29 +sectors will go from 0 to 28. + +

+

+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 77 being on the inside of +the disk (closest to the inner 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 D80. 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 RangeSectors/track# Sectors
1-39291131
40-5327378
54-6425275
65-7723299
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Track#Sect#SectorsInD8x Offset
1290$00000
22929$01D00
32958$03A00
42987$05700
529116$07400
629145$09100
729174$0AE00
829203$0CB00
929232$0E800
1029261$10500
1129290$12200
1229319$13F00
1329348$15C00
1429377$17900
1529406$19600
1629435$1B300
1729464$1D000
1829493$1ED00
1929522$20A00
2029551$22700
2129580$24400
2229609$26100
2329638$27E00
2429667$29B00
2529696$2B800
2629725$2D500
2729754$2F200
2829783$30F00
2929812$32C00
3029841$34900
3129870$36600
3229899$38300
3329928$3A000
3429957$3BD00
3529986$3DA00
36291015$3F700
37291044$41400
38291073$43100
39291102$44E00
40271131$46B00
41271158$48600
42271185$4A100
43271212$4BC00
44271239$4D700
45271266$4F200
46271293$50D00
47271320$52800
48271347$54300
49271374$55E00
50271401$57900
51271428$59400
52271455$5AF00
53271482$5CA00
54251509$5E500
55251534$5FE00
56251559$61700
57251584$63000
58251609$64900
59251634$66200
60251659$67B00
61251684$69400
62251709$6AD00
63251734$6C600
64251759$6DF00
65231784$6F800
66231807$70F00
67231830$72600
68231853$73D00
69231876$75400
70231899$76B00
71231922$78200
72231945$79900
73231968$7B000
74231991$7C700
75232014$7DE00
76232037$7F500
77232060$80C00
+ +

+The BAM (Block Availability Map) is on track 38. The D80 is only +77 tracks and so the BAM is contained on 38/0 and 38/3. The BAM +interleave is 3. + +

+

+The directory is on track 39, with 39/0 contains the header +(DOS type, disk name, disk ID's) and sectors 1-28 contain the +directory entries. Both files and the directory use an +interleave of 1. Since the directory is only 28 sectors large +(29 less one for the header), and each sector can contain only +8 entries (32 bytes per entry), the maximum number of directory +entries is 28 * 8 = 224. The first directory sector is always +39/1. It then follows a chain structure using a sector +interleave of 1 making the links go 39/1, 39/2, 39/3 etc. + +

+

+When reading a disk, you start with 39/0 (disk label/ID) which +points to 38/0 (BAM0), 38/3 (BAM1), and finally to 39/1 (first +dir entry sector). When writing a file to a blank disk, it will +start at 38/1 because 38/0 is already allocated. + +

+

+Below is a dump of the header sector 39/0: + +

+ +
+    00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
+    -----------------------------------------------
+00: 26 00 43 00 00 00 73 61 6D 70 6C 65 20 64 38 30
+10: A0 A0 A0 A0 A0 A0 A0 A0 65 72 A0 32 43 A0 A0 A0
+20: A0 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
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BytesDescription
$00-$01T/S pointer to first BAM sector (38/0)
$02$43 'C' is for DOS format version
$03Reserved
$04-$05Unused
$06-$16Disk name, padded with 0xA0 ("sample d80")
$170xA0
$18-$19Disk ID bytes "er"
$1A0xA0
$1B-$1CDOS version bytes "2C"
$1D-$200xA0
$21-$FFUnused
+ +

+Below is a dump of the first directory sector, 39/1 + +

+ +
+    00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
+    -----------------------------------------------
+00: 27 02 82 26 01 54 45 53 54 A0 A0 A0 A0 A0 A0 A0
+10: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 01 00
+20: 00 00 82 26 02 54 45 53 54 32 A0 A0 A0 A0 A0 A0
+30: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 01 00
+40: 00 00 82 26 04 54 45 53 54 33 A0 A0 A0 A0 A0 A0
+50: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 05 00
+60: 00 00 82 26 0B 54 45 53 54 34 A0 A0 A0 A0 A0 A0
+70: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 09 00
+80: 00 00 82 26 14 54 45 53 54 35 A0 A0 A0 A0 A0 A0
+90: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 0C 00
+A0: 00 00 82 28 00 54 45 53 54 36 A0 A0 A0 A0 A0 A0
+B0: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 01 00
+C0: 00 00 82 28 01 54 45 53 54 37 A0 A0 A0 A0 A0 A0
+D0: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 01 00
+E0: 00 00 82 28 02 54 45 53 54 38 A0 A0 A0 A0 A0 A0
+F0: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 01 00
+
+ +

+The first two bytes of the directory sector ($27/$02) indicate +the location of the next track/sector of the directory (39/2). +If the track is set to $00, then it is the last sector of the +directory. + +

+

+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: + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BytesDescription
$00-$1FFirst directory entry
$20-$3FSecond dir entry
$40-$5FThird dir entry
$60-$7FFourth dir entry
$80-$9FFifth dir entry
$A0-$BFSixth dir entry
$C0-$DFSeventh dir entry
$E0-$FFEighth dir entry
+ +

+This is a breakdown of a standard directory entry: + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BytesDescription
$00-$01Track/Sector location of next directory sector ($00 $00 if not the first entry in the sector)
$02File type
$03-$04Track/sector location of first sector of file
$05-$1416 character filename (in PETASCII, padded with $A0)
$15-$16Track/Sector location of first side-sector block (REL file only)
$17REL file record length (REL file only, max. value 254)
$18-$1DUnused
$1E-$1FFile size in sectors, low/high byte order ($1E+$1F*256). The approx. filesize in bytes is <= #sectors * 254
+ +

+The file type field is used as follows: + +

+ + + + + + + + + + + + + + + + + + + + + + + + + +
BitsDescription
0-3The actual file type
4Unused
5Used only during SAVE-@ replacement
6Locked flag (Set produces ">" locked files)
7Closed flag (Not set produces "*", or "splat" files)
+ +

+The actual file type can be one of the following: + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BinaryDecimalFile type
00000DEL
00011SEQ
00102PRG
00113USR
01004REL
+ +

+Values 5-15 are illegal, but if used will produce very strange results. + +

+ + +

15.8.1 Non-Standard & Long Directories

+ +

+Most Commdore floppy disk drives use a single dedicated +directory track where all filenames are stored. This limits the +number of files stored on a disk based on the number of sectors +on the directory track. There are some disk images that contain +more files than would normally be allowed. This requires +extending the directory off the default directory track by +changing the last directory sector pointer to a new track, +allocating the new sectors in the BAM, and manually placing (or +moving existing) file entries there. The directory of an +extended disk can be read and the files that reside there can +be loaded without problems on a real drive. However, this is +still a very dangerous practice as writing to the extended +portion of the directory will cause directory corruption in the +non-extended part. Many of the floppy drives core ROM routines +ignore the track value that the directory is on and assume the +default directory track for operations. + +

+ + +

15.8.2 BAM layout

+ +

+The BAM only occupies up to four sectors on track 38, so the +rest of the track is empty and is available for file storage. +Below is a dump of the first BAM block, 38/0. A D80 will only +contain two BAM sectors, 38/0 and 38/3. Each entry takes 5 +bytes, 1 for the free count on that track, and 4 for the BAM +bits. + +

+ +
+    00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
+    -----------------------------------------------
+00: 26 03 43 00 01 33 1D FF FF FF 1F 1D FF FF FF 1F
+10: 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D
+20: FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF
+30: FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF
+40: FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF
+50: 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F
+60: 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D
+70: FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF
+80: FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF
+90: FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF
+A0: 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F
+B0: 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1B
+C0: F6 FF FF 1F 1B FC FF FF 1F 1B FF FF FF 07 1B FF
+D0: FF FF 07 1B FF FF FF 07 1B FF FF FF 07 1B FF FF
+E0: FF 07 1B FF FF FF 07 1B FF FF FF 07 1B FF FF FF
+F0: 07 1B FF FF FF 07 1B FF FF FF 07 1B FF FF FF 07
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BytesDescription
$00-$01T/S pointer to second BAM sector (38/3)
$02DOS version byte (0x43='C')
$03Reserved
$04Lowest track covered by this BAM (0x01=1)
$05Highest+1 track covered by this BAM (0x33=51)
$06-$0ABAM for track 1. The first byte shows the "blocks free" for this track, the remaining 4 show the BAM for the track.
$0B-$0FBAM for track 2
......
$FB-$FFBAM for track 50
+ +

+Being bit-based, the BAM entries need some explanation. The +first track entry in the above BAM sector is at offset 06, +"1D FF FF FF 1F". The first number is how many blocks are +free on this track ($1D=29) and the remainder is the bit +representation of the usage map for the track. These +entries must be viewed in binary to make any sense. First +convert the values to binary: + +

+ +
+ FF=11111111, FF=11111111, FF=11111111, 1F=00011111
+
+ +

+In order to make any sense from the binary notation, flip the +bits around. + +

+ +
+            111111 11112222 222222
+ 01234567 89012345 67890123 456789...
+ -------------------------- ---------
+ 11111111 11111111 11111111 11111000
+ ^                              ^
+ sector 0                   sector 28
+
+ +

+Since we are on the first track, we have 29 sectors, and only +use up to the bit 28 position. If a bit is on (1), the sector +is free. Therefore, track 1 is clean, all sectors are free. +Any leftover bits that refer to sectors that don't exist, +like bits 29-31 in the above example, are set to allocated. + +

+

+Second BAM block 38/3. + +

+ +
+    00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
+    -----------------------------------------------
+00: 27 01 43 00 33 4E 1B FF FF FF 07 1B FF FF FF 07
+10: 1B FF FF FF 07 19 FF FF FF 01 19 FF FF FF 01 19
+20: FF FF FF 01 19 FF FF FF 01 19 FF FF FF 01 19 FF
+30: FF FF 01 19 FF FF FF 01 19 FF FF FF 01 19 FF FF
+40: FF 01 19 FF FF FF 01 19 FF FF FF 01 17 FF FF 7F
+50: 00 17 FF FF 7F 00 17 FF FF 7F 00 17 FF FF 7F 00
+60: 17 FF FF 7F 00 17 FF FF 7F 00 17 FF FF 7F 00 17
+70: FF FF 7F 00 17 FF FF 7F 00 17 FF FF 7F 00 17 FF
+80: FF 7F 00 17 FF FF 7F 00 17 FF FF 7F 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
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BytesDescription
$00-$01T/S pointer to second BAM sector (39/1)
$02DOS version byte (0x43='C')
$03Reserved
$04Lowest track covered by this BAM (0x33=51)
$05Highest+1 track covered by this BAM (0x43=78)
$06-$0ABAM for track 51. The first byte shows the "blocks free" for this track, the remaining 4 show the BAM for the track.
$0B-$0FBAM for track 52
......
$88-$8CBAM for track 77
$8D-$FFNot used
+ + + +

15.9 The D82 disk image format

+ +

+(This section was contributed by Peter Schepers and slightly edited by +Marco van den Heuvel.) + +

+

+This is a sector-for-sector copy of an 8250 floppy disk. The file +size for an 8250 image is 1066496 bytes. It is comprised of +256-byte sectors arranged across 154 tracks, with a varying +number of sectors per track for a total of 4166 sectors. Track +counting starts at 1 (not 0) and sector counting starts at 0 +(not 1), therefore a track with 29 sectors will go from 0 to 28. + +

+

+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 77 being on the inside of the disk +(closest to the inner 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 +D82. 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 RangeSectors/track# Sectors
1-39291131
40-5327378
55-6425275
65-7723299
78-116291131
117-13027378
131-14125275
142-15423299
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Track#Sect#SectorsInD82 Offset
1290$000000
22929$001D00
32958$003A00
42987$005700
529116$007400
629145$009100
729174$00AE00
829203$00CB00
929232$00E800
1029261$010500
1129290$012200
1229319$013F00
1329348$015C00
1429377$017900
1529406$019600
1629435$01B300
1729464$01D000
1829493$01ED00
1929522$020A00
2029551$022700
2129580$024400
2229609$026100
2329638$027E00
2429667$029B00
2529696$02B800
2629725$02D500
2729754$02F200
2829783$030F00
2929812$032C00
3029841$034900
3129870$036600
3229899$038300
3329928$03A000
3429957$03BD00
3529986$03DA00
36291015$03F700
37291044$041400
38291073$043100
39291102$044E00
40271131$046B00
41271158$048600
42271185$04A100
43271212$04BC00
44271239$04D700
45271266$04F200
46271293$050D00
47271320$052800
48271347$054300
49271374$055E00
50271401$057900
51271428$059400
52271455$05AF00
53271482$05CA00
54251509$05E500
55251534$05FE00
56251559$061700
57251584$063000
58251609$064900
59251634$066200
60251659$067B00
61251684$069400
62251709$06AD00
63251734$06C600
64251759$06DF00
65231784$06F800
66231807$070F00
67231830$072600
68231853$073D00
69231876$075400
70231899$076B00
71231922$078200
72231945$079900
73231968$07B000
74231991$07C700
75232014$07DE00
76232037$07F500
77232060$080C00
78292083$082300
79292112$084000
80292141$085D00
81292170$087A00
82292199$089700
83292228$08B400
84292257$08D100
85292286$08EE00
86292315$090600
87292344$092800
88292373$094500
89292402$096200
90292431$097F00
91292460$099C00
92292489$09B900
93292518$09D600
94292547$09F300
95292576$0A1000
96292605$0A2D00
97292634$0A4A00
98292663$0A6700
99292692$0A8400
100292721$0AA100
101292750$0ABE00
102292779$0ADB00
103292808$0AF800
104292837$0B1500
105292866$0B3200
106292895$0B4F00
107292924$0B6C00
108292953$0B8900
109292982$0BA600
110293011$0BC300
111293040$0BE000
112293069$0BFD00
113293098$0C1A00
114293137$0C3700
115293156$0C5400
116293185$0C7100
117273214$0C8E00
118273241$0CA900
119273268$0CC400
120273295$0CDF00
121273322$0CFA00
122273349$0D1500
123273376$0D3000
124273403$0D4B00
125273430$0D6600
126273457$0D8100
127273484$0D9C00
128273511$0DB700
129273538$0DD200
130273565$0DED00
131253592$0E0800
132253617$0E2100
133253642$0E3A00
134253667$0E5300
135253692$0E6C00
136253717$0E8500
137253742$0E9E00
138253767$0EB700
139253792$0ED000
140253817$0EE900
141253842$0F0200
142233867$0F1B00
143233890$0F3200
144233913$0F4900
145233936$0F6000
146233959$0F7700
147233982$0F8E00
148234005$0FA500
149234028$0FBC00
150234051$0FD300
151234074$0FEA00
152234097$100100
153234120$101800
154234143$102F00
+ +

+The BAM (Block Availability Map) is on track 38. The D82 is 154 +tracks and so the BAM is contained on 38/0, 38/3, 38/6 and 38/9. +The BAM interleave is 3. + +

+

+The directory is on track 39, with 39/0 contains the header (DOS +type, disk name, disk ID's) and sectors 1-28 contain the +directory entries. Both files and the directory use an +interleave of 1. Since the directory is only 28 sectors large +(29 less one for the header), and each sector can contain only 8 +entries (32 bytes per entry), the maximum number of directory +entries is 28 * 8 = 224. The first directory sector is always +39/1. It then follows a chain structure using a sector +interleave of 1 making the links go 39/1, 39/2, 39/3 etc. + +

+

+When reading a disk, you start with 39/0 (disk label/ID) which +points to 38/0 (BAM0), 38/3 (BAM1), 38/6 (BAM2), 38/9 (BAM3, and +finally to 39/1 (first dir entry sector). When writing a file to +a blank disk, it will start at 38/1 because 38/0 is already +allocated. + +

+

+Below is a dump of the header sector 39/0: + +

+ +
+    00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
+    -----------------------------------------------
+00: 26 00 43 00 00 00 73 61 6D 70 6C 65 20 64 38 30
+10: A0 A0 A0 A0 A0 A0 A0 A0 65 72 A0 32 43 A0 A0 A0
+20: A0 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
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BytesDescription
$00-$01T/S pointer to first BAM sector (38/0)
$02$43 'C' is for DOS format version
$03Reserved
$04-$05Unused
$06-$16Disk name, padded with 0xA0 ("sample d82")
$170xA0
$18-$19Disk ID bytes "er"
$1A0xA0
$1B-$1CDOS version bytes "2C"
$1D-$200xA0
$21-$FFUnused
+ +

+Below is a dump of the first directory sector, 39/1 + +

+ +
+    00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
+    -----------------------------------------------
+00: 27 02 82 26 01 54 45 53 54 A0 A0 A0 A0 A0 A0 A0
+10: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 01 00
+20: 00 00 82 26 02 54 45 53 54 32 A0 A0 A0 A0 A0 A0
+30: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 01 00
+40: 00 00 82 26 04 54 45 53 54 33 A0 A0 A0 A0 A0 A0
+50: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 05 00
+60: 00 00 82 26 0B 54 45 53 54 34 A0 A0 A0 A0 A0 A0
+70: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 09 00
+80: 00 00 82 26 14 54 45 53 54 35 A0 A0 A0 A0 A0 A0
+90: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 0C 00
+A0: 00 00 82 28 00 54 45 53 54 36 A0 A0 A0 A0 A0 A0
+B0: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 01 00
+C0: 00 00 82 28 01 54 45 53 54 37 A0 A0 A0 A0 A0 A0
+D0: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 01 00
+E0: 00 00 82 28 02 54 45 53 54 38 A0 A0 A0 A0 A0 A0
+F0: A0 A0 A0 A0 A0 00 00 00 00 00 00 00 00 00 01 00
+
+ +

+The first two bytes of the directory sector ($27/$02) indicate +the location of the next track/sector of the directory (39/2). +If the track is set to $00, then it is the last sector of the +directory. + +

+

+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: + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BytesDescription
$00-$1FFirst directory entry
$20-$3FSecond dir entry
$40-$5FThird dir entry
$60-$7FFourth dir entry
$80-$9FFifth dir entry
$A0-$BFSixth dir entry
$C0-$DFSeventh dir entry
$E0-$FFEighth dir entry
+ +

+This is a breakdown of a standard directory entry: + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BytesDescription
$00-$01Track/Sector location of next directory sector ($00 $00 if not the first entry in the sector)
$02File type
$03-$04Track/sector location of first sector of file
$05-$1416 character filename (in PETASCII, padded with $A0)
$15-$16Track/Sector location of first side-sector block (REL file only)
$17REL file record length (REL file only, max. value 254)
$18-$1DUnused
$1E-$1FFile size in sectors, low/high byte order ($1E+$1F*256). The approx. filesize in bytes is <= #sectors * 254
+ +

+The file type field is used as follows: + +

+ + + + + + + + + + + + + + + + + + + + + + + + + +
BitsDescription
0-3The actual file type
4Unused
5Used only during SAVE-@ replacement
6Locked flag (Set produces ">" locked files)
7Closed flag (Not set produces "*", or "splat" files)
+ +

+The actual file type can be one of the following: + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BinaryDecimalFile type
00000DEL
00011SEQ
00102PRG
00113USR
01004REL
+ +

+Values 5-15 are illegal, but if used will produce very strange results. + +

+ + +

15.9.1 Non-Standard & Long Directories

+ +

+Most Commdore floppy disk drives use a single dedicated +directory track where all filenames are stored. This limits the +number of files stored on a disk based on the number of sectors +on the directory track. There are some disk images that contain +more files than would normally be allowed. This requires +extending the directory off the default directory track by +changing the last directory sector pointer to a new track, +allocating the new sectors in the BAM, and manually placing (or +moving existing) file entries there. The directory of an +extended disk can be read and the files that reside there can +be loaded without problems on a real drive. However, this is +still a very dangerous practice as writing to the extended +portion of the directory will cause directory corruption in the +non-extended part. Many of the floppy drives core ROM routines +ignore the track value that the directory is on and assume the +default directory track for operations. + +

+ + +

15.9.2 BAM layout

+ +

+The BAM only occupies up to four sectors on track 38, so the +rest of the track is empty and is available for file storage. +Below is a dump of the first BAM block, 38/0. A D82 will +contain four BAM sectors, 38/0, 38/3, 38/6 and 38/9. Each +entry takes 5 bytes, 1 for the free count on that track, and +4 for the BAM bits. + +

+ +
+    00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
+    -----------------------------------------------
+00: 26 03 43 00 01 33 1D FF FF FF 1F 1D FF FF FF 1F
+10: 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D
+20: FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF
+30: FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF
+40: FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF
+50: 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F
+60: 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D
+70: FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF
+80: FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF
+90: FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF
+A0: 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F
+B0: 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1B
+C0: F6 FF FF 1F 1B FC FF FF 1F 1B FF FF FF 07 1B FF
+D0: FF FF 07 1B FF FF FF 07 1B FF FF FF 07 1B FF FF
+E0: FF 07 1B FF FF FF 07 1B FF FF FF 07 1B FF FF FF
+F0: 07 1B FF FF FF 07 1B FF FF FF 07 1B FF FF FF 07
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BytesDescription
$00-$01T/S pointer to second BAM sector (38/3)
$02DOS version byte (0x43='C')
$03Reserved
$04Lowest track covered by this BAM (0x01=1)
$05Highest+1 track covered by this BAM (0x33=51)
$06-$0ABAM for track 1. The first byte shows the "blocks free" for this track, the remaining 4 show the BAM for the track.
$0B-$0FBAM for track 2
......
$FB-$FFBAM for track 50
+ +

+Being bit-based, the BAM entries need some explanation. The +first track entry in the above BAM sector is at offset 06, +"1D FF FF FF 1F". The first number is how many blocks are free +on this track ($1D=29) and the remainder is the bit +representation of the usage map for the track. These entries +must be viewed in binary to make any sense. First convert the +values to binary: + +

+ +
+ FF=11111111, FF=11111111, FF=11111111, 1F=00011111
+
+ +

+In order to make any sense from the binary notation, flip the +bits around. + +

+ +
+            111111 11112222 222222
+ 01234567 89012345 67890123 456789...
+ -------------------------- ---------
+ 11111111 11111111 11111111 11111000
+ ^                              ^
+ sector 0                  sector 28
+
+ +

+Since we are on the first track, we have 29 sectors, and only +use up to the bit 28 position. If a bit is on (1), the sector is +free. Therefore, track 1 is clean, all sectors are free. Any +leftover bits that refer to sectors that don't exist, like bits +29-31 in the above example, are set to allocated. + +

+

+Second BAM block 38/3 + +

+ +
+    00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
+    -----------------------------------------------
+00: 26 06 43 00 33 65 1B FF FF FF 07 1B FF FF FF 07
+10: 1B FF FF FF 07 19 FF FF FF 01 19 FF FF FF 01 19
+20: FF FF FF 01 19 FF FF FF 01 19 FF FF FF 01 19 FF
+30: FF FF 01 19 FF FF FF 01 19 FF FF FF 01 19 FF FF
+40: FF 01 19 FF FF FF 01 19 FF FF FF 01 17 FF FF 7F
+50: 00 17 FF FF 7F 00 17 FF FF 7F 00 17 FF FF 7F 00
+60: 17 FF FF 7F 00 17 FF FF 7F 00 17 FF FF 7F 00 17
+70: FF FF 7F 00 17 FF FF 7F 00 17 FF FF 7F 00 17 FF
+80: FF 7F 00 17 FF FF 7F 00 17 FF FF 7F 00 1D FF FF
+90: FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF
+A0: 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F
+B0: 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D
+C0: FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF
+D0: FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF
+E0: FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF
+F0: 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BytesDescription
$00-$01T/S pointer to third BAM sector (38/6)
$02DOS version byte (0x43='C')
$03Reserved
$04Lowest track covered by this BAM (0x33=51)
$05Highest+1 track covered by this BAM (0x65=101)
$06-$0ABAM for track 51. The first byte shows the "blocks free" for this track, the remaining 4 show the BAM for the track.
$0B-$0FBAM for track 52
......
$FB-$FFBAM for track 100
+ +

+Third BAM block 38/6 + +

+ +
+    00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
+    -----------------------------------------------
+00: 26 09 43 00 65 97 1D FF FF FF 1F 1D FF FF FF 1F
+10: 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D
+20: FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF
+30: FF FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF
+40: FF 1F 1D FF FF FF 1F 1D FF FF FF 1F 1D FF FF FF
+50: 1F 1D FF FF FF 1F 1B FF FF FF 07 1B FF FF FF 07
+60: 1B FF FF FF 07 1B FF FF FF 07 1B FF FF FF 07 1B
+70: FF FF FF 07 1B FF FF FF 07 1B FF FF FF 07 1B FF
+80: FF FF 07 1B FF FF FF 07 1B FF FF FF 07 1B FF FF
+90: FF 07 1B FF FF FF 07 1B FF FF FF 07 19 FF FF FF
+A0: 01 19 FF FF FF 01 19 FF FF FF 01 19 FF FF FF 01
+B0: 19 FF FF FF 01 19 FF FF FF 01 19 FF FF FF 01 19
+C0: FF FF FF 01 19 FF FF FF 01 19 FF FF FF 01 19 FF
+D0: FF FF 01 17 FF FF 7F 00 17 FF FF 7F 00 17 FF FF
+E0: 7F 00 17 FF FF 7F 00 17 FF FF 7F 00 17 FF FF 7F
+F0: 00 17 FF FF 7F 00 17 FF FF 7F 00 17 FF FF 7F 00
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BytesDescription
$00-$01T/S pointer to fourth BAM sector (38/9)
$02DOS version byte (0x43='C')
$03Reserved
$04Lowest track covered by this BAM (0x65=101)
$05Highest+1 track covered by this BAM (0x97=151)
$06-$0ABAM for track 101. The first byte shows the "blocks free" for this track, the remaining 4 show the BAM for the track.
$0B-$0FBAM for track 102
......
$FB-$FFBAM for track 150
+ +

+Fourth BAM block 38/9 + +

+ +
+    00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
+    -----------------------------------------------
+00: 27 01 43 00 97 9B 17 FF FF 7F 00 17 FF FF 7F 00
+10: 17 FF FF 7F 00 17 FF FF 7F 00 00 00 00 00 00 00
+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
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BytesDescription
$00-$01T/S pointer to first directory sector (39/1)
$02DOS version byte (0x43='C')
$03Reserved
$04Lowest track covered by this BAM (0x97=151)
$05Highest+1 track covered by this BAM (0x9B=155)
$06-$0ABAM for track 151. The first byte shows the "blocks free" for this track, the remaining 4 show the BAM for the track.
$0B-$0FBAM for track 152
......
$15-$19BAM for track 154
$1A-$FFNot used
+ + + +

15.10 The P00 image format

+ +

+(This section was contributed by Peter Schepers and slightly edited by +Marco van den Heuvel.) + +

+

+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
+      -----------------------------------------------
+0000: 43 36 34 46 69 6C 65 00 43 52 49 53 49 53 20 4D
+0010: 4F 55 4E 54 41 49 4E 00 00 00
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BytesDescription
$00-$06ASCII string "C64File"
$07Always $00
$08-$17Filename in PETASCII, padded with $00 (not $A0, like a D64)
$18Always $00
$19REL 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 (x01, x02, x03, up to x99). 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 +containers 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. + +

+ + + +

15.11 The CRT cartridge image format

+ +

+This chapter is based on CRT.txt (rev1.14) compiled by Peter Schepers, with +additional contributions from Per Hakan Sundell, Markus Brenner, +Marco Van Den Heuvel, Groepaz. + +

+

+ 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 various ROM cartridges that exist, such as Action Replay, the +Power cartridge, and the Final Cartridge. + +

+

+ Normal game cartridges can load into several different memory ranges +($8000-9FFF, $A000-BFFF or $E000-FFFF). Newer utility and freezer +cartridges were less intrusive, hiding themselves until called upon, and +still others used bank-switching techniques to allow much larger ROM's than +normal. Because of these "stealthing" and bank-switching methods, a special +cartridge format was necessary, to let the emulator know where the +cartridge should reside, the control line states to enable it and any +special hardware features it uses. + +

+ + +

15.11.1 Header contents

+ +

+ Here is a dump of a sample 8K normal cartridge, "Attack Of The Mutant +Camels"... + +

+ +
+      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   C64?CARTRIDGE???
+0010: 00 00 00 40 01 00 00 00 00 01 00 00 00 00 00 00   ???@????????????
+0020: 41 54 54 41 43 4B 20 4F 46 20 54 48 45 20 4D 55   ATTACK?OF?THE?MU
+0030: 54 41 4E 54 20 43 41 4D 45 4C 53 00 00 00 00 00   TANT?CAMELS?????
+0040: 43 48 49 50 00 00 20 10 00 00 00 00 80 00 20 00   CHIP????????.???
+0050: D3 9B BC FE C3 C2 CD 38 30 EA EA EA A9 01 85 13   .?....80....??
+0060: 4C B3 9B A9 08 85 5A 88 D0 FD C6 5A D0 F9 60 D0   L.?Z...Z.?`.
+
+ + +
+  Bytes:$0000-000F - 16-byte cartridge signature  "C64  CARTRIDGE"  (padded
+                     with space characters)
+         0010-0013 - File header length  ($00000040,  in  high/low  format,
+                     calculated from offset $0000). The default  (also  the
+                     minimum) value is $40.  Some  cartridges  exist  which
+                     show a value of $00000020 which is wrong.
+         0014-0015 - Cartridge version (high/low, presently 01.00)
+         0016-0017 - Cartridge hardware type ($0000, high/low)
+                       0 - Normal cartridge
+                       1 - Action Replay
+                       2 - KCS Power Cartridge
+                       3 - Final Cartridge III
+                       4 - Simons' BASIC
+                       5 - Ocean type 1*
+                       6 - Expert Cartridge
+                       7 - Fun Play, Power Play
+                       8 - Super Games
+                       9 - Atomic Power
+                      10 - Epyx Fastload
+                      11 - Westermann Learning
+                      12 - Rex Utility
+                      13 - Final Cartridge I
+                      14 - Magic Formel
+                      15 - C64 Game System, System 3
+                      16 - Warp Speed
+                      17 - Dinamic**
+                      18 - Zaxxon, Super Zaxxon (SEGA)
+                      19 - Magic Desk, Domark, HES Australia
+                      20 - Super Snapshot V5
+                      21 - Comal-80
+                      22 - Structured BASIC
+                      23 - Ross
+                      24 - Dela EP64
+                      25 - Dela EP7x8
+                      26 - Dela EP256
+                      27 - Rex EP256
+                      28 - Mikro Assembler
+                      29 - Final Cartridge Plus
+                      30 - Action Replay 4
+                      31 - Stardos
+                      32 - EasyFlash
+                      33 - EasyFlash Xbank
+                      34 - Capture
+                      35 - Action Replay 3
+                      36 - Retro Replay
+                      37 - MMC64
+                      38 - MMC Replay
+                      39 - IDE64
+                      40 - Super Snapshot V4
+                      41 - IEEE-488
+                      42 - Game Killer
+                      43 - Prophet64
+                      44 - EXOS
+                      45 - Freeze Frame
+                      46 - Freeze Machine
+                      47 - Snapshot64
+                      48 - Super Explode V5.0
+                      49 - Magic Voice
+                      50 - Action Replay 2
+                      51 - MACH 5
+                      52 - Diashow-Maker
+                      53 - Pagefox
+              0018 - Cartridge port EXROM line status
+                      0 - inactive
+                      1 - active
+              0019 - Cartridge port GAME line status
+                      0 - inactive
+                      1 - active
+         001A-001F - Reserved for future use
+         0020-003F - 32-byte cartridge  name  "CCSMON"  (uppercase,  padded
+                     with null characters)
+         0040-xxxx - Cartridge contents (called CHIP PACKETS, as there  can
+                     be more than one  per  CRT  file).  See  below  for  a
+                     breakdown of the CHIP format.
+
+ +

+ (*Note: Ocean type 1 includes Navy Seals, Robocop 2 & 3, Shadow of the + Beast, Toki, Terminator 2 and more) + +

+

+ (**Note: Dinamic includes Narco Police and more) + +

+ + +

15.11.2 CHIP Contents

+ +

+ The following is the contents of the CHIP packet, from position $0040 on +in the CRT file. 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: D3 9B BC FE C3 C2 CD 38 30 EA EA EA A9 01 85 13   .?....80....??
+0020: 4C B3 9B A9 08 85 5A 88 D0 FD C6 5A D0 F9 60 D0   L.?Z...Z.?`.
+0030: F2 60 A9 04 85 49 A9 00 85 48 A2 00 A5 48 9D 40   ?`.?I.?H.?H@
+0040: 03 A5 49 9D 60 03 A5 48 18 69 28 85 48 A5 49 69   ?I`?H?i(HIi
+0050: 00 85 49 E8 E0 18 D0 E4 60 A6 03 A4 02 BD 40 03   ?I???.?`?????@?
+
+ + +
+  Bytes:$0000-0003 - Contained ROM 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) (high/low format)
+         0008-0009 - Chip type
+                      0 - ROM
+                      1 - RAM, no ROM data
+                      2 - Flash ROM
+         000A-000B - Bank number ($0000 - normal cartridge)
+         000C-000D - Starting load address (high/low format)
+         000E-000F - ROM image size in bytes  (high/low  format,  typically
+                     $2000 or $4000)
+         0010-xxxx - ROM data
+
+ +

+ The following is a chart taken from the "Commodore Programmers Reference +Guide". It details the state of various areas of memory depending on the +state of the control lines. + +

+ +

+Legend: +L - ROML (low) +H - ROMH (high) +G - GAME +E - EXROM + +

+ +
+Addr       LHGE   LHGE   LHGE   LHGE   LHGE   LHGE   LHGE   LHGE   LHGE
+Range
+           1111   101X   1000   011X   001X   1110   0100   1100   XX01
+         default                00X0                             Ultimax
+-------------------------------------------------------------------------
+E000-FFFF Kernal  RAM    RAM   Kernal  RAM   Kernal Kernal Kernal ROMH(*)
+D000-DFFF IO/CHR IO/CHR IO/RAM IO/CHR  RAM   IO/CHR IO/CHR IO/CHR   I/O
+C000-CFFF  RAM    RAM    RAM    RAM    RAM    RAM    RAM    RAM     -
+A000-BFFF BASIC   RAM    RAM    RAM    RAM   BASIC   ROMH   ROMH    -
+8000-9FFF  RAM    RAM    RAM    RAM    RAM    ROML   RAM    ROML  ROML(*)
+4000-7FFF  RAM    RAM    RAM    RAM    RAM    RAM    RAM    RAM     -
+1000-3FFF  RAM    RAM    RAM    RAM    RAM    RAM    RAM    RAM     -
+0000-0FFF  RAM    RAM    RAM    RAM    RAM    RAM    RAM    RAM    RAM
+
+ +

+(*) Internal memory does not respond to write accesses in these areas + +

+ +

+ From the above chart, the following table can be built. It shows standard +cartridges, either 8K or 16K in size, and the memory ranges they load into. + +

+ +
+Type     Size   Game   EXRom  Low Bank  High Bank
+         in K   Line   Line    (ROML)    (ROMH)
+-------------------------------------------------
+Normal    8k     hi     lo     $8000      ----
+Normal    16k    lo     lo     $8000     $A000
+Ultimax   8k     lo     hi     $E000      ----
+
+ +

+ The ROMH and ROML lines are CPU-controlled status lines, used to bank +in/out RAM, ROM or I/O, depending on what is needed at the time. + +

+

+ Ultimax cartridges typically are situated in the $E000-FFFF (8K) ROM +address range. There are some cartridges which only use 4K of the 8K +allocation. If the cartridge is 16K in size, then it will reside in both +$8000-9FFF and $E000-FFFF. + +

+ + +

15.11.3 Cartridge Specifics

+ + + +

15.11.3.1 0 - Normal cartridge

+ + + + + + + + + + + + + + + + + + +
Size8Kb
GAMEactive (1)
EXROMinactive (0)
Load address$8000-9FFF
+ + +
+      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   C64?CARTRIDGE???
+0010: 00 00 00 40 01 00 00 00 00 01 00 00 00 00 00 00   ???@????????????
+0020: 41 54 54 41 43 4B 20 4F 46 20 54 48 45 20 4D 55   ATTACK?OF?THE?MU
+0030: 54 41 4E 54 20 43 41 4D 45 4C 53 00 00 00 00 00   TANT?CAMELS?????
+0040: 43 48 49 50 00 00 20 10 00 00 00 00 80 00 20 00   CHIP????????.???
+0050: D3 9B BC FE C3 C2 CD 38 30 EA EA EA A9 01 85 13   .?....80....??
+
+ +

+ The second sample below is a dump of "Music Machine", a 4Kb ULTIMAX + mode cartridge. It is still identified as a "standard cartridge" + according to the ID. + +

+

+ Normal cartridge + +

+ + + + + + + + + + + + + + + + + +
Size4Kb (ULTIMAX mode)
GAMEinactive (0)
EXROMactive (1)
Load address$F000-F7FF
+ + +
+      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   C64?CARTRIDGE???
+0010: 00 00 00 40 01 00 00 00 01 00 00 00 00 00 00 00   ???@????????????
+0020: 4D 55 53 49 43 20 4D 41 43 48 49 4E 45 00 00 00   MUSIC?MACHINE???
+0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ????????????????
+0040: 43 48 49 50 00 00 10 10 00 00 00 00 F0 00 10 00   CHIP????????????
+0050: 3C 66 C3 C3 66 3C FF FF 18 3C 66 7E 66 66 66 00   <f..f<???<f~fff?
+
+ +

+ The third sample is a dump of "Adventure Creator", a 16Kb standard + cartridge. + +

+

+ Normal cartridge + +

+ + + + + + + + + + + + + + + + + +
Size16Kb
GAMEinactive (0)
EXROMinactive (0)
Load address$8000-BFFF
+ + +
+      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   C64?CARTRIDGE???
+0010: 00 00 00 40 01 00 00 00 00 00 00 00 00 00 00 00   ???@????????????
+0020: 41 64 76 65 6E 74 75 72 65 20 43 72 65 61 74 6F   Adventure?Creato
+0030: 72 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   r???????????????
+0040: 43 48 49 50 00 00 40 10 00 00 00 00 80 00 40 00   CHIP???????.?@?
+0050: 09 80 81 EA C3 C2 CD 38 30 A2 00 78 D8 8E 11 D0   ?.....80.?x.?.
+
+ + + +

15.11.3.2 1 - Action Replay

+ + + + + + + + + + + + + + + + + + +
Size32Kb (4 banks of 8Kb each)
GAMEinactive (0)
EXROMinactive (0)
Load address$8000-9FFF (all modules)
+ + +
+      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   C64?CARTRIDGE???
+0010: 00 00 00 40 01 00 00 01 00 00 00 00 00 00 00 00   ???@????????????
+0020: 41 63 74 69 6F 6E 20 52 65 70 6C 61 79 20 56 00   Action?Replay?V?
+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????????.???
+0050: 09 80 0C 80 C3 C2 CD 38 30 4C 60 80 4C 63 80 4C   ?.?....80L`.Lc.L
+
+ +

+ This cart has 32Kb of ROM, and 8Kb of RAM. The bank switching is done + by writing to the I/O-1 range as follows: + +

+ +
+    bit  meaning
+    ---  -------
+    7    extra ROM bank selector (A15) (unused)
+    6    1 = resets FREEZE-mode (turns back to normal mode)
+    5    1 = enable RAM at ROML ($8000-$9FFF) &
+             I/O-2 ($DF00-$DFFF = $9F00-$9FFF)
+    4    ROM bank selector high (A14)
+    3    ROM bank selector low  (A13)
+    2    1 = disable cartridge (turn off $DE00)
+    1    1 = /EXROM high
+    0    1 = /GAME low
+
+ +

+ Additionally the RAM or ROM can be available through a window in the + I/O-2 range. + +

+ + + +

15.11.3.3 2 - KCS Power Cartridge

+ + + + + + + + + + + + + + + + + + + module #2 - $A000-BFFF +
Size16Kb (2 banks of 8K each)
GAMEinactive (0)
EXROMinactive (0)
Load addressmodule #1 - $8000-9FFF
+ + +
+      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   C64?CARTRIDGE???
+0010: 00 00 00 20 01 00 00 02 00 00 00 00 00 00 00 00   ????????????????
+0020: 4B 43 53 20 50 6F 77 65 72 20 43 61 72 74 72 69   KCS?Power?Cartri
+0030: 64 67 65 00 00 00 00 00 00 00 00 00 00 00 00 00   dge?????????????
+0040: 43 48 49 50 00 00 20 10 00 00 00 00 80 00 20 00   CHIP????????.???
+0050: 09 80 5E FE C3 C2 CD 38 30 78 D8 A2 FF 9A A9 27   ?.^....80x..?..'
+...
+2050: 43 48 49 50 00 00 20 10 00 00 00 00 A0 00 20 00   CHIP???????????
+2060: 97 E3 16 A1 FF FF FF 20 13 A0 A5 01 09 01 85 01   .?.?????????
+
+ + + +

15.11.3.4 3 - Final Cartridge III

+ + + + + + + + + + + + + + + + + + +
Size64Kb (4 banks of 16Kb each)
GAMEactive (1)
EXROMactive (1)
Load address$8000-BFFF (all modules)
+ + +
+      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   C64?CARTRIDGE???
+0010: 00 00 00 40 01 00 00 03 01 01 00 00 00 00 00 00   ???@????????????
+0020: 46 69 6E 61 6C 20 43 61 72 74 72 69 64 67 65 20   Final?Cartridge?
+0030: 49 49 49 20 31 39 38 37 00 00 00 00 00 00 00 00   III?1987????????
+0040: 43 48 49 50 00 00 40 10 00 00 00 00 80 00 40 00   CHIP??@?????.?@?
+0050: 09 80 5E FE C3 C2 CD 38 30 4C 4C 80 4C 55 95 4C   ?.^....80LL.LUL
+...
+4050: 43 48 49 50 00 00 40 10 00 00 00 01 80 00 40 00   CHIP??@?????.?@?
+4060: 01 02 00 81 5D 81 61 81 99 81 D8 81 0B 82 33 82   ???]a.?3
+...
+8060: 43 48 49 50 00 00 40 10 00 00 00 02 80 00 40 00   CHIP??@?????.?@?
+8070: 20 43 80 20 52 80 A9 4E 20 05 DE 20 FD BF AD 39   ?C.?R..N??.?..9
+...
+C070: 43 48 49 50 00 00 40 10 00 00 00 03 80 00 40 00   CHIP??@?????.?@?
+C080: A2 06 BD DD 85 95 05 CA 10 F8 AE A0 02 E8 EC A2   .??.?.?????.
+
+ +

+ A total of 64 kB of ROM memory is organized into four $4000 banks + located at $8000-$BFFF. + +

+

+ The banks are arranged in the following way: + +

+ +
+    Bank 0:  BASIC, Monitor, Disk-Turbo
+    Bank 1:  Notepad, BASIC (Menu Bar)
+    Bank 2:  Desktop, Freezer/Print
+    Bank 3:  Freezer, Compression
+
+ +

+ The cartridges uses the entire I/O-1 and I/O-2 range. Bank switching is + done by writing the bank number plus $40 into memory location $DFFF. + For instance, to select bank 2, $DFFF is set to $42. + +

+

+ The CRT file contains four CHIP blocks, each block with a start address + of $8000, length $4000 and the bank number in the bank field. In the + cartridge header, both EXROM ($18) and GAME ($19) are set to 1 to + enable the 16 kB ROM configuration. + +

+

+ The registers are arranged in the following way: + +

+

+ One register at $DFFF: + +

+ +
+    bit  meaning
+    ---  -------
+    7      Hide this register (1 = hidden)
+    6      NMI line  (0 = low = active) *1)
+    5      GAME line  (0 = low = active) *2)
+    4      EXROM line (0 = low = active)
+    2-3    unassigned (usually set to 0)
+    0-1    number of bank to show at $8000
+
+ +

+ 1) if either the freezer button is pressed, or bit 6 is 0, then an NMI + is generated + +

+

+ 2) if the freezer button is pressed, GAME is also forced low + +

+

+ The rest of I/O-1/I/O-2 contain a mirror of the last 2 pages of the + currently selected ROM bank (also at $dfff, contrary to what some other + documents say) + +

+ + + +

15.11.3.5 4 - Simons' Basic

+ + + + + + + + + + + + + + + + + + + module #2 - $A000-BFFF +
Size16Kb (2 banks of 8kb each)
GAMEactive (1)
EXROMinactive (0)
Load addressmodule #1 - $8000-9FFF
+ + +
+      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   C64?CARTRIDGE???
+0010: 00 00 00 40 01 00 00 04 00 01 00 00 00 00 00 00   ???@????????????
+0020: 53 69 6D 6F 6E 27 73 20 42 61 73 69 63 00 00 00   Simon's?Basic???
+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????????.???
+0050: 52 81 52 81 C3 C2 CD 38 30 41 4C 52 81 20 2C 81   RR...80ALR?,
+...
+2050: 43 48 49 50 00 00 20 10 00 00 00 00 A0 00 20 00   CHIP???????????
+2060: 20 A4 A6 99 9E CB A0 05 A5 A8 91 20 A4 A6 99 A2   ???.??.???.
+
+ +

+ Simons' BASIC permanently uses 16 kB ($4000) bytes of cartridge memory + from $8000-$BFFF. However, through some custom bank-switching logic the + upper area ($A000-$BFFF) may be disabled so Simons' BASIC may use it as + additional RAM. Writing a value of $01 to address location $DE00 banks + in ROM, $00 disables ROM and enables RAM. + +

+

+ The CRT file contains two CHIP blocks of length $2000 each, the first + block having a start address of $8000, the second block $A000. In the + cartridge header, EXROM ($18) is set to 0, GAME ($19) is set to 1 to + indicate the RESET/power-up configuration of 8 kB ROM. + +

+ + + +

15.11.3.6 5 - Ocean type 1

+ + + + + + + + + + + + + + + + + + + Banks 16-31 - $A000-BFFF (except Terminator 2) +
Size32Kb, 128Kb, 256Kb or 512Kb sizes (4, 16, 32 or 64 banks of 8Kb)
GAMEinactive (0)
EXROMinactive (0)
Load addressBanks 00-15 - $8000-9FFF
+ + +
+       00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F        ASCII
+       -----------------------------------------------   ----------------
+00000: 43 36 34 20 43 41 52 54 52 49 44 47 45 20 20 20   C64?CARTRIDGE???
+00010: 00 00 00 40 01 00 00 05 00 00 00 00 00 00 00 00   ???@????????????
+00020: 53 48 41 44 4F 57 20 4F 46 20 54 48 45 20 42 45   SHADOW?OF?THE?BE
+00030: 41 53 54 00 00 00 00 00 00 00 00 00 00 00 00 00   AST?????????????
+00040: 43 48 49 50 00 00 20 10 00 00 00 00 80 00 20 00   CHIP????????.???
+00050: 09 80 83 81 C3 C2 CD 38 30 4C 83 81 4C 76 82 80   ?....80LLv.
+ ...
+02050: 43 48 49 50 00 00 20 10 00 00 00 01 80 00 20 00   CHIP????????.???
+02060: 59 6D 00 56 AD 00 55 AE F0 00 01 A0 FE 00 01 F8   Ym?V?U???.???
+ ...
+20140: 43 48 49 50 00 00 20 10 00 00 00 10 A0 00 20 00   CHIP???????????
+20150: 0A 9A 55 FF 9B 69 57 FE AA 65 96 FE 65 0F D6 D9   ?.U?iW.e.e?..
+
+ +

+ Here is a list of the known OCEAN cartridges: + +

+ +
+    Batman The Movie    (128 kB)
+    Battle Command      (128 kB)
+    Double Dragon       (128 kB)
+    Navy Seals          (128 kB)
+    Pang                (128 kB)
+    Robocop 3           (128 kB)
+    Space Gun           (128 kB)
+    Toki                (128 kB)
+    Chase H.Q. II       (256 kB)
+    Robocop 2           (256 kB)
+    Shadow of the Beast (256 kB)
+    Terminator 2        (512 kB)
+
+ +

+ The 32Kb type of cart has 4 banks of 8Kb ($2000), banked in at + $8000-$9FFF. + +

+

+ The 128Kb type of cart has 16 banks of 8Kb ($2000), banked in at + $8000-$9FFF. + +

+

+ The 256Kb type of cart has 32 banks of 8Kb ($2000), 16 banked in at + $8000-$9FFF, and 16 banked in at $A000-$BFFF. + +

+

+ The 512Kb type of cart has 64 banks of 8Kb ($2000), banked in at + $8000-$9FFF. + +

+

+ Bank switching is done by writing to $DE00. The lower six bits give the + bank number (ranging from 0-63). Bit 8 in this selection word is always + set. + +

+ + + +

15.11.3.7 6 - Expert Cartridge

+ + + + + + + + + + + + + + + + + + +
Size8Kb
GAMEactive (1)
EXROMactive (1)
Load address$8000-9FFF
+ + +
+      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   C64?CARTRIDGE???
+0010: 00 00 00 40 01 00 00 06 01 01 00 00 00 00 00 00   ???@????????????
+0020: 45 78 70 65 72 74 20 43 61 72 74 72 69 64 67 65   Expert?Cartridge
+0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ????????????????
+0040: 43 48 49 50 00 00 40 10 00 02 00 00 80 00 20 00   CHIP??@?????.???
+0050: 00 00 00 0A F3 00 00 00 00 00 00 00 00 00 00 00   ????????????????
+
+ + + +

15.11.3.8 7 - Fun Play, Power Play

+ + + + + + + + + + + + + + + + + + +
Size128Kb (16 banks of 8Kb modules)
GAMEinactive (0)
EXROMinactive (0)
Load address$8000-9FFF (all modules)
+ + +
+       00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F        ASCII
+       -----------------------------------------------   ----------------
+00000: 43 36 34 20 43 41 52 54 52 49 44 47 45 20 20 20   C64?CARTRIDGE???
+00010: 00 00 00 40 01 00 00 07 00 00 00 00 00 00 00 00   ???@????????????
+00020: 46 55 4E 20 50 4C 41 59 00 00 00 00 00 00 00 00   FUN?PLAY????????
+00030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ????????????????
+00040: 43 48 49 50 00 00 20 10 00 00 00 00 80 00 20 00   CHIP????????.???
+00050: 1E 80 86 EA C3 C2 CD 38 30 1B 00 81 0D 08 80 00   ?.....80????.?
+ ...
+02050: 43 48 49 50 00 00 20 10 00 00 00 08 80 00 20 00   CHIP????????.???
+02060: 78 A2 F0 86 01 BD 1D 08 9D F8 00 CA D0 F7 4C 00   x.???????..?L?
+ ...
+04060: 43 48 49 50 00 00 20 10 00 00 00 10 80 00 20 00   CHIP????????.???
+04070: 38 E5 68 85 03 B0 11 27 03 12 C0 18 69 27 42 90   8?h??'??.?i'B
+ ...
+06070: 43 48 49 50 00 00 20 10 00 00 00 18 80 00 20 00   CHIP????????.???
+06080: 44 D0 5E 06 02 C0 44 11 40 04 11 44 01 5F 1C 73   D.^??.D?@??D?_?s
+ ...
+1E130: 43 48 49 50 00 00 20 10 00 00 00 39 80 00 20 00   CHIP???????9.???
+1E140: 85 EB 41 EA 9E 08 03 00 C0 06 18 01 00 C0 08 03   ?A.???.????.??
+
+ +

+ The FUN PLAY Cartridge uses $DE00 for bank selection, and uses 8Kb + banks ($2000) at $8000-$9FFF. There are 16 banks of ROM memory and are + referenced by the following values: + +

+ +
+    $00 -> Bank 0
+    $08 -> Bank 1
+    $10 -> Bank 2
+    $18 -> Bank 3
+    $20 -> Bank 4
+    $28 -> Bank 5
+    $30 -> Bank 6
+    $38 -> Bank 7
+    $01 -> Bank 8
+    $09 -> Bank 9
+    $11 -> Bank 10
+    $19 -> Bank 11
+    $21 -> Bank 12
+    $29 -> Bank 13
+    $31 -> Bank 14
+    $39 -> Bank 15
+
+ +

+ The bank field in the chip headers is set according to the value + written to $DE00. The following bits are used for bank decoding in + $DE00 (0 being the LSB, 3 being the MSB). + +

+ +
+        Bit# 76543210
+             xx210xx3
+
+ +

+ After copying memory from the ROM banks, the selection program writes + a value of $86 to $DE00. This seems either to reset or disable the + cartridge ROM. + +

+ + + +

15.11.3.9 8 - Super Games

+ + + + + + + + + + + + + + + + + + +
Size64Kb (4 banks of 16Kb each)
GAMEinactive (0)
EXROMinactive (0)
Load address$8000-BFFF (all modules)
+ + +
+      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   C64?CARTRIDGE???
+0010: 00 00 00 40 01 00 00 08 00 00 00 00 00 00 00 00   ???@????????????
+0020: 53 55 50 45 52 20 47 41 4D 45 53 00 00 00 00 00   SUPER?GAMES?????
+0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ????????????????
+0040: 43 48 49 50 00 00 40 10 00 00 00 00 80 00 40 00   CHIP??@?????.?@?
+0050: 0A 80 0A 80 C3 C2 CD 38 30 00 A9 80 A0 00 85 FB   ?.?....80?..?.
+...
+4050: 43 48 49 50 00 00 40 10 00 00 00 01 80 00 40 00   CHIP??@?????.?@?
+4060: 27 80 A8 80 C3 C2 CD 38 30 00 40 C0 40 C0 40 C0   '.?....80?@.@.@.
+...
+8060: 43 48 49 50 00 00 40 10 00 00 00 02 80 00 40 00   CHIP??@?????.?@?
+8070: 00 00 00 49 4D C7 64 47 46 45 F3 48 DC 08 7E 0B   ???IM.dGFE?H.?~?
+...
+C070: 43 48 49 50 00 00 40 10 00 00 00 03 80 00 40 00   CHIP??@?????.?@?
+C080: D5 F9 F0 C1 D5 F7 F0 BD E8 B5 02 F0 FB C9 05 30   .??..??????..?0
+
+ +

+ The Super Games cartridge uses 4 16Kb banks ($8000-$BFFF) of ROM + memory. Bank selecting is done by writing to $DF00. + +

+

+ $DF00 register is as follows: + +

+ +
+    bit  meaning
+    ---  -------
+    0    bank bit 0
+    1    bank bit 1
+    2    inverted GAME line
+    3    inverted EXROM line
+    4-7  unused
+
+ + + +

15.11.3.10 9 - Atomic Power

+ + + + + + + + + + + + + + + + + + +
Size32Kb (4 banks of 8Kb modules)
GAMEinactive (0)
EXROMinactive (0)
Load address$8000-9FFF (all modules)
+ + +
+      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   C64?CARTRIDGE???
+0010: 00 00 00 40 01 00 00 09 00 00 00 00 00 00 00 00   ???@????????????
+0020: 41 74 6F 6D 69 63 20 50 6F 77 65 72 00 00 00 00   Atomic?Power????
+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????????.???
+0050: 09 80 0C 80 C3 C2 CD 38 30 4C 41 80 4C 1E 80 4C   ?.?....80LA.L?.L
+...
+2050: 43 48 49 50 00 00 20 10 00 00 00 01 80 00 20 00   CHIP????????.???
+2060: 09 80 0C 80 C3 C2 CD 38 30 4C 3F 80 4C 91 80 4C   ?.?....80L?.L..L
+...
+4060: 43 48 49 50 00 00 20 10 00 00 00 02 80 00 20 00   CHIP????????.???
+4070: EF FC 09 80 C3 C2 CD 38 30 4C 27 80 4C DB 81 4C   ?.?....80L'.L.L
+...
+6070: 43 48 49 50 00 00 20 10 00 00 00 03 80 00 20 00   CHIP????????.???
+6080: 09 80 0C 80 C3 C2 CD 38 30 4C 73 86 4C 30 80 4C   ?.?....80LsL0.L
+
+ +

+ This cart has 32Kb of ROM and 8Kb of RAM + +

+

+ Writing to I/O-1 will do the following: + +

+ +
+    bit  meaning
+    ---  -------
+    7    extra ROM bank selector (A15) (unused)
+    6    1 = resets FREEZE-mode (turns back to normal mode)
+    5    1 = enable RAM at ROML ($8000-$9FFF) &
+             I/O-2 ($DF00-$DFFF = $9F00-$9FFF)
+    4    ROM bank selector high (A14)
+    3    ROM bank selector low  (A13)
+    2    1 = disable cartridge (turn off $DE00)
+    1    1 = /EXROM high
+    0    1 = /GAME low
+
+ +

+ If bit 5 (RAM enable) is 1, bit 0,1 (exrom/game) is == 2 (cart off), + bit 2,6,7 (cart disable, freeze clear) are 0, then cart ROM (Bank 0..3) + is mapped at 8000-9FFF, and cart RAM (Bank 0) is mapped at A000-BFFF + and cart RAM (Bank 0) is is enabled in the I/O-2 area using 16Kb game + config. + +

+

+ The cart RAM or ROM is available through a window in the I/O-2 range. + +

+ + + +

15.11.3.11 10 - Epyx Fastload

+ + + + + + + + + + + + + + + + + + +
Size8Kb
GAMEactive (1)
EXROMactive (1)
Load address$8000-9FFF
+ + +
+      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   C64?CARTRIDGE???
+0010: 00 00 00 40 01 00 00 0A 01 01 00 00 00 00 00 00   ???@????????????
+0020: 45 50 59 58 20 46 41 53 54 4C 4F 41 44 00 00 00   EPYX?FASTLOAD???
+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????????.???
+0050: 30 80 5E FE C3 C2 CD 38 30 20 04 90 4C 38 DF AB   0.^....80??L8?
+
+ +

+ The Epyx FastLoad cart uses a simple capacitor to toggle the ROM on + and off: + +

+

+ the capacitor is discharged, and 8k game config enabled, by either + reading ROML or reading I/O-1. If none of those accesses happen the + capacitor will charge, and if it is charged (after 512 cycles) then + the ROM will get disabled. + +

+ + +

15.11.3.12 11 - Westermann Learning

+ + + + + + + + + + + + + + + + + + +
Size16Kb
GAMEinactive (0)
EXROMinactive (0)
Load address$8000-BFFF
+ + +
+      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   C64?CARTRIDGE???
+0010: 00 00 00 40 01 00 00 0B 00 00 00 00 00 00 00 00   ???@????????????
+0020: 57 45 53 54 45 52 4D 41 4E 4E 00 00 00 00 00 00   WESTERMANN??????
+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 40 00   CHIP????????.?@?
+0050: 09 80 9C 80 C3 C2 CD 38 30 A2 00 8E 16 D0 20 84   ?.....80.??.?
+
+ +

+ Any read from the I/O-2 range will switch the cart off. + +

+ + + +

15.11.3.13 12 - Rex Utility

+ + + + + + + + + + + + + + + + + + +
Size8K
GAMEactive (1)
EXROMinactive (0)
Load address$8000-9FFF
+ + +
+      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   C64?CARTRIDGE???
+0010: 00 00 00 40 01 00 00 0C 00 01 00 00 00 00 00 00   ???@????????????
+0020: 52 45 58 00 00 00 00 00 00 00 00 00 00 00 00 00   REX?????????????
+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????????.???
+0050: 08 80 C1 FE C3 C2 CD 38 30 6C 95 E3 20 A3 FD 20   ?......80l.?.?
+
+ +

+ Reading from $DF00-DFBF disables ROM, reading from $DFC0-DFFF enables + ROM (8k game config). + +

+ + + +

15.11.3.14 13 - Final Cartridge I

+ + + + + + + + + + + + + + + + + + +
Size16Kb
GAMEactive (1)
EXROMactive (1)
Load address$8000-BFFF
+ + +
+      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   C64?CARTRIDGE???
+0010: 00 00 00 40 01 00 00 0D 01 01 00 00 00 00 00 00   ???@????????????
+0020: 54 68 65 20 46 69 6E 61 6C 20 43 61 72 74 72 69   The?Final?Cartri
+0030: 64 67 65 20 49 00 00 00 00 00 00 00 00 00 00 00   dge?I???????????
+0040: 43 48 49 50 00 00 40 10 00 00 00 00 80 00 40 00   CHIP??@?????.?@?
+0050: 80 BA 5E FE C3 C2 CD 38 30 00 A0 A0 20 2D FE 58   .^....80??-.X
+
+ +

+ Any access to I/O-1 turns cartridge ROM off. Any access to I/O-2 turns + cartridge ROM on. + +

+

+ The cart ROM is visible in I/O-1 and I/O-2. + +

+ + +

15.11.3.15 14 - Magic Formel

+ + + + + + + + + + + + + + + + + + +
Size64Kb (8 banks of 8Kb)
GAMEInactive (0)
EXROMInactive (0)
Load Address$E000-FFFF
+ + +
+      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  C64?CARTRIDGE???
+0010: 00 00 00 40 01 00 00 0E 01 01 00 00 00 00 00 00  ???@????????????
+0020: 4D 61 67 69 63 20 46 6F 72 6D 65 6C 00 00 00 00  Magic?Formel????
+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 E0 00 20 00  CHIP????????????
+0050: 4D 46 30 8D 00 DF 60 8D 01 DF 60 8D 02 DF 60 8D  MF0??`??`??`
+...
+2050: 43 48 49 50 00 00 20 10 00 00 00 01 E0 00 20 00  CHIP????????????
+2060: 4C 5F E4 8D 00 DF 60 8D 01 DF 60 8D 02 DF 60 8D  L_???`??`??`
+...
+4060: 43 48 49 50 00 00 20 10 00 00 00 02 E0 00 20 00  CHIP????????????
+4070: 4D 46 32 8D 00 DF 60 8D 01 DF 60 8D 02 DF 60 8D  MF2??`??`??`
+...
+6070: 43 48 49 50 00 00 20 10 00 00 00 03 E0 00 20 00  CHIP????????????
+6080: 4D 46 33 8D 00 DF 60 8D 01 DF 60 8D 02 DF 60 8D  MF3??`??`??`
+...
+8080: 43 48 49 50 00 00 20 10 00 00 00 04 E0 00 20 00  CHIP????????????
+8090: 4D 46 34 8D 00 DF 60 8D 01 DF 60 8D 02 DF 60 8D  MF4??`??`??`
+...
+A090: 43 48 49 50 00 00 20 10 00 00 00 05 E0 00 20 00  CHIP????????????
+A0A0: 4D 46 35 8D 00 DF 60 8D 01 DF 60 8D 02 DF 60 8D  MF5??`??`??`
+...
+C0A0: 43 48 49 50 00 00 20 10 00 00 00 06 E0 00 20 00  CHIP????????????
+C0B0: 4D 46 36 8D 00 DF 60 8D 01 DF 60 8D 02 DF 60 8D  MF6??`??`??`
+..
+E0B0: 43 48 49 50 00 00 20 10 00 00 00 07 E0 00 20 00  CHIP????????????
+E0C0: 4D 46 37 8D 00 DF 60 8D 01 DF 60 8D 02 DF 60 8D  MF7??`??`??`
+
+ + + +

15.11.3.16 15 - C64 Game System, System 3

+ + + + + + + + + + + + + + + + + + +
Size512Kb (64 banks of 8Kb each)
GAMEinactive (0)
EXROMactive (1)
Load address$8000-9FFF (all modules)
+ + +
+        00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F       ASCII
+        -----------------------------------------------  ----------------
+000000: 43 36 34 20 43 41 52 54 52 49 44 47 45 20 20 20  C64?CARTRIDGE???
+000010: 00 00 00 40 01 00 00 0F 00 01 00 00 00 00 00 00  ???@????????????
+000020: 43 36 34 47 53 20 43 61 72 74 72 69 64 67 65 00  C64GS?Cartridge?
+000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ????????????????
+000040: 43 48 49 50 00 00 20 10 00 00 00 00 80 00 20 00  CHIP????????.???
+000050: 6D 80 C5 80 C3 C2 CD 38 30 4C CB 80 4C 36 84 4C  m......80L..L6L
+...
+002050: 43 48 49 50 00 00 20 10 00 00 00 01 80 00 20 00  CHIP????????.???
+002060: 18 D0 A9 FF 8D 15 D0 8D 1D D0 8D 17 D0 A2 07 A9  ?..??.?.?..?.
+...
+004060: 43 48 49 50 00 00 20 10 00 00 00 02 80 00 20 00  CHIP????????.???
+004070: E0 08 19 21 77 84 52 98 9F 80 A5 21 31 01 31 89  ???!wR.!1?1
+...
+006070: 43 48 49 50 00 00 20 10 00 00 00 03 80 00 20 00  CHIP????????.???
+006080: C0 08 1C 1D A0 92 03 03 D8 AA 04 C0 B8 01 40 EA  .???.??.?.??@.
+...
+07E430: 43 48 49 50 00 00 20 10 00 00 00 3F 80 00 20 00  CHIP????????.???
+07E440: 45 20 41 20 42 49 47 20 58 FE 4F 4E 20 54 48 49  E?A?BIG?X.ON?THI
+
+ +

+ Here is a list of the known cartridges: + +

+ +
+    C64GS 4-in-1      (Commodore)  (512 kB)
+    Last Ninja Remix  (System 3)   (512 kB)
+    Myth              (System 3)   (512 kB)
+
+ +

+ ROM memory is organized in 8Kb ($2000) banks located at $8000-$9FFF. + Bank switching is done by writing to address $DE00+X, where X is the + bank number (STA $DE00,X). For instance, to read from bank 3, address + $DE03 is written to. Reading from anywhere in the I/O-1 range will + disable the cart. + +

+

+ The CRT file contains a string of CHIP blocks, each block with a start + address of $8000, length $2000 and the bank number in the bank field. + In the cartridge header, EXROM ($18) is set to 0, GAME ($19) is set to + 1 to enable the 8 kB ROM configuration. + +

+ + + +

15.11.3.17 16 - Warp Speed

+ + + + + + + + + + + + + + + + + + +
Size16Kb
GAMEinactive (0)
EXROMinactive (0)
Load address$8000-BFFF
+ + +
+      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  C64?CARTRIDGE???
+0010: 00 00 00 40 01 00 00 10 01 01 00 00 00 00 00 00  ???@????????????
+0020: 57 61 72 70 73 70 65 65 64 00 00 00 00 00 00 00  Warpspeed???????
+0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ????????????????
+0040: 43 48 49 50 00 00 40 10 00 00 00 00 80 00 40 00  CHIP??@?????.?@?
+0050: 4C 22 80 4C 22 80 FF 43 42 4D 20 53 E4 20 18 E5  L".L".?CBM?S????
+
+ +

+ After RESET or POWER ON, 16kB of cartridge ROM is visible at + $8000-$BFFF. Additionally, ROM normally located at $9E00-$9FFF is + mirrored into I/O-1 and I/O-2 at $DE00-$DFFF. ROM at $8000-$BFFF is + disabled by writing into the I/O-2 area (typically $DF00) and may be + re-enabled by writing into I/O-1 ($DE00). However, the $DE00-$DFFF + (I/O-1/I/O-2) area itself always remains mapped to cartridge ROM. + +

+ + + +

15.11.3.18 17 - Dinamic

+ + + + + + + + + + + + + + + + + + +
Size128Kb (16 banks of 8Kb each)
GAMEinactive (0)
EXROMactive (1)
Load address$8000-9FFF (all modules)
+ + +
+        00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F       ASCII
+        -----------------------------------------------  ----------------
+000000: 43 36 34 20 43 41 52 54 52 49 44 47 45 20 20 20  C64?CARTRIDGE???
+000010: 00 00 00 40 01 00 00 11 00 01 00 00 00 00 00 00  ???@????????????
+000020: 4E 61 72 63 6F 20 50 6F 6C 69 63 65 00 00 00 00  Narco?Police????
+000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ????????????????
+000040: 43 48 49 50 00 00 20 10 00 00 00 00 80 00 20 00  CHIP????????.???
+000050: 0B 80 0B 80 C3 C2 CD 38 30 00 00 78 A2 FF 9A D8  ?.?....80??x.?..
+..
+002050: 43 48 49 50 00 00 20 10 00 00 00 01 80 00 20 00  CHIP????????.???
+002060: 1C 8C 1B 8C 16 16 8F 16 16 88 1C 1C 86 1C 1C 89  ??????????
+..
+004060: 43 48 49 50 00 00 20 10 00 00 00 02 80 00 20 00  CHIP????????.???
+004070: B6 02 07 08 07 07 00 0A 0A B6 00 05 0A 00 07 07  ??????????????
+..
+01E130: 43 48 49 50 00 00 20 10 00 00 00 0F 80 00 20 00  CHIP????????.???
+01E140: 00 D5 70 03 F5 70 0F 5F 70 0F F7 70 35 FD F0 37  ?.p??p?_p??p5.?7
+
+ +

+ Here is a list of the known DINAMIC cartridges: + +

+ +
+    Narco Police  (128 kB)
+    Satan         (128 kB)
+
+ +

+ ROM memory is organized in 8Kb ($2000) banks located at $8000-$9FFF. + Bank switching is done by reading from address $DE00+X, where X is the + bank number (LDA $DE00,X). For instance, to read from bank 3, address + $DE03 is accessed. + +

+

+ The CRT file contains a string of CHIP blocks, each block with a start + address of $8000, length $2000 and the bank number in the bank field. + In the cartridge header, EXROM ($18) is set to 0, GAME ($19) is set to + 1 to enable the 8 kB ROM configuration. + +

+ + + +

15.11.3.19 18 - Zaxxon, Super Zaxxon (SEGA)

+ + + + + + + + + + + + + + + + + + + $A000-BFFF (banked modules 1 and 2, chip U2) +
Size20Kb (3 banks of different sizes)
GAMEactive (1)
EXROMactive (1)
Load address$8000-8FFF (mirrored in $9000-9FFF, module 0, chip U1)
+ + +
+        00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F       ASCII
+        -----------------------------------------------  ----------------
+000000: 43 36 34 20 43 41 52 54 52 49 44 47 45 20 20 20  C64?CARTRIDGE???
+000010: 00 00 00 40 01 00 00 12 00 00 00 00 00 00 00 00  ???@????????????
+000020: 5A 61 78 78 6F 6E 00 00 00 00 00 00 00 00 00 00  Zaxxon??????????
+000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ????????????????
+000040: 43 48 49 50 00 00 10 10 00 00 00 00 80 00 10 00  CHIP????????.???
+000050: 0D 80 29 80 C3 C2 CD 38 30 78 4C 09 80 78 A9 00  ?.)....80xL?.x.?
+..
+001050: 43 48 49 50 00 00 20 10 00 00 00 00 A0 00 20 00  CHIP???????????
+001060: A2 0F BD 00 20 D0 04 CA 10 F8 60 BD 70 20 F0 0D  .????.?.??`?p???
+..
+003060: 43 48 49 50 00 00 20 10 00 00 00 01 A0 00 20 00  CHIP???????????
+003070: 65 A2 36 A3 E7 A3 CB A4 94 A5 86 A6 5E A7 35 A8  e.6?.??^5?
+
+ +

+ The (Super) Zaxxon carts use a 4Kb ($1000) ROM at $8000-$8FFF (mirrored + in $9000-$9FFF) along with two 8Kb ($2000) cartridge banks located at + $A000-$BFFF. One of the two banks is selected by doing a read access to + either the $8000-$8FFF area (bank 0 is selected) or to $9000-$9FFF area + (bank 1 is selected). EXROM ($18 = $00) and GAME ($19 = $00) lines are + always pulled to GND to select the 16 kB ROM configuration. + +

+

+ The CRT file includes three CHIP blocks: + +

+    a) bank = 0, load address = $8000, size = $1000
+    b) bank = 0, load address = $A000, size = $2000
+    c) bank = 1, load address = $A000, size = $2000
+
+ + + +

15.11.3.20 19 - Magic Desk, Domark, HES Australia

+ + + + + + + + + + + + + + + + + + +
Size32Kb, 64Kb or 128Kb sizes (4 to 16 banks of 8Kb each)
GAMEinactive (0)
EXROMactive (1)
Load address(banks 00-15) - $8000-9FFF
+ + +
+      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  C64?CARTRIDGE???
+0010: 00 00 00 40 01 00 00 13 00 01 00 00 00 00 00 00  ???@????????????
+0020: 4D 61 67 69 63 20 44 65 73 6B 00 00 00 00 00 00  Magic?Desk??????
+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????????.???
+0050: 09 80 C6 CA C3 C2 CD 38 30 8E 16 D0 20 A3 FD 20  ?......80?.?.?
+..
+2050: 43 48 49 50 00 00 20 10 00 00 00 01 80 00 20 00  CHIP????????.???
+2060: 00 3F 0A 01 00 86 4E 24 28 31 30 29 3A 4A 4F 59  ?????N$(10):JOY
+..
+4060: 43 48 49 50 00 00 20 10 00 00 00 02 80 00 20 00  CHIP????????.???
+4070: 00 8B C9 28 4E 24 2C 31 29 B3 B1 22 FF 22 A7 32  ?.(N$,1)"?"2
+..
+6070: 43 48 49 50 00 00 20 10 00 00 00 03 80 00 20 00  CHIP????????.???
+6080: AE 01 83 33 2C 37 2C 22 32 29 20 44 45 4C 20 4B  ?3,7,"2)?DEL?K
+
+ +

+ This cartridge type is very similar to the OCEAN cart type: ROM memory + is organized in 8Kb ($2000) banks located at $8000-$9FFF. Bank + switching is done by writing the bank number to $DE00. Deviant from the + Ocean type, bit 8 is cleared for selecting one of the ROM banks. If bit + 8 is set ($DE00 = $80), the GAME/EXROM lines are disabled, turning on + RAM at $8000-$9FFF instead of ROM. + +

+

+ In the cartridge header, EXROM ($18) is set to 0, GAME ($19) is set to + 1 to indicate the RESET/power-up configuration of 8 kB ROM. + +

+

+ Here is a list of the known cartridges: + +

+ +
+    Ghosbusters        (HES Australia)   (32 kB)
+    Magic Desk         (Commodore)       (32 kB)
+    Badlands           (Domark)          (64 kB)
+    Vindicators        (Domark)          (64 kB)
+    Wonderboy          (HES Australia)   (64 kB)
+    Cyberball          (Domark)         (128 kB)
+
+ + + +

15.11.3.21 20 - Super Snapshot V5

+ + + + + + + + + + + + + + + + + + +
Size64Kb (4 banks of 16Kb each)
GAMEactive (1)
EXROMactive (1)
Load address$8000-BFFF
+ + +
+      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  C64?CARTRIDGE???
+0010: 00 00 00 40 01 00 00 14 01 01 00 00 00 00 00 00  ???@????????????
+0020: 53 75 70 65 72 20 53 6E 61 70 73 68 6F 74 20 35  Super?Snapshot?5
+0030: 20 4E 54 53 43 00 00 00 00 00 00 00 00 00 00 00  ?NTSC???????????
+0040: 43 48 49 50 00 00 40 10 00 00 00 00 80 00 40 00  CHIP??@?????.?@?
+0050: 09 80 59 80 C3 C2 CD 38 30 20 03 9F 00 FA F4 20  ?.Y....80??????
+...
+4050: 43 48 49 50 00 00 40 10 00 00 00 01 80 00 40 00  CHIP??@?????.?@?
+4060: 79 DE BC FE C3 C2 CD 38 30 A9 05 8D 20 D0 8D 21  y.?....80.??.!
+...
+8060: 43 48 49 50 00 00 40 10 00 00 00 02 80 00 40 00  CHIP??@?????.?@?
+8070: 50 DE BC FE C3 C2 CD 38 30 A9 0A 85 6A A9 0D 85  P.?....80.?j.?
+...
+C070: 43 48 49 50 00 00 40 10 00 00 00 03 80 00 40 00  CHIP??@?????.?@?
+C080: 50 DE BC FE C3 C2 CD 38 30 85 07 20 1A AD A5 76  P.?....80???v
+
+ +

+ The first page of the currently selected ROM bank is mirrored in the + I/O-1 range when reading. + +

+

+ The control Register is the I/O-1 range when writing: + +

+ +
+    bit  meaning
+    ---  -------
+    7-5  unused
+    4    ROM/RAM bank bit 1
+    3    ROM enable
+    2    ROM/RAM bank bit 0
+    1    RAM enable, EXROM
+    0    release freeze, !GAME
+
+ + + +

15.11.3.22 21 - Comal-80

+ + + + + + + + + + + + + + + + + + +
Size64Kb (4 banks of 16Kb each)
GAMEactive (1)
EXROMactive (1)
Load address$8000-BFFF
+ + +
+      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  C64?CARTRIDGE???
+0010: 00 00 00 40 01 00 00 15 01 01 00 00 00 00 00 00  ???@????????????
+0020: 43 6F 6D 61 6C 20 38 30 00 00 00 00 00 00 00 00  Comal?80????????
+0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ????????????????
+0040: 43 48 49 50 00 00 40 10 00 00 00 00 80 00 40 00  CHIP??@?????.?@?
+0050: 87 87 70 CF C3 C2 CD 38 30 4C AA CF 4C 70 CF 4C  ..p....80L.Lp.L
+...
+4050: 43 48 49 50 00 00 40 10 00 00 00 01 80 00 40 00  CHIP??@?????.?@?
+4060: AA CF 70 CF C3 C2 CD 38 30 01 29 01 28 01 2C 04  .p....80?)?(?,?
+...
+8060: 43 48 49 50 00 00 40 10 00 00 00 02 80 00 40 00  CHIP??@?????.?@?
+8070: AA CF 70 CF C3 C2 CD 38 30 91 92 92 92 92 92 92  .p....80.......
+...
+C070: 43 48 49 50 00 00 40 10 00 00 00 03 80 00 40 00  CHIP??@?????.?@?
+C080: 7B C8 7E C8 C3 C2 CD 38 30 43 4F 4D 41 4C 80 93  ..~....80COMAL..
+
+ +

+ The Comal-80 Cartridge uses $DE00 for bank selection, and uses 16Kb + banks ($4000) at $8000-$BFFF. There are 4 banks of ROM memory and are + referenced by the following values: + +

+ +
+       $80 -> Bank 0
+       $81 -> Bank 1
+       $82 -> Bank 2
+       $83 -> Bank 3
+
+ + + +

15.11.3.23 22 - Structured Basic

+ + + + + + + + + + + + + + + + + + +
Size16Kb (2 banks of 8Kb each)
GAMEactive (0)
EXROMactive (1)
Load address$8000-9FFF
+ +

+ No sample data/file available. + +

+

+ Any read/write access to $DE00 or $DE01 will switch in bank 0. Any + read/write access to $DE02 will switch in bank 1. Any read/write access + to $DE03 will switch off EXROM. + +

+ + + +

15.11.3.24 23 - Ross

+ + + + + + + + + + + + + + + + + + +
Size16Kb or 32Kb sizes (1 or 2 banks of 16Kb each)
GAMEactive (1)
EXROMactive (1)
Load address$8000-BFFF
+ + +
+      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  C64?CARTRIDGE???
+0010: 00 00 00 40 01 00 00 17 00 00 00 00 00 00 00 00  ???@????????????
+0020: 52 6F 73 73 20 31 34 00 00 00 00 00 00 00 00 00  Ross?14?????????
+0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ????????????????
+0040: 43 48 49 50 00 00 40 10 00 00 00 00 80 00 40 00  CHIP??@?????.?@?
+0050: 09 80 09 80 C3 C2 CD 38 30 A2 00 BD 20 80 4D 0E  ?.?....80.???.M?
+...
+4050: 43 48 49 50 00 00 40 10 00 00 00 01 80 00 40 00  CHIP??@?????.?@?
+4060: 3F 5A 4D 4D 50 4D 8D 25 3F 1A 1F 77 3F CD E0 3F  ?ZMMPM%???w?.??
+
+ +

+ Any read access to $DE00 will switch in bank 1 (if cart is 32Kb). Any + read access to $DF00 will switch off EXROM and GAME. + +

+ + + +

15.11.3.25 24 - Dela EP64

+ + + + + + + or 1 bank of 8Kb and 1 or 2 banks + of 32Kb each) + + + + + + + + + + + + +
Size8Kb to 72kb sizes (1 to 9 banks of 8Kb each,
GAMEinactive (0)
EXROMactive (1)
Load address$8000-9FFF
+ + +
+      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  C64?CARTRIDGE???
+0010: 00 00 00 40 01 00 00 18 00 01 00 00 00 00 00 00  ???@????????????
+0020: 44 45 4C 41 20 45 50 36 34 00 00 00 00 00 00 00  DELA?EP64???????
+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????????.???
+0050: 00 85 5E FE C3 C2 CD 38 30 FF FF FF FF FF FF FF  ?^....80???????
+...
+2050: 43 48 49 50 00 00 80 10 00 00 00 01 80 00 80 00  CHIP??.?????.?.?
+2060: 54 45 53 54 0D 2A 0D 54 45 20 36 34 0D 00 00 00  TEST?*?TE?64????
+
+ +

+ This is an eprom cartridge. It has 1 2764 (8Kb) which holds the base + eprom with the base menu, and 2 27256 eproms of which 8Kb parts are + banked into the $8000-9FFF area. + +

+

+ The bank selecting is done by writing to $DE00. The following bits are + used for bank decoding in $DE00 (0 being the LSB, 3 being the MSB). + +

+ +
+         Bit# 76543210
+              xx10xx32
+
+ +

+ Any bank value below 4 or above 11 switches in the base bank (bank 0). + +

+

+ The bit values for each eprom bank are : + +

+ +
+    eprom bank 1 : xx00xx01
+    eprom bank 2 : xx01xx01
+    eprom bank 3 : xx10xx01
+    eprom bank 4 : xx11xx01
+    eprom bank 5 : xx00xx10
+    eprom bank 6 : xx01xx10
+    eprom bank 7 : xx10xx10
+    eprom bank 8 : xx11xx10
+
+ +

+ Setting bit 7 high will switch off EXROM. + +

+ + + +

15.11.3.26 25 - Dela EP7x8

+ + + + + + + + + + + + + + + + + + +
Size8Kb to 64kb sizes (1 to 8 banks of 8Kb each)
GAMEinactive (0)
EXROMactive (1)
Load address$8000-9FFF
+ + +
+      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  C64?CARTRIDGE???
+0010: 00 00 00 40 01 00 00 19 00 01 00 00 00 00 00 00  ???@????????????
+0020: 44 45 4C 41 20 45 50 37 78 38 00 00 00 00 00 00  DELA?EP7x8??????
+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????????.???
+0050: 09 80 5E FE C3 C2 CD 38 30 78 A2 FF 9A D8 8E 16  ?.^....80x.?..?
+...
+2050: 43 48 49 50 00 00 20 10 00 00 00 01 80 00 20 00  CHIP????????.???
+2060: 94 83 A0 83 C3 C2 CD 38 30 02 BB 5A 30 5F EE 3D  ...80?Z0_?=
+
+ +

+ This is an eprom cartridge. It has 8 8Kb banks of which the first holds + the base menu, the other eproms can be banked into the $8000-9FFF area. + +

+

+ The bank selecting is done by writing to $DE00. Each low bit is used to + bank in the respective eprom. If all bits are high then the EXROM is + switched off. + +

+

+ The bit values for each eprom bank is: + +

+ +
+    eprom bank 1 : 11111110 ($FE) (base eprom)
+    eprom bank 2 : 11111101 ($FD)
+    eprom bank 3 : 11111011 ($FB)
+    eprom bank 4 : 11110111 ($F7)
+    eprom bank 5 : 11101111 ($EF)
+    eprom bank 6 : 11011111 ($DF)
+    eprom bank 7 : 10111111 ($BF)
+    eprom bank 8 : 01111111 ($7F)
+
+    EXROM off    : 11111111 ($FF)
+
+ + + +

15.11.3.27 26 - Dela EP256

+ + + + + + + + + + + + + + + + + + +
Size8Kb to 262kb sizes (1 to 33 banks of 8Kb each)
GAMEinactive (0)
EXROMactive (1)
Load address$8000-9FFF
+ + +
+      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  C64?CARTRIDGE???
+0010: 00 00 00 40 01 00 00 1A 00 01 00 00 00 00 00 00  ???@????????????
+0020: 44 45 4C 41 20 45 50 32 35 36 00 00 00 00 00 00  DELA?EP256??????
+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????????.???
+0050: 00 85 5E FE C3 C2 CD 38 30 93 0D 2B 2B 2B 20 45  ?^....80.?+++?E
+...
+2050: 43 48 49 50 00 00 20 10 00 00 00 01 80 00 20 00  CHIP????????.???
+2060: 09 80 28 80 C3 C2 CD 38 30 78 A2 05 8E 16 D0 20  ?.(....80x.??.?
+...
+4060: 43 48 49 50 00 00 20 10 00 00 00 02 80 00 20 00  CHIP????????.???
+4070: 0B 80 BC FE C3 C2 CD 38 30 DC 10 8E 16 D0 20 87  ?.?....80.??.?.
+...
+6070: 43 48 49 50 00 00 20 10 00 00 00 03 80 00 20 00  CHIP????????.???
+6080: 09 80 F6 8E C3 C2 CD 38 30 A2 C8 8E 16 D0 20 ..  ?.?...80..?.?.
+...
+8080: 43 48 49 50 00 00 20 10 00 00 00 04 80 00 20 00  CHIP????????.???
+8090: 94 83 A0 83 C3 C2 CD 38 30 02 BB 5A 30 5F EE 3D  ...80?Z0_?=
+
+ +

+ This is an eprom cartridge. It has 33 8Kb banks of which the first + holds the base menu, the other eproms can be banked into the $8000-9FFF + area. + +

+

+ The bank selecting is done by writing to $DE00. + +

+

+ The values for the (extra) eprom banks are: + +

+ +
+    eprom banks  1- 8 : $38-3F
+    eprom banks  9-16 : $28-2F
+    eprom banks 17-24 : $18-1F
+    eprom banks 25-32 : $08-0F
+
+ +

+ Setting bit 7 high will switch off EXROM. + +

+ + + +

15.11.3.28 27 - Rex EP256

+ + + + + + + 8Kb, 16Kb or 32Kb) + + + + + + + + + + + + +
Size8Kb to 262kb sizes (1 bank of 8Kb and 1 to 8 banks of either
GAMEinactive (0)
EXROMactive (1)
Load address$8000-9FFF
+ + +
+      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  C64?CARTRIDGE???
+0010: 00 00 00 40 01 00 00 1B 00 01 00 00 00 00 00 00  ???@????????????
+0020: 52 45 58 20 45 50 32 35 36 00 00 00 00 00 00 00  REX?EP256???????
+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????????.???
+0050: 09 80 C1 FE C3 C2 CD 38 30 20 A3 FD 20 50 FD 20  ?......80?.?P.?
+...
+2050: 43 48 49 50 00 00 20 10 00 00 00 01 80 00 20 00  CHIP????????.???
+2060: 09 80 F2 8F C3 C2 CD 38 30 A2 C8 8E 16 D0 20 A3  ?.?...80..?.?
+...
+4060: 43 48 49 50 00 00 40 10 00 00 00 02 80 00 40 00  CHIP??@?????.?@?
+4070: 09 80 09 80 C3 C2 CD 38 30 58 D8 20 84 FF 20 8A  ?.?....80X.???
+
+ +

+ This is an eprom cartridge. It has 9 eprom sockets, of which the first + holds the base eprom with the base menu which is an 8Kb eprom, the + other eprom sockets can handle 8Kb, 16Kb or 32Kb eproms, of which 8kb + can be banked into the $8000-9FFF area. + +

+

+ The bank selecting is done by writing to $DFA0. Bits 2, 1 and 0 + determine which socket is used and bits 5 and 4 are used to select an + 8Kb piece of the eprom. + +

+

+ The possible values for bits 5 and 4 for the (extra) eprom banks are: + +

+ +
+     8Kb        : 3, 2, 1, 0
+
+    16Kb bank 0 : 2, 0
+    16Kb bank 1 : 3, 1
+
+    32Kb bank 0 : 0
+    32Kb bank 1 : 1
+    32Kb bank 2 : 2
+    32Kb bank 3 : 3
+
+ +

+ Reading from $DFC0 switches off the EXROM. + Reading from $DFE0 switches on the EXROM. + +

+ + +

15.11.3.29 28 - Mikro Assembler

+ + + + + + + + + + + + + + + + + + +
Size8Kb (1 bank of 8Kb)
GAMEinactive (0)
EXROMactive (1)
Load address$8000-9FFF
+ + +
+      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  C64?CARTRIDGE???
+0010: 00 00 00 40 01 00 00 1C 00 01 00 00 00 00 00 00  ???@????????????
+0020: 56 49 43 45 20 43 41 52 54 00 00 00 00 00 00 00  VICE CART???????
+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????????.???
+0050: 60 80 FE 80 C3 C2 CD 38 30 4C 07 87 4C CA 82 41  `......80L?.L.A
+
+ +

+ The $9E00-$9EFF range is mirrored at $DE00-$DEFF. The $9F00-$9FFF range + is mirrored at $DF00-$DFFF. + +

+ + +

15.11.3.30 29 - Final Cartridge Plus

+ + + + + + + + + + + + + + + + + + +
Size32Kb (1 bank of 32Kb)
GAMEactive (1)
EXROMactive (1)
Load address$0000-$7FFF
+ + +
+      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  C64?CARTRIDGE???
+0010: 00 00 00 40 01 00 00 1D 00 01 00 00 00 00 00 00  ???@????????????
+0020: 56 49 43 45 20 43 41 52 54 00 00 00 00 00 00 00  VICE?CART???????
+0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ????????????????
+0040: 43 48 49 50 00 00 80 10 00 00 00 00 00 00 80 00  CHIP??.???????.?
+0050: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF  ????????????????
+
+ +

+ This cart has 32Kb of ROM, bank 0 is in the cart image but is unused. + The first 8Kb of the cart image is unused, the second 8Kb of the cart + image is mapped to $E000-$FFFF, the third 8Kb of the cart image is + mapped to $8000-$9FFF and the fourth 8Kb of the cart image is mapped + to $A000-$BFFF. An NMI can be triggered by the cart, if address $0001 + is written to and the cartridge is enabled. The cart can be disabled + by software, by clearing bit 4 when writing to $DF00-$DFFF. Cart ROM + at $E000-$FFFF can be disabled by setting bit 5 to 0 when writing to + $DF00-$DFFF. Cart ROM at $8000-$BFFF can be disabled by setting bit 6 + to 1 when writing to $DF00-$DFFF. Bit 7 of a byte written to + $DF00-$DFFF can be read back from the cartridge if enabled (like a + memory cell). + +

+ + +

15.11.3.31 30 - Action Replay 4

+ + + + + + + + + + + + + + + + + + +
Size32Kb (4 banks of 8Kb)
GAMEactive (1)
EXROMinactive (0)
Load address$8000-$9FFF
+ + +
+      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  C64?CARTRIDGE???
+0010: 00 00 00 40 01 00 00 1E 00 01 00 00 00 00 00 00  ???@????????????
+0020: 56 49 43 45 20 43 41 52 54 00 00 00 00 00 00 00  VICE?CART???????
+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????????.???
+0050: EA 78 48 A9 7F 8D 0D DD D0 0E 48 AD 0D DD 10 04  .xP.??..?P?.??
+...
+2050: 43 48 49 50 00 00 20 10 00 00 00 01 80 00 20 00  CHIP????????.???
+2060: 09 80 0C 80 C3 C2 CD 38 30 4C E9 80 4C 81 81 4C  ?.?....80L?.LL
+...
+4060: 43 48 49 50 00 00 20 10 00 00 00 02 80 00 20 00  CHIP????????.???
+4070: 09 80 0E 80 C3 C2 CD 38 30 A2 00 4C EF FC 20 BC  ?.?....80.?L?.??
+...
+6070: 43 48 49 50 00 00 20 10 00 00 00 03 80 00 20 00  CHIP????????.???
+6080: 09 80 0C 80 C3 C2 CD 38 30 4C 70 88 4C 3F 80 4C  ?.?....80LpL?.L
+
+ +

+ The control register is the I/O-1 range: + +

+ +
+    bit  meaning
+    ---  -------
+    0    Eprom banking bit 0 (bank address 13)
+    1    Controls the GAME line (0 sets GAME low, 1 sets GAME high)
+    2    Freeze-end bit (disables the register and hides any rom bank)
+    3    Controls the Exrom line (1 sets EXROM low, 0 sets EXROM high)
+    4    Eprom banking bit 1 (bank address 14)
+    5-7  Unused
+
+ +

+ The first page of the currently banked ROM block can be read in the + I/O-2 range. + +

+ + +

15.11.3.32 31 - Stardos

+ + + + + + + + + + + + + + + + + + + $E000-$FFFF (bank 1) +
Size16Kb (2 banks of 8Kb)
GAMEactive (1)
EXROMinactive (0)
Load address$8000-$9FFF (bank 0),
+ + +
+      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  C64?CARTRIDGE???
+0010: 00 00 00 40 01 00 00 1F 00 01 00 00 00 00 00 00  ???@????????????
+0020: 56 49 43 45 20 43 41 52 54 00 00 00 00 00 00 00  VICE?CART???????
+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????????.???
+0050: F9 80 B6 80 C3 C2 CD 38 30 FD 80 89 80 4C 0C 88  ?.....80...L?
+...
+2050: 43 48 49 50 00 00 20 10 00 00 00 00 E0 00 20 00  CHIP????????????
+2060: 85 56 20 0F BC A5 61 C9 88 90 03 20 D4 BA 20 CC  V???a.??.?.
+
+ +

+ This cart has 16Kb of ROM, of which the first 8Kb is mapped in at + $8000-$9FFF and the second 8Kb is used as a kernel replacement. The + kernel replacement is achieved by a clip that needs to be installed + inside the C64. + +

+

+ Reading from I/O-1 causes a capacitor to get charged with every read, + once the capacitor is charged enough it switches the cart on. + +

+

+ Reading from I/O-2 causes a different capacitor to get charged with + every read, once the capacitor is charged enough it switched the cart + off. + +

+ + +

15.11.3.33 32 - EasyFlash

+ + + + + + + + + + + + + + + + + + +
Size1024Kb (64 banks of 2 * 8Kb)
GAMEinactive (0)
EXROMactive (1)
Load address$8000-$9FFF (ROML), $A000-$BFFF or $E000-$FFFF (ROMH)
+ + +
+      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  C64?CARTRIDGE???
+0010: 00 00 00 40 01 00 00 20 00 01 00 00 00 00 00 00  ???@????????????
+0020: 45 61 73 79 46 6C 61 73 68 20 43 61 72 74 72 69  EasyFlash?Cartri
+0030: 64 67 65 00 00 00 00 00 00 00 00 00 00 00 00 00  dge?????????????
+0040: 43 48 49 50 00 00 20 10 00 00 00 01 80 00 20 00  CHIP????????.???
+0050: 00 85 5E FE C3 C2 CD 38 30 93 0D 2B 2B 2B 20 45  ?^....80.?+++?E
+
+ +

+ EasyFlash is a 1 MByte Flash EPROM card with multiple configurations + and banks possible, it also has 256 bytes of RAM which is mapped into + the I/O-2 range. + +

+

+ There are two control registers, one at $DE00 and one at $DE02. + +

+

+ The register at $DE00 does the following: + +

+ +
+    bit  meaning
+    ---  -------
+    7    LED control
+    6-3  Unused
+    2    Mode (0/1)
+    1    Exrom line control
+    0    Game line control
+
+ +

+ The register at $DE02 controls which bank is mapped into ROMH and + ROML. + +

+ + +

15.11.3.34 33 - EasyFlash Xbank

+ + + + + + + + + + + + + + + + + + +
Size-
GAME-
EXROM-
Load address-
+ +

+This CRT type is not actually related to a seperate hardware, it is used by some +EasyFlash related tools as a container format. Consequently VICE does (can) not +load files of this type. + +

+ + +

15.11.3.35 34 - Capture

+ + + + + + + + + + + + + + + + + + +
Size8Kb (1 bank of 8Kb)
GAMEinactive (0)
EXROMinactive (0)
Load address$E000-$FFFF
+ + +
+      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  C64?CARTRIDGE???
+0010: 00 00 00 40 01 00 00 22 00 01 00 00 00 00 00 00  ???@???"????????
+0020: 4D 61 67 69 63 20 46 6F 72 6D 65 6C 00 00 00 00  Magic?Formel????
+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 01 E0 00 20 00  CHIP????????????
+0050: 00 0A 0D 8A B4 A1 20 80 00 0A 82 8A 8D 20 9E 20  ????.?.????
+
+ +

+ This cart has 8Kb of ROM which is mapped to $E000, and 8Kb of RAM + which is mapped to $6000. The cartridge is disabled after a reset. + +

+

+ When the freeze button is pressed the following happens: + +

+ +
    +
  • an NMI is generated + +
  • as soon as the current adress is in bank 0xfe the cart switches to + + ultimax mode. The cart ROM then contains one page full of + "jmp $eaea", which ultimately calls the freezer code. +
  • the $FFF7/$FFF8 "register" logic is enabled and any access (read or + + write) to $FFF7 will turn the cart_enabled off (leave ultimax mode), + and an access to $FFF8 will turn the cart back on (enter ultimax + mode). the "register logic" that causes this can only be disabled + again by a hardware reset. +
+ + + +

15.11.3.36 35 - Action Replay 3

+ + + + + + + + + + + + + + + + + + +
Size16Kb (2 banks of 8Kb)
GAMEactive (1)
EXROMinactive (0)
Load address$8000-$9FFF
+ + +
+      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  C64?CARTRIDGE???
+0010: 00 00 00 40 01 00 00 23 00 01 00 00 00 00 00 00  ???@???#????????
+0020: 56 49 43 45 20 43 41 52 54 00 00 00 00 00 00 00  VICE?CART???????
+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????????.???
+0050: EA A9 E3 48 A9 7B 48 08 4C 1A 80 EA EA EA 48 AD  ...H..H?L?....H
+...
+2050: 43 48 49 50 00 00 20 10 00 00 00 01 80 00 20 00  CHIP????????.???
+2060: 09 80 5E FE C3 C2 CD 38 30 78 A2 FB D8 9A A9 27  ?.^....80x.....'
+
+ +

+ This cart has 16Kb of ROM of which 8Kb is mapped in at both ROML and + ROMH. Bank switching and control register is done through the I/O-1 + range: + +

+ +
+    bit  meaning
+    ---  -------
+    7-4  unused
+    3    Exrom line control
+    2    Disable cart
+    1    Unused
+    0    Bank
+
+ + + +

15.11.3.37 36 - Retro Replay

+ + + + + + + + + + + + + + + + + + +
Size32Kb, 64Kb or 128Kb (4, 8 or 16 banks of 8Kb)
GAMEinactive (0)
EXROMinactive (0)
Load address$8000-$9FFF
+ + +
+      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  C64?CARTRIDGE???
+0010: 00 00 00 40 01 00 00 24 00 00 00 00 00 00 00 00  ???@???$????????
+0020: 56 49 43 45 20 43 41 52 54 00 00 00 00 00 00 00  VICE?CART???????
+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????????.???
+0050: 09 80 0C 80 C3 C2 CD 38 30 4C 7F 81 4C 87 81 4C  ?.?....80L?L.L
+
+ +

+ The Retro Replay has three registers: Two write-only ($DE00 & $DE01) + and one read-only register ($DE00 & $DE01 giving the same results). + +

+

+ The register at $DE00 is reset to $00 on a hard reset if not in flash + mode. If in flash mode, it is set to $02 in order to prevent the + computer from starting the normal cartridge. Flash mode is selected + with a jumper. + +

+

+ Register at $DE00: + +

+ +
+    bit  meaning
+    ---  -------
+    0    Controls the GAME line: A 1 asserts the line, a 0  will  deassert
+         it.
+    1    Controls the EXROM line: A 0 will assert it, a  1  will  deassert
+         it.
+    2    Writing a 1 will disable further write accesses to all  registers
+         of the Retro Replay, and  set  the  memory  map  of  the  C64  to
+         standard, as if there is no cartridge installed at all.
+    3    Controls bank-address 13 for ROM and RAM banking.
+    4    Controls bank-address 14 for ROM and RAM banking.
+    5    Switches between ROM and RAM: 0=ROM, 1=RAM
+    6    Must be written once to "1" after a successful freeze in order to
+         set the correct memory map and  enable  bits  0  and  1  of  this
+         register. Otherwise no effect.
+    7    Controls bank-address 15 for ROM banking.
+
+ +

+ The register at $DE01 is the extended control register. If not in + Flash mode, bits 1, 2 and 6 can only be written once. If in Flash + mode, the REUcomp bit cannot be set, but the register will not be + disabled by the first write. Bit 5 is always set to 0 if not in Flash + mode. + +

+

+ Register at $DE01: + +

+ +
+    bit  meaning
+    ---  -------
+    0    Enable clockport connector.
+    1    AllowBank (1 allows banking of RAM in $DF00/$DE02 area)
+    2    NoFreeze (1 disables Freeze function)
+    3    Bank-address 13 for RAM and ROM (mirror of $DE00)
+    4    Bank-address 14 for RAM and ROM (mirror of $DE00)
+    5    Bank-address 16 for ROM (only in flash mode)
+    6    REU compatibility bit. 0=standard memory map, 1 = REU  compatible
+         memory map
+    7    Bank-address 15 for ROM (mirror of $DE00)
+
+ +

+ Reading from the registers at either $DE00 or $DE01 will return the + content of the status register. + +

+

+ Status register: + +

+ +
+    bit  meaning
+    ---  -------
+    0    1=Flashmode active (jumper set)
+    1    feedback of AllowBank bit
+    2    1=Freeze button pressed
+    3    feedback of banking bit 13
+    4    feedback of banking bit 14
+    5    feedback of banking bit 16
+    6    1=REU compatible memory map active
+    7    feedback of banking bit 15
+
+ +

+ The following memory maps are available: + +

+ +
    +
  • standard - + + $DE00 and $DE01 registers are active, $DF00-$DFFF contain the last + page of the selected 8Kb bank of either ROM or RAM, whatever is + selected. RAM can only be accessed in $8000-$9FFF. ROM can be mapped + to $8000, $A000 or $E000 with the corresponding status on GAME and + EXROM. + + Note: If the AllowBank bit is not set, the $DF00-$DFFF area will + always access bank 0 of the RAM, so the older cartridge images will + work. The AllowBank bit does not have any effect on the ROM mirror in + that area. + +
  • Freeze - + + ROM is mapped to $E000-$FFFF, bank 0 is active directly after Freeze. + Writing to bits 0 and 1 of the $DE00 register will have no effect on + GAME and EXROM. RAM can be selected and used in $DF00 or $DE02, + respectively, but not in $8000. Banking bits work, so you have full + read access to the ROM, and access to up to four RAM pages with the + AllowBank bit set (minus 2 bytes if REU compatible bit is set). You + should leave this memory map ASAP by setting bit 6 of $DE00, because + C64 RAM in the $E000 area is not available, and you don't have control + of the GAME and EXROM lines. + +
  • REU compatible - + + $DE00 and $DE01 registers are active, $DE02-$DEFF contain a mirror of + $9E02-$9EFF of the selected 8K-bank of either ROM or RAM, whatever is + selected. RAM can only be accessed in $8000-$9FFF. ROM can be mapped + to $8000, $A000 or $E000 with the corresponding status on GAME and + EXROM. The $DF00 stays free for use with the 1764 Ram Expansion Unit + (REU). + + Note: If the AllowBank bit is not set, the $DE02-$DEFF area will + always access bank 0 of the RAM, so the older cartridge images will + work. The AllowBank bit does not have any effect on the ROM mirror in + that area. +
+ + + +

15.11.3.38 37 - MMC64

+ + + + + + + + + + + + + + + + + + +
Size8Kb (1 bank of 8Kb)
GAMEactive (1)
EXROMinactive (0)
Load address$8000-$9FFF
+ + +
+      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  C64?CARTRIDGE???
+0010: 00 00 00 40 01 00 00 25 00 01 00 00 00 00 00 00  ???@???%????????
+0020: 56 49 43 45 20 43 41 52 54 00 00 00 00 00 00 00  VICE?CART???????
+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????????.???
+0050: 09 80 64 97 C3 C2 CD 38 30 78 D8 A2 FF 9A 20 D4  ?.d...80x..?.?.
+
+ +

+ The clockport registers of this cart can be switched to either + $DE01-$DE0F or $DF21-$DF2F. The control registers are available at + $DF10-$DF13. + +

+

+ The register at $DE01 / $DF21 is write only: + +

+ +
+    bit  meaning
+    ---  -------
+    7-1  Unused
+    0    0 = disable clock port, 1 = enable clockport
+
+ +

+ The registers at $DE02-$DE0F / $DF22-$DF2F are for the clock port and + are read/write. + +

+

+ The register at $DF10 is the MMC64 SPI transfer register, a byte + written to this registers is sent to the card & response from the card + is read here. + +

+

+ The register at $DF11 is the MMC64 control register: + +

+ +
+    bit  meaning
+    ---  -------
+    0    0 = MMC64 BIOS active, 1 = external ROM active
+    1    0 = card selected, 1 = card not selected
+    2    0 = 250khz transfer, 1 = 8mhz transfer
+    3    0 = clock port @ $DE00, 1 = clock port @ $DF20
+    4    0 = normal Operation, 1 = flash mode (*)
+    5    0 = allow external rom when BIOS is disabled,
+         1 = disable external ROM
+    6    0 = SPI write trigger mode, 1 = SPI read trigger mode
+    7    0 = MMC64 is active, 1 = MMC64 is completely disabled (**)
+
+ +

+ (*) bit can only be programmed when flash jumper is set + (**) bit can only be modified after unlocking + +

+

+ The register at $DF12 is the MMC64 status register, which is + read-only: + +

+ +
+    bit  meaning
+    ---  -------
+    0    0 = SPI ready, 1 = SPI busy
+    1    external GAME line
+    2    external EXROM line
+    3    0 = card inserted, 1 = no card inserted
+    4    0 = card write enabled, 1 = card write disabled
+    5    0 = flash jumper not set, 1 = flash jumper set
+    6-7  unused
+
+ +

+ The register at $DF13 is the MMC64 identification register, which when + reading from it can have the following values: + +

+

+ $64 when bit 1 of $DF11 is 0. + $01 when bit 1 of $DF11 is 1 and REV A hardware is used. + $02 when bit 1 of $DF11 is 1 and REV B hardware is used. + +

+

+ when writing to it it can be used to unlock bit 7 of $DF11 or to + re-enable the cart: + +

+

+ Write $55 & $AA into this register to unlock bit 7 of $DF11. + Write $0A & $1C into this register to re-enable MMC64 hardware. + +

+ + +

15.11.3.39 38 - MMC Replay

+ + + + + + + + + + + + + + + + + + +
Size64Kb or 512Kb (8 or 64 banks of 8Kb)
GAMEinactive (0)
EXROMinactive (0)
Load address$8000-$9FFF
+ + +
+      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  C64?CARTRIDGE???
+0010: 00 00 00 40 01 00 00 26 00 00 00 00 00 00 00 00  ???@???&????????
+0020: 56 49 43 45 20 43 41 52 54 00 00 00 00 00 00 00  VICE?CART???????
+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????????.???
+0050: 1A 80 6E 9E C3 C2 CD 38 30 4D 4D 43 52 45 50 4C  ?.n...80MMCREPL
+
+ +

+ The cart uses the following registers: + +

+

+ $DE00 - RR control register write + +

+ +
+    bit  meaning
+    ---  -------
+    0    GAME line
+    1    EXROM line
+    2    1 = disable RR, bit can be reset by setting bit 6 of $DF12
+    3    bank address 13
+    4    bank address 14
+    5    0 = rom enable, 1 = ram enable
+    6    1 = exit freeze mode
+    7    bank address 15
+
+ +

+ $DE01 - extended RR control register write + +

+ +
+    bit  meaning
+    ---  -------
+    0    0 = disable clockport, 1 = enable clockport
+    1    0 = disable I/O RAM banking, 1 = enable I/O RAM banking
+    2    0 = enable freeze, 1 = disable freeze
+    3    bank address 13 (mirror of $DE00)
+    4    bank address 14 (mirror of $DE00)
+    5    0 = enable MMC registers, 1 = disable MMC registers. Can only  be
+         written when bit 6 of $DF12 is 1. Register becomes effective when
+         bit 0 of $DF11 is 1.
+    6    0 = RAM/ROM at $DFxx, 1 = RAM/ROM at $DExx
+    7    bank address 15 (mirror of $DE00)
+
+ +

+ $DE02-$DE0F - Clockport memory area (when enabled) + +

+

+ $DF10 - MMC SPI transfer register, a byte written is sent to the card + & response from the card is read here. + +

+

+ $DF11 - MMC control register + +

+ +
+    bit  meaning
+    ---  -------
+    0    0 = MMC BIOS enabled, 1 = MMC BIOS disabled.  Enabling  MMC  BIOS
+         sets ROM banking to the last 64Kb bank.
+    1    0 = card selected, 1 = card not selected. This bit also  controls
+         the green activity LED.
+    2    0 = 250khz transfer, 1 = 8mhz transfer
+    3    ALWAYS 0
+    4    ALWAYS 0
+    5    (in RR-Mode:)
+          0 = allow RR rom when MMC BIOS disabled , 1 = disable RR ROM
+          (in mmcreplay bios mode:)
+          RAM banking (0 = $E000 - $FFFF, 1 = $8000 - $9FFF)
+          (in 16K mode:)
+          enable RAM at $A000 - $BFFF
+    6    0 = SPI write trigger mode, 1 = SPI read trigger mode
+    7    ALWAYS 0
+
+ +

+ $DF12 - MMC status register + +

+ +
+    bit  meaning
+    ---  -------
+    0    0 = SPI ready, 1 = SPI busy (read)
+                        1 = forbid ROM  write  accesses  (write).  Setting
+                        this bit will disable writes  to  ROM  until  next
+                        reset
+    1  feedback of $DE00 bit 0 (GAME)
+    2  feedback of $DE00 bit 1 (EXROM)
+    3  0 = card inserted, 1 = no card inserted
+    4  0 = card write enabled, 1 = card write disabled
+    5  EEPROM DATA line /  DDR  register.  Setting  DATA  to  "1"  enables
+       reading data bit from EEPROM at this position.
+    6  0 = RR compatibility mode, 1 = Extended mode
+       Selecting RR compatibility mode limits RAM  to  32Kb  and  disables
+       writes  to  extended  banking  register.  Selecting  Extended  mode
+       enables full RAM banking and enables Nordic Power mode in RR mode.
+    7  EEPROM CLK line
+
+ +

+ $DF13 - Extended banking register + Can only be read/written to when bit 6 of $DF12 is 1 + +

+ +
+    bit  meaning
+    ---  -------
+    0    bank address 16
+    1    bank address 17
+    2    bank address 18
+    3    ALWAYS 0
+    4    ALWAYS 0
+    5    16K rom mapping
+    6    1 = enable  RR  register.  Disabling  RR  register  disables  ALL
+         ROM/RAM banking too.
+    7    ALWAYS 0
+
+ + + +

15.11.3.40 39 - IDE64

+ + + + + + + + + + + + + + + + + + +
Size64Kb or 128Kb (8 or 16 banks of 8Kb)
GAMEinactive (0)
EXROMinactive (0)
Load address$8000-$9FFF
+ + +
+      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  C64?CARTRIDGE???
+0010: 00 00 00 40 01 00 00 26 00 00 00 00 00 00 00 00  ???@???'????????
+0020: 56 49 43 45 20 43 41 52 54 00 00 00 00 00 00 00  VICE?CART???????
+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????????.???
+0050: 63 80 5E FE C3 C2 CD 38 30 20 49 44 45 36 34 20  c.^....80?IDE64?
+
+ +

+ The IDE64 cart uses the following registers: + +

+ +
+    $DE20 - $DE27  Primary HDD Registers
+    $DE28 - $DE2F  Secondary HDD Registers
+    $DE30 - Low Data HDD register
+    $DE31 - High Data HDD register
+
+ +

+ $DE32 register: + +

+ +
+    bit  meaning
+    ---  -------
+    7    unused (0)
+    6    unused (0)
+    5    unused (0)
+    4    version number (1)
+    3    romaddr15
+    2    romaddr14
+    1    game
+    0    exrom
+
+ + +
+    $DE33 - $DE35 = IDE64 ROM bank select registers
+    $DE5F         = RTC access (bit 0 only to serial accessed RTC)
+    $DE60 - $DEFA = RAM used by software
+    $DEFB         = IDE64 clock reset, kill the cartridge
+    $DEFC - $DEFF = IDE64 ROM configuration registers
+
+ + + +

15.11.3.41 40 - Super Snapshot V4

+ + + + + + + + + + + + + + + + + + +
Size32Kb (4 banks of 8Kb)
GAMEactive (1)
EXROMinactive (0)
Load address$8000-$9FFF
+ + +
+      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  C64?CARTRIDGE???
+0010: 00 00 00 40 01 00 00 28 00 01 00 00 00 00 00 00  ???@???(????????
+0020: 56 49 43 45 20 43 41 52 54 00 00 00 00 00 00 00  VICE?CART???????
+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????????.???
+0050: 80 AD B5 80 C3 C2 CD 38 30 08 48 A9 06 8D 00 DF  .....80?P.???
+...
+2050: 43 48 49 50 00 00 20 10 00 00 00 00 A0 00 20 00  CHIP???????????
+2060: 4C FA A0 A9 07 8D 00 DD 2C 00 DD 50 FB 2C 00 DD  L?.??.,?.P.,?.
+...
+4060: 43 48 49 50 00 00 20 10 00 00 00 01 80 00 20 00  CHIP????????.???
+4070: 13 80 BC FE C3 C2 CD 38 30 08 48 A9 02 8D 00 DF  ?.?....80?H.???
+...
+6070: 43 48 49 50 00 00 20 10 00 00 00 01 A0 00 20 00  CHIP???????????
+6080: F0 8A 48 A9 00 85 22 85 23 8D 53 0F 20 0C A1 B0  ?H.?"#S???.
+
+ +

+ This cart has 32Kb of ROM and 8Kb of RAM, it uses I/O-1 as a mirror of + the last page of cart RAM. It has the following registers in the I/O-2 + range: + +

+

+ ROM config register at $DF00 (can only be written to): + +

+ +
+    bit  meaning
+    ---  -------
+    0    ?
+    1    ? (write 1 to release freeze mode)
+    2    ROM bank select
+    3    write 1 to disable cartridge
+    4-6  unused
+    7    ?
+
+ +

+ Note: if bit0, bit1, bit7 are all 0, then ultimax mapping is selected + and RAM is enabled at ROML, otherwise if bit 0 is 0, then 16Kb mapping + is enabled, or if bit 0 is 1, then 8Kb mapping is enabled. + +

+

+ RAM config register at $DF01 (read/write): + +

+

+ If written value == last value - 1, then ultimax mapping is selected + and RAM is enabled at ROML, if written value == last value + 1, then + ROM is enabled at ROML and exrom is deasserted (switch to either 8k or + 16k mapping) + +

+

+ $DF02-$DFFF holds the last page of the first 8kb of the current bank. + +

+ + +

15.11.3.42 41 - IEEE-488

+ + + + + + + + + + + + + + + + + + +
Size4Kb (1 bank of 4Kb)
GAMEactive (1)
EXROMinactive (0)
Load address$8000-$8FFF
+ + +
+      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  C64?CARTRIDGE???
+0010: 00 00 00 40 01 00 00 29 00 01 00 00 00 00 00 00  ???@???)????????
+0020: 56 49 43 45 20 43 41 52 54 00 00 00 00 00 00 00  VICE?CART???????
+0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ????????????????
+0040: 43 48 49 50 00 00 10 10 00 00 00 00 80 00 10 00  CHIP????????.???
+0050: 09 80 7A 80 C3 C2 CD 38 30 8E 16 D0 20 84 FF 20  ?.z....80?.???
+
+ +

+ The cart uses a TPI for the IEEE488 interface/communication in the + I/O-2 range: + +

+ +
+    $DF00 - Port A Data
+    $DF01 - Port B Data
+    $DF02 - Port C Data
+    $DF03 - Port A Direction
+    $DF04 - Port B Direction
+    $DF05 - Port C Direction
+    $DF06 - Control register
+    $DF07 - Active Interrupt register
+
+ + + +

15.11.3.43 42 - Game Killer

+ + + + + + + + + + + + + + + + + + +
Size8Kb (1 bank of 8Kb)
GAMEinactive (0)
EXROMinactive (0)
Load address$E000-$FFFF
+ + +
+      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  C64?CARTRIDGE???
+0010: 00 00 00 40 01 00 00 2A 00 00 00 00 00 00 00 00  ???@???*????????
+0020: 56 49 43 45 20 43 41 52 54 00 00 00 00 00 00 00  VICE?CART???????
+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 E0 00 20 00  CHIP????????????
+0050: 00 25 08 CF 07 9E 32 30 38 38 20 4D 43 2E 43 52  ?%?.?2088?MC.CR
+
+ +

+ When the cartridge is active, ultimax is enabled when the address + being accessed is is the $E000-$FFFF range, so the ROM is visible at + $E000, below is normal C64 RAM. The cart can be disabled by writing to + either I/O-1 or I/O-2 range. When the freezer button is pressed, the + cartridge will be enabled and an NMI will be triggered. + +

+ + +

15.11.3.44 43 - Prophet64

+ + + + + + + + + + + + + + + + + + +
Size256Kb (32 banks of 8Kb)
GAMEactive (1)
EXROMinactive (0)
Load address$8000-$9FFF
+ + +
+      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  C64?CARTRIDGE???
+0010: 00 00 00 40 01 00 00 2B 00 01 00 00 00 00 00 00  ???@???+????????
+0020: 56 49 43 45 20 43 41 52 54 00 00 00 00 00 00 00  VICE?CART???????
+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????????.???
+0050: 09 80 09 80 C3 C2 CD 38 30 78 A0 00 84 F8 84 FA  ?.?....80x???
+
+ +

+ The control register is the I/O-2 range: + +

+ +
+    bit  meaning
+    ---  -------
+    7-6  unused
+    5    disable cart
+    4-0  bank select
+
+ + + +

15.11.3.45 44 - EXOS

+ + + + + + + + + + + + + + + + + + +
Size8Kb (1 bank of 8Kb)
GAMEinactive (0)
EXROMactive (1)
Load address$E000-$FFFF
+ + +
+      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  C64?CARTRIDGE???
+0010: 00 00 00 40 01 00 00 2C 01 00 00 00 00 00 00 00  ???@???,????????
+0020: 56 49 43 45 20 43 41 52 54 00 00 00 00 00 00 00  VICE?CART???????
+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 E0 00 20 00  CHIP????????????
+0050: 85 56 20 0F BC A5 61 C9 88 90 03 20 D4 BA 20 CC  V???a.??.?.
+
+ +

+ This cart has 8Kb of ROM, mapped in at $E000-$FFFF only when hirom is + selected. The cart uses a clip that needs to be installed inside the + C64. + +

+ + +

15.11.3.46 45 - Freeze Frame

+ + + + + + + + + + + + + + + + + + +
Size8Kb (1 bank of 8Kb)
GAMEactive (1)
EXROMinactive (0)
Load address$8000-$9FFF
+ + +
+      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  C64?CARTRIDGE???
+0010: 00 00 00 40 01 00 00 2D 00 01 00 00 00 00 00 00  ???@???-????????
+0020: 56 49 43 45 20 43 41 52 54 00 00 00 00 00 00 00  VICE?CART???????
+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????????.???
+0050: 10 80 10 80 C3 C2 CD 38 30 20 00 00 00 00 00 00  ?.?....80???????
+
+ +

+ When reading from the I/O-1 range the cart is enabled, when reading + from the I/O-2 range the cart is disabled. When the freeze button is + pressed the ROM is mapped to both $8000-$9FFF and $E000-$FFFF. + +

+ + +

15.11.3.47 46 - Freeze Machine

+ + + + + + + + + + + + + + + + + + +
Size16Kb or 32Kb (2 or 4 banks of 8Kb)
GAMEactive (1)
EXROMinactive (0)
Load address$8000-$9FFF
+ + +
+      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  C64?CARTRIDGE???
+0010: 00 00 00 40 01 00 00 2E 00 01 00 00 00 00 00 00  ???@???.????????
+0020: 56 49 43 45 20 43 41 52 54 00 00 00 00 00 00 00  VICE?CART???????
+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????????.???
+0050: 3A 83 60 80 C3 C2 CD 38 30 20 00 00 40 00 00 00  :`....80???@???
+...
+2050: 43 48 49 50 00 00 20 10 00 00 00 00 A0 00 20 00  CHIP???????? ???
+2060: 78 A9 34 85 01 A0 00 B1 F8 91 F6 E6 F8 D0 02 E6  x.4???.??.?
+...
+4060: 43 48 49 50 00 00 20 10 00 00 00 01 80 00 20 00  CHIP????????.???
+4070: 3A 83 60 80 C3 C2 CD 38 30 20 00 00 40 00 00 00  :`....80???@???
+...
+6070: 43 48 49 50 00 00 20 10 00 00 00 01 A0 00 20 00  CHIP???????? ???
+6080: 78 A9 34 85 01 A0 00 B1 F8 91 F6 E6 F8 D0 02 E6  x.4???.??.?
+
+ +

+ Warning, the following information is based on guess-work and might be + incorrect, any further information and/or corrections are appreciated. + +

+

+ When reading from the I/O-1 range ROM bank 0(/2) is mapped to + $8000-$9FFF and ROM bank 1(/3) is mapped to $A000-$BFFF. When reading + from the I/O-2 range the cart is disabled. When a reset happens the + ROM banks get switched and ROM bank 0(/2) is mapped to $8000-$9FFF. + When a freeze happens ROM bank 0(/2) is mapped to both $8000-$9FFF and + $E000-$FFFF. + +

+ + + +

15.11.3.48 47 - Snapshot 64

+ + + + + + + + + + + + + + + + + + +
Size4Kb (1 bank of 4Kb)
GAMEinactive (0)
EXROMinactive (0)
Load address$E000-$EFFF
+ + +
+      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  C64?CARTRIDGE???
+0010: 00 00 00 40 01 00 00 2F 00 00 00 00 00 00 00 00  ???@???/????????
+0020: 56 49 43 45 20 43 41 52 54 00 00 00 00 00 00 00  VICE?CART???????
+0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ????????????????
+0040: 43 48 49 50 00 00 10 10 00 00 00 00 E0 00 10 00  CHIP????????????
+0050: 78 D8 48 8A 48 98 48 AC 0D DD 10 03 4C EE F2 AD  x.HHH??.??L??
+
+ +

+ Warning, the following information is based on guess-work and might be + incorrect, any further information and/or corrections are appreciated. + +

+

+ The cart has a control bit (bit 0) in the I/O-2 range which is used to + disable or enable the cart. + +

+ + + +

15.11.3.49 48 - Super Explode V5.0

+ + + + + + + + + + + + + + + + + + +
Size16Kb (2 banks of 8Kb)
GAMEactive (1)
EXROMinactive (0)
Load address$8000-$9FFF
+ + +
+      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  C64?CARTRIDGE???
+0010: 00 00 00 40 01 00 00 30 00 01 00 00 00 00 00 00  ???@???0????????
+0020: 56 49 43 45 20 43 41 52 54 00 00 00 00 00 00 00  VICE?CART???????
+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????????.???
+0050: D7 86 5E FE C3 C2 CD 38 30 A9 00 2C A9 FF 85 FE  .^....80.?,.?.
+...
+2050: 43 48 49 50 00 00 20 10 00 00 00 01 80 00 20 00  CHIP????????.???
+2060: E8 96 5E FE C3 C2 CD 38 30 20 6C 81 A9 09 8D 99  ?^....80?l.?
+
+ +

+ Warning, the following information is based on guess-work and might be + incorrect, any further information and/or corrections are appreciated. + +

+

+ The cart has 16Kb of ROM which are used as two banks of 8Kb, they are + mapped into $8000-$9FFF and the last page of the current ROM bank is + mirrored in $DF00-$DFFF. The cart has a control bit (bit 7) at $DF00, + which is used to select what ROM bank is used. + +

+ + + +

15.11.3.50 49 - Magic Voice

+ + + + + + + + + + + + + + + + + + + $A000-$BFFF (bank 2) +
Size16Kb (2 banks of 8Kb)
GAMEactive (1)
EXROMinactive (0)
Load address$8000-$9FFF (bank 1),
+ + +
+      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  C64?CARTRIDGE???
+0010: 00 00 00 40 01 00 00 31 00 01 00 00 00 00 00 00  ???@???1????????
+0020: 56 49 43 45 20 43 41 52 54 00 00 00 00 00 00 00  VICE?CART???????
+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????????.???
+0050: EA 2C 80 DF 50 FB A0 00 8C 80 DF B9 E3 A3 29 0F  .,.?P. ?.?.)?
+...
+2050: 43 48 49 50 00 00 20 10 00 00 00 00 A0 00 20 00  CHIP???????? ???
+2060: 4A EB C0 49 6A EA BB FB 4E CA 43 1E 75 63 15 97  J?.Ij..N.C?uc?
+
+ +

+ This cart has 16Kb of ROM, mapped in at reset at $8000-$BFFF. The cart + is controled through a TPI at $DF80-$DF87: + +

+ +
+    $DF80 - Port A Data
+    $DF81 - Port B Data
+    $DF82 - Port C Data
+    $DF83 - Port A Direction
+    $DF84 - Port B Direction
+    $DF85 - Port C Direction
+    $DF86 - Control register
+    $DF87 - Active Interrupt register
+
+ +

+ The cart has a pass-through port and does the following at start-up: + +

+ +
    +
  • Program starts after reset at $FFD3, and copies code from + + $FF36-$FFD2 to $0200-$029C (157 bytes) + +
  • Program continues at $021A, copies $A000-$BFFF from EPROM to RAM at + + $A000-$BFFF (8Kb), copies $E000-$FFFF from EPROM to RAM at + $E000-$FFFF (8Kb), copies $AE62-$B461 from RAM to RAM at $C000-$C5FF + (Magic Voice Code) + +
  • Jump to beginning of Magic Voice code at $C000 + +
+ + + +

15.11.3.51 50 - Action Replay 2

+ + + + + + + + + + + + + + + + + + +
Size16Kb (2 banks of 8Kb)
GAMEactive (1)
EXROMinactive (0)
Load address$8000-$9FFF
+ + +
+      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  C64?CARTRIDGE???
+0010: 00 00 00 40 01 00 00 32 00 01 00 00 00 00 00 00  ???@???2????????
+0020: 56 49 43 45 20 43 41 52 54 00 00 00 00 00 00 00  VICE?CART???????
+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????????.???
+0050: EA EA 68 AA 68 85 94 68 85 95 68 85 96 68 85 97  ..hhhhh
+...
+2050: 43 48 49 50 00 00 20 10 00 00 00 01 80 00 20 00  CHIP????????.???
+2060: 30 80 5E FE C3 C2 CD 38 30 20 04 90 4C 38 DF 1A  0.^....80??L8??
+
+ +

+ Warning, the following information is based on guess-work and might be + incorrect, any further information and/or corrections are appreciated. + +

+

+ I/O-1 is somehow used to enable the cart, the exact way in which this + is done is unknown. Reading from the I/O-2 range will give you the + last page of the current ROM bank, and writing to it will disable the + cart. + +

+ + +

15.11.3.52 51 - MACH 5

+ + + + + + + + + + + + + + + + + + + $8000-$9FFF (8Kb) +
Size4Kb or 8Kb (1 bank of 4Kb or 8Kb)
GAMEactive (1)
EXROMinactive (0)
Load address$8000-$8FFF (4Kb),
+ + +
+      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  C64?CARTRIDGE???
+0010: 00 00 00 40 01 00 00 33 00 01 00 00 00 00 00 00  ???@???3????????
+0020: 56 49 43 45 20 43 41 52 54 00 00 00 00 00 00 00  VICE?CART???????
+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????????.???
+0050: AF 83 5E FE C3 C2 CD 38 30 4D 41 43 48 35 A5 93  ^....80MACH5.
+
+ +

+ This cart has 8Kb ROM mapped at $8000-$9FFF, the $9E00-$9EFF range is + mirrored at $DE00-$DEFF and the $9F00-$9FFF range is mirrored at + $DF00-$DFFF. + +

+ + + +

15.11.3.53 52 - Diashow maker

+ + + + + + + + + + + + + + + + + + +
Size8Kb (1 bank of 8Kb)
GAMEactive (1)
EXROMinactive (0)
Load address$8000-$9FFF
+ + +
+      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  C64?CARTRIDGE???
+0010: 00 00 00 40 01 00 00 34 00 01 00 00 00 00 00 00  ???@???4????????
+0020: 56 49 43 45 20 43 41 52 54 00 00 00 00 00 00 00  VICE?CART???????
+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????????.???
+0050: 09 80 09 80 C3 C2 CD 38 30 AD 11 D0 29 10 D0 62  ?.?....80?.)?.b
+
+ +

+ Accessing I/O-1 (the software uses $DE00 only it seems) disables + cartridge ROM. A reset enables 8K game mode and the ROM bank is mapped + to $8000. A freeze causes ROM to be mapped to $8000. + +

+ + + +

15.11.3.54 53 - Pagefox

+ + + + + + + + + + + + + + + + + + +
Size64Kb (4 banks of 16Kb)
GAMEactive (1)
EXROMactive (1)
Load address$8000-$BFFF
+ + +
+      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  C64?CARTRIDGE???
+0010: 00 00 00 40 01 00 00 35 01 01 00 00 00 00 00 00  ???@???5????????
+0020: 56 49 43 45 20 43 41 52 54 00 00 00 00 00 00 00  VICE?CART???????
+0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ????????????????
+0040: 43 48 49 50 00 00 40 10 00 00 00 00 80 00 40 00  CHIP??@?????.?@?
+0050: 31 80 BB 0E C3 C2 CD 38 30 50 46 20 56 31 2E 30  1.?...80PF?V1.0
+...
+4050: 43 48 49 50 00 00 40 10 00 00 00 01 80 00 40 00  CHIP??@?????.?@?
+4060: A2 FE 9A 20 EC AE 20 82 80 20 74 86 20 A5 8B 4C  ...???.?t?L
+...
+8060: 43 48 49 50 00 00 40 10 00 00 00 02 80 00 40 00  CHIP??@?????.?@?
+8070: 5A 01 02 03 04 06 0A 0B 10 14 1E 28 3C 00 00 00  Z??????????(<???
+...
+C070: 43 48 49 50 00 00 40 10 00 00 00 03 80 00 40 00  CHIP??@?????.?@?
+C080: 1E 03 14 82 09 05 09 0F 0C 0D 0F 05 09 09 0B 0A  ???????????????
+
+ +

+ This cart has 64Kb ROM (2 32Kb Eproms, mapped to $8000 and $A000 in + 16Kb Game Mode), and 32Kb RAM (mapped to $8000 and $A000 in 16K Game + Mode). The cart has 1 (write-only) bank control register which is + located at $DE80 and mirrored throughout the $DE80-$DEFF range: + +

+ +
+    Bit 0: unused/don't care
+    Bit 1: Bank select: 0=upper, 1=lower (not correct ?!)
+    Bit 2: chip select 0
+    Bit 3: chip select 1
+    Bit 4: cartridge enable/disable: 0=enable, 1=disable
+    Bits 5-7: unused/don't care
+
+ +

+ Chip select combinations of 0/1 are: + +

+    00: Eprom "79"
+    01: Eprom "ZS3"
+    10: Ram
+    11: empty space (reading returns VIC-II data)
+
+ +

+ note: on the original hardware "disabling" the cartridge by setting + bit 4 of the control register does NOT prevent write accesses to + the cartridge RAM!. So to actually disable the RAM, it is + suggested to write $FF to the register. + +

+ + +

15.11.3.55 54 - Kingsoft

+ + + + + + + + + + + + + + + + + + +
Size-
GAME-
EXROM-
Load address-
+ + + +

15.11.3.56 55 - Silverrock 128

+ + + + + + + + + + + + + + + + + + +
Size128k (16 banks of 8k)
GAMEactive (1)
EXROMinactive (0)
Load address$8000-$9FFF
+ + + +

15.11.3.57 56 - Formel 64

+ + + + + + + + + + + + + + + + + + +
Size32kb (4 banks of 8k)
GAMEinactive (0)
EXROMinactive (0)
Load address$E000-$FFFF
+ +


+Go to the first, previous, next, last section, table of contents. + +